mirror of https://github.com/doitsujin/dxvk
Compare commits
458 Commits
Author | SHA1 | Date |
---|---|---|
Blisto91 | 8d965359a5 | |
Philip Rebohle | fd978704fb | |
Tiagoquix | ee18aecb8a | |
Blisto91 | c2fd91f835 | |
Tiagoquix | 79eea564fb | |
Robin Kertels | 7df8017e46 | |
WinterSnowfall | c98152683f | |
Blisto91 | 890ad3f47f | |
Robin Kertels | 60cfafe027 | |
Robin Kertels | 889802887f | |
WinterSnowfall | a1ce690c5c | |
WinterSnowfall | 07d007c642 | |
Danylo Piliaiev | 58d8ea2d31 | |
Philip Rebohle | 61bd62c327 | |
Philip Rebohle | 7bc77b597e | |
Simon McVittie | 2ff2c826a5 | |
Simon McVittie | f9b4046223 | |
Simon McVittie | 83436a97f2 | |
Ethan Lee | e991bfa604 | |
Ethan Lee | f33453afbb | |
Robin Kertels | 65dd3c7df3 | |
Robin Kertels | dfc3776b24 | |
Philip Rebohle | 3420cd78ac | |
Philip Rebohle | 4225f35034 | |
Philip Rebohle | 2cb2f8694e | |
Blisto91 | c1f665f92b | |
WinterSnowfall | 20185a5309 | |
Blisto91 | 0c2efda804 | |
Blisto91 | c7d61b2fc0 | |
Ethan Lee | 6259e86392 | |
Ethan Lee | d5d236a1e2 | |
Ethan Lee | 10b83d184b | |
Ethan Lee | 0f7c1f753a | |
Ethan Lee | 529129c332 | |
Ethan Lee | 4055a92856 | |
Blisto91 | 7bad17c1d1 | |
Blisto91 | 6b76d70d9d | |
Philip Rebohle | 611dc60018 | |
WinterSnowfall | b2789ab894 | |
Philip Rebohle | ab715a8876 | |
talkingerbil | 1fb35b6d19 | |
Rémi Bernon | 4333ee872d | |
Rémi Bernon | b99d42c688 | |
Blisto91 | dacb8b434b | |
Philip Rebohle | ea4cb84d8a | |
Philip Rebohle | 65373792d2 | |
Lierrmm | 29253da356 | |
Robin Kertels | 79398b468d | |
Robin Kertels | e7d14e97de | |
Philip Rebohle | c613078ba8 | |
Philip Rebohle | 2970645f33 | |
Philip Rebohle | 462165da19 | |
Philip Rebohle | 3f27a0ee58 | |
Katharine Chui | aac3396671 | |
Katharine Chui | 92a43ebf65 | |
Blisto91 | 8ba5256dc7 | |
Philip Rebohle | 2b70ba8f77 | |
Philip Rebohle | 9c66c4bf1d | |
Philip Rebohle | 00872e9e4f | |
Philip Rebohle | 35157357dd | |
Philip Rebohle | 617ebf4e05 | |
Philip Rebohle | c2489d5a45 | |
Philip Rebohle | 6ef98c613f | |
Philip Rebohle | 7441137a33 | |
WinterSnowfall | 571948cfc0 | |
Martino Fontana | 133f0794bc | |
Philip Rebohle | 44695f9311 | |
Casey Bowman | 49e9ea5f5a | |
Blisto91 | 198bd3a4b8 | |
Philip Rebohle | f06c646315 | |
Philip Rebohle | 855b2746b6 | |
Blisto91 | 28c7c09bf5 | |
Philip Rebohle | 2742486540 | |
Philip Rebohle | 037d0fa1ad | |
Philip Rebohle | cbf51a7a25 | |
Philip Rebohle | 70e34dc31c | |
Philip Rebohle | c5aeb0f87a | |
Philip Rebohle | a163082770 | |
Blisto91 | 2e1a19c7fd | |
Joshua Ashton | 0beb18ef73 | |
Joshua Ashton | ef4428ab8c | |
Philip Rebohle | 1085ba713e | |
Philip Rebohle | e857b09432 | |
Kaitlyn | 538f1d13d4 | |
Kaitlyn | 783c9d4591 | |
Kaitlyn | 1a685b1c67 | |
Robin Kertels | 8b8be7c2bf | |
Billy Laws | 0776d764a4 | |
Robin Kertels | 15ddadc4de | |
Philip Rebohle | 69a52b3da0 | |
Philip Rebohle | 707ad6f328 | |
Philip Rebohle | 3a6992ea97 | |
Robin Kertels | 72c86b8229 | |
Robin Kertels | 85215b10d6 | |
Philip Rebohle | fd3fbf6607 | |
Minelelol | 0a699fddb6 | |
Blisto91 | afec5cce88 | |
Ethan Lee | 4b0e3111d1 | |
Philip Rebohle | 0414bbe2d5 | |
Robin Kertels | 20490b678f | |
Blisto91 | 428c98bc63 | |
Robin Kertels | a0e39e94fa | |
Robin Kertels | eaa732d0b3 | |
Robin Kertels | 49b18f03fe | |
Philip Rebohle | c9cea93b7b | |
Philip Rebohle | 69d74a46a0 | |
Philip Rebohle | 94098aa97d | |
Philip Rebohle | c677ba9b3e | |
Philip Rebohle | 77c7396ee1 | |
Philip Rebohle | f07e5f9eaa | |
Philip Rebohle | d5c3011f54 | |
Blisto91 | 6b3b934471 | |
Philip Rebohle | 9004c132ed | |
Philip Rebohle | 24d4c9c938 | |
Philip Rebohle | 5ded7d67f0 | |
Philip Rebohle | 234f3ea071 | |
Robin Kertels | c5a37d443a | |
Robin Kertels | f254afb4fb | |
Robin Kertels | 39c19e9299 | |
Robin Kertels | 738fd4f895 | |
Philip Rebohle | 9491b56beb | |
Robin Kertels | ab3593185f | |
Robin Kertels | e9a0fec5b3 | |
Echo J | fae78407a2 | |
Robin Kertels | 5312ef1cf9 | |
Robin Kertels | 62d64bd63a | |
Robin Kertels | f83ba898af | |
Ethan Lee | 30f2b2df31 | |
Philip Rebohle | 05cb963e22 | |
Philip Rebohle | eb339bc7e4 | |
Ethan Lee | c423819e90 | |
Tatsuyuki Ishi | e2a46a347d | |
Tatsuyuki Ishi | afc6aa70fb | |
Tatsuyuki Ishi | 799aeff560 | |
Robin Kertels | 2ca8fdf890 | |
Robin Kertels | 0841f5faf4 | |
Ethan Lee | 2334bbccb0 | |
Robin Kertels | 7d9864c077 | |
Dean Beeler | d4c5fc74e7 | |
Tatsuyuki Ishi | 6199776869 | |
Tatsuyuki Ishi | 6faf3c1acd | |
Tatsuyuki Ishi | ab6bd8b17f | |
Tatsuyuki Ishi | 89267b62ad | |
Blisto91 | 34d8e65fd7 | |
Joshua Ashton | 1568c263fb | |
Joshua Ashton | 0cd4165658 | |
Joshua Ashton | 4b8e8bed6e | |
r-a-sattarov | ac78048c23 | |
Richard Yao | 14560600a9 | |
Blisto91 | 854e06d3f0 | |
Blisto91 | eb806952d8 | |
Blisto91 | a44dfabe26 | |
spiffeeroo | 5e06cf9573 | |
Blisto91 | 2cf590f636 | |
Robin Kertels | a7a63b37c3 | |
Robin Kertels | 9cde0b5798 | |
Blisto91 | adb33d3af1 | |
Philip Rebohle | 1b31aa5dbc | |
Philip Rebohle | 03c09ce15f | |
Blisto91 | 91f7f43c35 | |
Robin Kertels | d998dee46e | |
Philip Rebohle | ea3149801f | |
xpander69 | 1cb58b0732 | |
Philip Rebohle | 2ed1778df9 | |
Philip Rebohle | a427d22cde | |
Joshua Ashton | 22c2abb9b7 | |
Blisto91 | f45911a28f | |
Blisto91 | e00db24557 | |
Paul Gofman | 552d2f0a6d | |
WinterSnowfall | 4d974685c9 | |
Blisto91 | f0ff0007dc | |
Robin Kertels | 494f7fd38d | |
WinterSnowfall | 0632da1935 | |
Philip Rebohle | 83dc4678df | |
Paul Gofman | f93cfbc26a | |
Philip Rebohle | c113b791a1 | |
Ellie Hermaszewska | 41191af3b1 | |
Philip Rebohle | 5828f0e2b9 | |
Philip Rebohle | 80e075406b | |
Margen67 | a53f0e8168 | |
Margen67 | 4705de5725 | |
Robin Kertels | 9e26964a96 | |
Blisto91 | ce2f9f35ce | |
Philip Rebohle | a3fa9c26dc | |
Joshua Ashton | ff5507769a | |
WinterSnowfall | 5c56fa0df4 | |
Tatsuyuki Ishi | 7e10021eac | |
Joshua Ashton | bbd1d84cd0 | |
Jens Peters | 02db89ac30 | |
Philip Rebohle | 92dc61f161 | |
Philip Rebohle | 6a5ed02db3 | |
Philip Rebohle | 64828e2c6c | |
Philip Rebohle | a4f2a49a02 | |
Philip Rebohle | aa41a7a351 | |
Philip Rebohle | fb71c08d8c | |
Philip Rebohle | 79f6239df3 | |
Philip Rebohle | 53a68635b2 | |
Philip Rebohle | 179c5ec998 | |
Philip Rebohle | d6e0107e23 | |
Joshua Ashton | 428ca9416d | |
Joshua Ashton | c26f40229a | |
Joshua Ashton | 8226690298 | |
Joshua Ashton | 138f727fbb | |
Philip Rebohle | c2cd129b89 | |
Philip Rebohle | 915244c00c | |
Blisto91 | 6fce094942 | |
Robin Kertels | 740ebec7ee | |
Robin Kertels | bcaaac4ad7 | |
Joshua Ashton | 1130512db5 | |
Blisto91 | 143eb8c710 | |
Philip Rebohle | 4ae542e875 | |
Philip Rebohle | 952c66fe2a | |
Philip Rebohle | b6a7714e67 | |
Etaash Mathamsetty | 037669f715 | |
Robin Kertels | 295a58afdf | |
Robin Kertels | 0746a3b91a | |
Etaash Mathamsetty | 429555a540 | |
Blisto91 | dfcd7aedd8 | |
gofman | cbda22a040 | |
Georg Lehmann | 549bd86f03 | |
WinterSnowfall | b0b46fd075 | |
Joshua Ashton | a62117cd13 | |
pchome | e598dcd77e | |
Philip Rebohle | 09857dcaa9 | |
Philip Rebohle | d66f8385c3 | |
Philip Rebohle | 007e9f4c89 | |
Philip Rebohle | 9b019d26ac | |
Philip Rebohle | 228615b639 | |
Ellie Hermaszewska | dfbebba6b5 | |
Blisto91 | 4ed04268fd | |
Blisto91 | 4ed1474030 | |
Blisto91 | 13440a5d89 | |
Blisto91 | 1daae75048 | |
Philip Rebohle | b4d87eaac0 | |
Philip Rebohle | 1e11db98d0 | |
Philip Rebohle | f689ddd838 | |
Philip Rebohle | eed43c8524 | |
Philip Rebohle | d066fbbaed | |
Philip Rebohle | a67c99943a | |
Philip Rebohle | 5ece97f769 | |
Philip Rebohle | 228cd4c331 | |
Blisto91 | 98f3887680 | |
Blisto91 | 3a9a70b5f0 | |
Philip Rebohle | 878da4984b | |
Philip Rebohle | c599f95e5d | |
Paul Gofman | 4893788d9b | |
Paul Gofman | fc952a3ca3 | |
Paul Gofman | 01ad79278b | |
Paul Gofman | 48557886de | |
Paul Gofman | 8319793a98 | |
Blisto91 | 886268fcf9 | |
Hans-Kristian Arntzen | 84e59fc9e5 | |
Blisto91 | 6be1f6d7bd | |
Joshua Ashton | 2f72115f91 | |
Alpyne | 026aa49ef8 | |
Trevonn | 3a368f4780 | |
Tatsuyuki Ishi | 2ef41bdbf6 | |
Philip Rebohle | 0f4458e173 | |
Philip Rebohle | ccb87d5ea9 | |
Alpyne | 022bf1d134 | |
Alpyne | d6e7e3e780 | |
Blisto91 | b77928b6fe | |
Philip Rebohle | 987df8a487 | |
Philip Rebohle | a7278cdab1 | |
Joshua Ashton | 3b3ebc9350 | |
Joshua Ashton | 00ae118655 | |
Joshua Ashton | 55be12daa5 | |
Joshua Ashton | 0e36a07a93 | |
Joshua Ashton | ff65599dba | |
Joshua Ashton | 6b60de2d31 | |
Joshua Ashton | 362743c1d6 | |
Joshua Ashton | 7f302fc350 | |
Philip Rebohle | 8704ed7af6 | |
Philip Rebohle | 0895858901 | |
Joshua Ashton | 80b27f95bc | |
Joshua Ashton | a791493d14 | |
Joshua Ashton | c768196251 | |
Joshua Ashton | 3625c5d481 | |
Philip Rebohle | b3cbe36c08 | |
Philip Rebohle | 166d90b04c | |
Robin Kertels | 60b6e98529 | |
Robin Kertels | a20869fb93 | |
Philip Rebohle | a287566c65 | |
Philip Rebohle | 28f48f9fdc | |
Philip Rebohle | e02a800c33 | |
Philip Rebohle | d7fa39c4eb | |
Philip Rebohle | d1e39be7e7 | |
Philip Rebohle | 438c535fe7 | |
Philip Rebohle | 7dbe4abb48 | |
Philip Rebohle | e99bc591df | |
Philip Rebohle | 08363edb05 | |
Philip Rebohle | 5d1196733b | |
Philip Rebohle | ca3492570c | |
Philip Rebohle | 215c4f8f6f | |
Robin Kertels | 5a1ebfa4ee | |
Joshua Ashton | 6f87ccdafc | |
Joshua Ashton | b30a4f0cc7 | |
Joshua Ashton | 4e9853f608 | |
Joshua Ashton | 5fbb0dd4ba | |
Joshua Ashton | 77f6f2a84b | |
Alpyne | 0b9acf3a25 | |
Timo Gurr | 211d095ee4 | |
Trevonn | 77e7e8bfba | |
Alpyne | 42a0264e69 | |
Alpyne | 5d29140f74 | |
Alpyne | 0236e780a7 | |
Alpyne | 24dbcf8fd8 | |
Alpyne | 404c984f9c | |
Alpyne | a79772322b | |
Trevonn | 36e6a7c2e5 | |
Trevonn | c5ab5be48d | |
Paul Gofman | af9bd16b8d | |
Winter Snowfall | 2c014fdb34 | |
Timo Gurr | 6478c10a18 | |
Philip Rebohle | 7388c243d2 | |
Lilium | bd575a4a46 | |
Lilium | 3fce9886f5 | |
Lilium | 5d134b877a | |
Robin Kertels | c75ed86909 | |
Robin Kertels | d1707026f9 | |
Robin Kertels | b8d36eeacc | |
Robin Kertels | 8f740c53b4 | |
Robin Kertels | 52ac271acb | |
Robin Kertels | a1a91dd766 | |
Robin Kertels | 22f6246fd6 | |
Robin Kertels | 9d6804e40a | |
Robin Kertels | 5fd025c513 | |
Robin Kertels | d9d6316609 | |
Robin Kertels | 9b877cf623 | |
Robin Kertels | 2c3f2b9ad1 | |
Robin Kertels | 1850819483 | |
Robin Kertels | 1db2e3a6ec | |
Robin Kertels | 2efd3f3698 | |
Robin Kertels | bbaf01d9e6 | |
Robin Kertels | 4a55047dde | |
Joshua Ashton | 3fddc364ee | |
Blisto91 | f3fb5ba320 | |
Philip Rebohle | 4d254b13be | |
Joshua Ashton | d241daa0b1 | |
Eric Sullivan | 2e70a2b07d | |
Robin Kertels | 52f04ca3d4 | |
Joshua Ashton | c585ea251e | |
Philip Rebohle | ab00591297 | |
Philip Rebohle | 85d52ccb88 | |
Philip Rebohle | e6be0cf996 | |
Philip Rebohle | 1728d9e89d | |
Philip Rebohle | b1b0abdbbf | |
Philip Rebohle | be875cd7e6 | |
Philip Rebohle | 0543956ea0 | |
Blisto91 | e9e0949717 | |
WinterSnowfall | 8b6cbda6de | |
Robin Kertels | 4b10846008 | |
Joshua Ashton | e0654977c9 | |
Joshua Ashton | b5c18a02ae | |
Joshua Ashton | cafd104783 | |
Joshua Ashton | 269bab2c34 | |
Joshua Ashton | 075c0bf203 | |
Joshua Ashton | 8560efa3c7 | |
Blisto91 | b9b2db510e | |
Lilium | d5c6ae2e4d | |
Lilium | 633f6663a4 | |
Robin Kertels | d2759c20ba | |
Robin Kertels | 1a2e724c16 | |
Blisto91 | 6449f583f8 | |
Joshua Ashton | f2bb1d4b69 | |
Joshua Ashton | 495dc75ab2 | |
Paul Gofman | 550e04c579 | |
WinterSnowfall | d4a7346198 | |
Blisto91 | 99b367cdd6 | |
Blisto91 | 65520fa18e | |
Joshua Ashton | f30376a1e4 | |
Philip Rebohle | cae0a1cef3 | |
Philip Rebohle | 14eb469005 | |
Oleksii Bozhenko | 80f7d2abd8 | |
Alpyne | 2b09932d51 | |
Robin Kertels | bef2ef69ab | |
Robin Kertels | b08665c808 | |
Robin Kertels | 96e22e7c67 | |
Robin Kertels | 5443a2f9f5 | |
Paul Gofman | 83a294285e | |
Robin Kertels | 242ac20752 | |
Robin Kertels | b357d16940 | |
Robin Kertels | b4366db398 | |
Blisto91 | b5f43063b1 | |
Joshua Ashton | f140d2de0d | |
Aleksey Komarov | 20356148af | |
Ellie Hermaszewska | b81536458f | |
Robin Kertels | 9ce1c4df0d | |
Robin Kertels | 860237e775 | |
Robin Kertels | ceb3a7f8c6 | |
Robin Kertels | a42643b235 | |
Philip Rebohle | 5c8ed491ab | |
Joshua Ashton | b44c5bbd18 | |
mbriar | 16d2a6045c | |
mbriar | 1971a5d187 | |
Philip Rebohle | e074d83d0b | |
Robin Kertels | 990a720525 | |
Rémi Bernon | 0cf563d5df | |
Florian Will | 01dc9ddc7d | |
oltolm | 6b779206d9 | |
Blisto91 | 8508633ba3 | |
Robin Kertels | af0009c5de | |
Robin Kertels | 31af522cbc | |
Philip Rebohle | d9a6b40ae3 | |
Tatsuyuki Ishi | 6d14fffdbd | |
Blisto91 | 3ce3209e3e | |
Philip Rebohle | f212cc8f7d | |
Philip Rebohle | 306919047b | |
Philip Rebohle | 977669c613 | |
Zhiyi Zhang | 631171cf45 | |
František Zatloukal | 1a5afc77b1 | |
Robin Kertels | d11878e793 | |
Philip Rebohle | 4b74d1a97b | |
Blisto91 | b0ed97e070 | |
Philip Rebohle | 3d5becaf6a | |
Philip Rebohle | 5595844f75 | |
Philip Rebohle | 9bdad71dc6 | |
Philip Rebohle | 3c99314332 | |
Philip Rebohle | fa8cf50263 | |
Philip Rebohle | 3f9d2269f6 | |
Philip Rebohle | 6432787ac3 | |
Philip Rebohle | da32453b42 | |
Philip Rebohle | 27f3648a44 | |
Philip Rebohle | 35895ba05b | |
Philip Rebohle | 56a8fa2e6f | |
Philip Rebohle | d8f3a1c83d | |
Philip Rebohle | ef9d5048f3 | |
Philip Rebohle | f50f5bc9bc | |
Philip Rebohle | b06e82591e | |
Philip Rebohle | 687d32cac5 | |
WinterSnowfall | 243c2f3cf5 | |
Philip Rebohle | af811656bb | |
Philip Rebohle | 05fb634f91 | |
Blisto91 | 3a123222e5 | |
Philip Rebohle | 4faa598e09 | |
Philip Rebohle | 6783123654 | |
Robin Kertels | d14dcf5d47 | |
Joshua Ashton | 996acbe3f2 | |
Blisto91 | 8ecd1b3b6b | |
Philip Rebohle | 7f21a6c491 | |
Philip Rebohle | e430ff5cfd | |
Joshua Ashton | 1acf885109 | |
Robin Kertels | 1c6fc7b5b8 | |
Guy1524 | 5609c5e076 | |
Philip Rebohle | 55e7cb1d54 | |
Philip Rebohle | 4c78964679 | |
Philip Rebohle | cc78276897 | |
Philip Rebohle | aa92cf48f5 | |
Philip Rebohle | 81440340ac | |
Philip Rebohle | 2356d34f2e | |
Philip Rebohle | f4b91817fe | |
Philip Rebohle | 2be0d6842e | |
Robin Kertels | 0d28be4ab8 | |
Blisto91 | 081181313e | |
TacoDeBoss | caf31033d7 | |
Paul Gofman | 2263dcad95 | |
Jens Peters | 41b1efd7ce | |
Philip Rebohle | c6111eaf61 |
|
@ -26,6 +26,6 @@ Name of the game, settings used etc.
|
||||||
For instructions on how to use apitrace, see: https://github.com/doitsujin/dxvk/wiki/Using-Apitrace
|
For instructions on how to use apitrace, see: https://github.com/doitsujin/dxvk/wiki/Using-Apitrace
|
||||||
|
|
||||||
### Log files
|
### Log files
|
||||||
- d3d9.log:
|
Please attach Proton or Wine logs as a text file:
|
||||||
- d3d11.log:
|
- When using Proton, set the Steam launch options for your game to `PROTON_LOG=1 %command%` and attach the corresponding `steam-xxxxx.log` file in your home directory.
|
||||||
- dxgi.log:
|
- When using regular Wine, use `wine game.exe > game.log 2>&1` and attach the resulting `game.log` file.
|
|
@ -9,13 +9,13 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
id: checkout-code
|
id: checkout-code
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Setup problem matcher
|
- name: Setup problem matcher
|
||||||
uses: Joshua-Ashton/gcc-problem-matcher@v2
|
uses: Joshua-Ashton/gcc-problem-matcher@v3
|
||||||
|
|
||||||
- name: Build release
|
- name: Build release
|
||||||
id: build-release
|
id: build-release
|
||||||
|
@ -28,9 +28,9 @@ jobs:
|
||||||
|
|
||||||
- name: Upload artifacts
|
- name: Upload artifacts
|
||||||
id: upload-artifacts
|
id: upload-artifacts
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: dxvk-${{ env.VERSION_NAME }}
|
name: dxvk-win-${{ env.VERSION_NAME }}
|
||||||
path: build/dxvk-${{ env.VERSION_NAME }}
|
path: build/dxvk-${{ env.VERSION_NAME }}
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
|
@ -41,26 +41,43 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
id: checkout-code
|
id: checkout-code
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Setup problem matcher
|
- name: Setup problem matcher
|
||||||
uses: Joshua-Ashton/gcc-problem-matcher@v2
|
uses: Joshua-Ashton/gcc-problem-matcher@v3
|
||||||
|
|
||||||
- name: Build release
|
- name: Build release
|
||||||
id: build-release
|
id: build-release
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
export VERSION_NAME="${GITHUB_REF##*/}-${GITHUB_SHA##*/}"
|
export VERSION_NAME="${GITHUB_REF##*/}-${GITHUB_SHA##*/}"
|
||||||
./package-native.sh ${VERSION_NAME} build --no-package
|
./package-native.sh ${VERSION_NAME} build
|
||||||
echo "VERSION_NAME=${VERSION_NAME}" >> $GITHUB_ENV
|
echo "VERSION_NAME=${VERSION_NAME}" >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: Upload artifacts
|
- name: Upload artifacts
|
||||||
id: upload-artifacts
|
id: upload-artifacts
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: dxvk-${{ env.VERSION_NAME }}
|
name: dxvk-native-${{ env.VERSION_NAME }}
|
||||||
path: build/dxvk-native-${{ env.VERSION_NAME }}
|
path: build/dxvk-native-${{ env.VERSION_NAME }}.tar.gz
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
|
merge-artifacts:
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
needs: [artifacts-mingw-w64, artifacts-steamrt-sniper]
|
||||||
|
steps:
|
||||||
|
- name: Get version
|
||||||
|
id: get-version
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
echo "VERSION_NAME=${GITHUB_REF##*/}-${GITHUB_SHA##*/}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Merge Artifacts
|
||||||
|
uses: actions/upload-artifact/merge@v4
|
||||||
|
with:
|
||||||
|
name: dxvk-${{ env.VERSION_NAME }}
|
||||||
|
pattern: dxvk*
|
||||||
|
delete-merged: true
|
||||||
|
|
|
@ -9,16 +9,15 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
id: checkout-code
|
id: checkout-code
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
|
|
||||||
- name: Setup glslangValidator
|
- name: Setup glslangValidator
|
||||||
shell: pwsh
|
shell: pwsh
|
||||||
run: |
|
run: |
|
||||||
choco install vulkan-sdk -y
|
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/HansKristian-Work/vkd3d-proton-ci/main/glslangValidator.exe" -OutFile "glslangValidator.exe"
|
||||||
Write-Output "$([System.Environment]::GetEnvironmentVariable('VULKAN_SDK', 'Machine'))\Bin" `
|
Write-Output "$pwd" | Out-File -FilePath "${Env:GITHUB_PATH}" -Append
|
||||||
| Out-File -FilePath "${Env:GITHUB_PATH}" -Append
|
|
||||||
|
|
||||||
- name: Setup Meson
|
- name: Setup Meson
|
||||||
shell: pwsh
|
shell: pwsh
|
||||||
|
|
62
README.md
62
README.md
|
@ -9,18 +9,32 @@ The most recent development builds can be found [here](https://github.com/doitsu
|
||||||
Release builds can be found [here](https://github.com/doitsujin/dxvk/releases).
|
Release builds can be found [here](https://github.com/doitsujin/dxvk/releases).
|
||||||
|
|
||||||
## How to use
|
## How to use
|
||||||
In order to install a DXVK package obtained from the [release](https://github.com/doitsujin/dxvk/releases) page into a given wine prefix, copy or symlink the DLLs into the following directories as follows, then open `winecfg` and manually add DLL overrides for `d3d11`, `d3d10core`, `dxgi`, and `d3d9`:
|
In order to install a DXVK package obtained from the [release](https://github.com/doitsujin/dxvk/releases) page into a given wine prefix, copy or symlink the DLLs into the following directories as follows, then open `winecfg` and manually add DLL overrides for `d3d11`, `d3d10core`, `dxgi`, and `d3d9`.
|
||||||
|
|
||||||
|
In a default Wine prefix that would be as follows:
|
||||||
```
|
```
|
||||||
WINEPREFIX=/path/to/wineprefix
|
export WINEPREFIX=/path/to/wineprefix
|
||||||
cp x64/*.dll $WINEPREFIX/drive_c/windows/system32
|
cp x64/*.dll $WINEPREFIX/drive_c/windows/system32
|
||||||
cp x32/*.dll $WINEPREFIX/drive_c/windows/syswow64
|
cp x32/*.dll $WINEPREFIX/drive_c/windows/syswow64
|
||||||
winecfg
|
winecfg
|
||||||
```
|
```
|
||||||
|
|
||||||
Verify that your application uses DXVK instead of wined3d by checking for the presence of the log file `d3d9.log` or `d3d11.log` in the application's directory, or by enabling the HUD (see notes below).
|
For a pure 32-bit Wine prefix (non default) the 32-bit DLLs instead go to the `system32` directory:
|
||||||
|
```
|
||||||
|
export WINEPREFIX=/path/to/wineprefix
|
||||||
|
cp x32/*.dll $WINEPREFIX/drive_c/windows/system32
|
||||||
|
winecfg
|
||||||
|
```
|
||||||
|
|
||||||
|
Verify that your application uses DXVK instead of wined3d by enabling the HUD (see notes below).
|
||||||
|
|
||||||
In order to remove DXVK from a prefix, remove the DLLs and DLL overrides, and run `wineboot -u` to restore the original DLL files.
|
In order to remove DXVK from a prefix, remove the DLLs and DLL overrides, and run `wineboot -u` to restore the original DLL files.
|
||||||
|
|
||||||
|
Tools such as Steam Play, Lutris, Bottles, Heroic Launcher, etc will automatically handle setup of dxvk on their own when enabled.
|
||||||
|
|
||||||
|
### Notes on Vulkan drivers
|
||||||
|
Before reporting an issue, please check the [Wiki](https://github.com/doitsujin/dxvk/wiki/Driver-support) page on the current driver status and make sure you run a recent enough driver version for your hardware.
|
||||||
|
|
||||||
## Build instructions
|
## Build instructions
|
||||||
|
|
||||||
In order to pull in all submodules that are needed for building, clone the repository using the following command:
|
In order to pull in all submodules that are needed for building, clone the repository using the following command:
|
||||||
|
@ -64,12 +78,14 @@ ninja install
|
||||||
|
|
||||||
The D3D9, D3D10, D3D11 and DXGI DLLs will be located in `/your/dxvk/directory/bin`. Setup has to be done manually in this case.
|
The D3D9, D3D10, D3D11 and DXGI DLLs will be located in `/your/dxvk/directory/bin`. Setup has to be done manually in this case.
|
||||||
|
|
||||||
### Notes on Vulkan drivers
|
|
||||||
Before reporting an issue, please check the [Wiki](https://github.com/doitsujin/dxvk/wiki/Driver-support) page on the current driver status and make sure you run a recent enough driver version for your hardware.
|
|
||||||
|
|
||||||
### Online multi-player games
|
### Online multi-player games
|
||||||
Manipulation of Direct3D libraries in multi-player games may be considered cheating and can get your account **banned**. This may also apply to single-player games with an embedded or dedicated multiplayer portion. **Use at your own risk.**
|
Manipulation of Direct3D libraries in multi-player games may be considered cheating and can get your account **banned**. This may also apply to single-player games with an embedded or dedicated multiplayer portion. **Use at your own risk.**
|
||||||
|
|
||||||
|
### Logs
|
||||||
|
When used with Wine, DXVK will print log messages to `stderr`. Additionally, standalone log files can optionally be generated by setting the `DXVK_LOG_PATH` variable, where log files in the given directory will be called `app_d3d11.log`, `app_dxgi.log` etc., where `app` is the name of the game executable.
|
||||||
|
|
||||||
|
On Windows, log files will be created in the game's working directory by default, which is usually next to the game executable.
|
||||||
|
|
||||||
### HUD
|
### HUD
|
||||||
The `DXVK_HUD` environment variable controls a HUD which can display the framerate and some stat counters. It accepts a comma-separated list of the following options:
|
The `DXVK_HUD` environment variable controls a HUD which can display the framerate and some stat counters. It accepts a comma-separated list of the following options:
|
||||||
- `devinfo`: Displays the name of the GPU and the driver version.
|
- `devinfo`: Displays the name of the GPU and the driver version.
|
||||||
|
@ -87,6 +103,7 @@ The `DXVK_HUD` environment variable controls a HUD which can display the framera
|
||||||
- `compiler`: Shows shader compiler activity
|
- `compiler`: Shows shader compiler activity
|
||||||
- `samplers`: Shows the current number of sampler pairs used *[D3D9 Only]*
|
- `samplers`: Shows the current number of sampler pairs used *[D3D9 Only]*
|
||||||
- `scale=x`: Scales the HUD by a factor of `x` (e.g. `1.5`)
|
- `scale=x`: Scales the HUD by a factor of `x` (e.g. `1.5`)
|
||||||
|
- `opacity=y`: Adjusts the HUD opacity by a factor of `y` (e.g. `0.5`, `1.0` being fully opaque).
|
||||||
|
|
||||||
Additionally, `DXVK_HUD=1` has the same effect as `DXVK_HUD=devinfo,fps`, and `DXVK_HUD=full` enables all available HUD elements.
|
Additionally, `DXVK_HUD=1` has the same effect as `DXVK_HUD=devinfo,fps`, and `DXVK_HUD=full` enables all available HUD elements.
|
||||||
|
|
||||||
|
@ -99,6 +116,15 @@ Some applications do not provide a method to select a different GPU. In that cas
|
||||||
|
|
||||||
**Note:** If the device filter is configured incorrectly, it may filter out all devices and applications will be unable to create a D3D device.
|
**Note:** If the device filter is configured incorrectly, it may filter out all devices and applications will be unable to create a D3D device.
|
||||||
|
|
||||||
|
### Graphics Pipeline Library
|
||||||
|
On drivers which support `VK_EXT_graphics_pipeline_library` Vulkan shaders will be compiled at the time the game loads its D3D shaders, rather than at draw time. This reduces or eliminates shader compile stutter in many games when compared to the previous system.
|
||||||
|
|
||||||
|
In games that load their shaders during loading screens or in the menu, this can lead to prolonged periods of very high CPU utilization, especially on weaker CPUs. For affected games it is recommended to wait for shader compilation to finish before starting the game to avoid stutter and low performance. Shader compiler activity can be monitored with `DXVK_HUD=compiler`.
|
||||||
|
|
||||||
|
This feature largely replaces the state cache.
|
||||||
|
|
||||||
|
**Note:** Games which only load their D3D shaders at draw time (e.g. most Unreal Engine games) will still exhibit some stutter, although it should still be less severe than without this feature.
|
||||||
|
|
||||||
### State cache
|
### State cache
|
||||||
DXVK caches pipeline state by default, so that shaders can be recompiled ahead of time on subsequent runs of an application, even if the driver's own shader cache got invalidated in the meantime. This cache is enabled by default, and generally reduces stuttering.
|
DXVK caches pipeline state by default, so that shaders can be recompiled ahead of time on subsequent runs of an application, even if the driver's own shader cache got invalidated in the meantime. This cache is enabled by default, and generally reduces stuttering.
|
||||||
|
|
||||||
|
@ -108,13 +134,16 @@ The following environment variables can be used to control the cache:
|
||||||
- `reset`: Clears the cache file.
|
- `reset`: Clears the cache file.
|
||||||
- `DXVK_STATE_CACHE_PATH=/some/directory` Specifies a directory where to put the cache files. Defaults to the current working directory of the application.
|
- `DXVK_STATE_CACHE_PATH=/some/directory` Specifies a directory where to put the cache files. Defaults to the current working directory of the application.
|
||||||
|
|
||||||
|
This feature is mostly only relevant on systems without support for `VK_EXT_graphics_pipeline_library`
|
||||||
|
|
||||||
### Debugging
|
### Debugging
|
||||||
The following environment variables can be used for **debugging** purposes.
|
The following environment variables can be used for **debugging** purposes.
|
||||||
- `VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation` Enables Vulkan debug layers. Highly recommended for troubleshooting rendering issues and driver crashes. Requires the Vulkan SDK to be installed on the host system.
|
- `VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation` Enables Vulkan debug layers. Highly recommended for troubleshooting rendering issues and driver crashes. Requires the Vulkan SDK to be installed on the host system.
|
||||||
- `DXVK_LOG_LEVEL=none|error|warn|info|debug` Controls message logging.
|
- `DXVK_LOG_LEVEL=none|error|warn|info|debug` Controls message logging.
|
||||||
- `DXVK_LOG_PATH=/some/directory` Changes path where log files are stored. Set to `none` to disable log file creation entirely, without disabling logging.
|
- `DXVK_LOG_PATH=/some/directory` Changes path where log files are stored. Set to `none` to disable log file creation entirely, without disabling logging.
|
||||||
- `DXVK_CONFIG_FILE=/xxx/dxvk.conf` Sets path to the configuration file.
|
|
||||||
- `DXVK_DEBUG=markers|validation` Enables use of the `VK_EXT_debug_utils` extension for translating performance event markers, or to enable Vulkan validation, respecticely.
|
- `DXVK_DEBUG=markers|validation` Enables use of the `VK_EXT_debug_utils` extension for translating performance event markers, or to enable Vulkan validation, respecticely.
|
||||||
|
- `DXVK_CONFIG_FILE=/xxx/dxvk.conf` Sets path to the configuration file.
|
||||||
|
- `DXVK_CONFIG="dxgi.hideAmdGpu = True; dxgi.syncInterval = 0"` Can be used to set config variables through the environment instead of a configuration file using the same syntax. `;` is used as a seperator.
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
DXVK requires threading support from your mingw-w64 build environment. If you
|
DXVK requires threading support from your mingw-w64 build environment. If you
|
||||||
|
@ -134,3 +163,22 @@ For non debian based distros, make sure that your mingw-w64-gcc cross compiler
|
||||||
does have `--enable-threads=posix` enabled during configure. If your distro does
|
does have `--enable-threads=posix` enabled during configure. If your distro does
|
||||||
ship its mingw-w64-gcc binary with `--enable-threads=win32` you might have to
|
ship its mingw-w64-gcc binary with `--enable-threads=win32` you might have to
|
||||||
recompile locally or open a bug at your distro's bugtracker to ask for it.
|
recompile locally or open a bug at your distro's bugtracker to ask for it.
|
||||||
|
|
||||||
|
# DXVK Native
|
||||||
|
|
||||||
|
DXVK Native is a version of DXVK which allows it to be used natively without Wine.
|
||||||
|
|
||||||
|
This is primarily useful for game and application ports to either avoid having to write another rendering backend, or to help with port bringup during development.
|
||||||
|
|
||||||
|
[Release builds](https://github.com/doitsujin/dxvk/releases) are built using the Steam Runtime.
|
||||||
|
|
||||||
|
### How does it work?
|
||||||
|
|
||||||
|
DXVK Native replaces certain Windows-isms with a platform and framework-agnostic replacement, for example, `HWND`s can become `SDL_Window*`s, etc.
|
||||||
|
All it takes to do that is to add another WSI backend.
|
||||||
|
|
||||||
|
**Note:** DXVK Native requires a backend to be explicitly set via the `DXVK_WSI_DRIVER` environment variable. The current built-in options are `SDL2` and `GLFW`.
|
||||||
|
|
||||||
|
DXVK Native comes with a slim set of Windows header definitions required for D3D9/11 and the MinGW headers for D3D9/11.
|
||||||
|
In most cases, it will end up being plug and play with your renderer, but there may be certain teething issues such as:
|
||||||
|
- `__uuidof(type)` is supported, but `__uuidof(variable)` is not supported. Use `__uuidof_var(variable)` instead.
|
||||||
|
|
164
dxvk.conf
164
dxvk.conf
|
@ -1,3 +1,10 @@
|
||||||
|
# Device filter. Only exposes devices whose Vulkan device name contains
|
||||||
|
# the given string. May be useful to force an application to run on a
|
||||||
|
# specific GPU, but not applications launched by that application.
|
||||||
|
|
||||||
|
# dxvk.deviceFilter = ""
|
||||||
|
|
||||||
|
|
||||||
# Expose the HDR10 ColorSpace (DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020)
|
# Expose the HDR10 ColorSpace (DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020)
|
||||||
# to the application by default.
|
# to the application by default.
|
||||||
# This shows to the game that the global Windows 'HDR Mode' is enabled.
|
# This shows to the game that the global Windows 'HDR Mode' is enabled.
|
||||||
|
@ -10,6 +17,7 @@
|
||||||
|
|
||||||
# dxgi.enableHDR = True
|
# dxgi.enableHDR = True
|
||||||
|
|
||||||
|
|
||||||
# Create the VkSurface on the first call to IDXGISwapChain::Present,
|
# Create the VkSurface on the first call to IDXGISwapChain::Present,
|
||||||
# rather than when creating the swap chain. Some games that start
|
# rather than when creating the swap chain. Some games that start
|
||||||
# rendering with a different graphics API may require this option,
|
# rendering with a different graphics API may require this option,
|
||||||
|
@ -61,18 +69,43 @@
|
||||||
# d3d9.customDeviceDesc = ""
|
# d3d9.customDeviceDesc = ""
|
||||||
|
|
||||||
|
|
||||||
# Report Nvidia GPUs as AMD GPUs by default. This is enabled by default
|
# Report Nvidia GPUs as AMD GPUs. Unless NVAPI support is explicitly
|
||||||
# to work around issues with NVAPI, but may cause issues in some games.
|
# enabled through Proton, this is done by default in order to work
|
||||||
|
# around crashes or low performance with Nvidia-speciic code paths
|
||||||
|
# in games, especially Unreal Engine.
|
||||||
#
|
#
|
||||||
# Supported values: True, False
|
# Supported values: Auto, True, False
|
||||||
|
|
||||||
# dxgi.nvapiHack = True
|
# dxgi.hideNvidiaGpu = Auto
|
||||||
|
|
||||||
|
|
||||||
|
# Report Nvidia GPUs running on NVK as AMD GPUs.
|
||||||
|
#
|
||||||
|
# Supported values: Auto, True, False
|
||||||
|
|
||||||
|
# dxgi.hideNvkGpu = Auto
|
||||||
|
|
||||||
|
|
||||||
|
# Report AMD GPUs as Nvidia GPUs. This is only done for games that are
|
||||||
|
# known to have issues with AMDAGS or other AMD-specific code paths.
|
||||||
|
#
|
||||||
|
# Supported values: Auto, True, False
|
||||||
|
|
||||||
|
# dxgi.hideAmdGpu = Auto
|
||||||
|
|
||||||
|
|
||||||
|
# Report Intel GPUs as AMD GPUs. This is only done for games that are
|
||||||
|
# known to have issues with Intel-specific libraries such as XESS.
|
||||||
|
#
|
||||||
|
# Supported values: Auto, True, False
|
||||||
|
|
||||||
|
# dxgi.hideIntelGpu = Auto
|
||||||
|
|
||||||
|
|
||||||
# Override maximum amount of device memory and shared system memory
|
# Override maximum amount of device memory and shared system memory
|
||||||
# reported to the application. This may fix texture streaming issues
|
# reported to the application. This may fix texture streaming issues
|
||||||
# in games that do not support cards with large amounts of VRAM.
|
# in games that do not support cards with large amounts of VRAM.
|
||||||
|
# This is not a hard cap and applications can choose to ignore it.
|
||||||
#
|
#
|
||||||
# Supported values: Any number in Megabytes.
|
# Supported values: Any number in Megabytes.
|
||||||
|
|
||||||
|
@ -122,8 +155,7 @@
|
||||||
#
|
#
|
||||||
# Supported values: Auto, True, False
|
# Supported values: Auto, True, False
|
||||||
|
|
||||||
# dxgi.tearFree = Auto
|
# dxvk.tearFree = Auto
|
||||||
# d3d9.tearFree = Auto
|
|
||||||
|
|
||||||
|
|
||||||
# Assume single-use mode for command lists created on deferred contexts.
|
# Assume single-use mode for command lists created on deferred contexts.
|
||||||
|
@ -190,6 +222,16 @@
|
||||||
# Supported values: Any number between -2.0 and 1.0
|
# Supported values: Any number between -2.0 and 1.0
|
||||||
|
|
||||||
# d3d11.samplerLodBias = 0.0
|
# d3d11.samplerLodBias = 0.0
|
||||||
|
# d3d9.samplerLodBias = 0.0
|
||||||
|
|
||||||
|
|
||||||
|
# Clamps any negative LOD bias to 0. Applies after samplerLodBias has been
|
||||||
|
# applied. May help with games that use a high negative LOD bias by default.
|
||||||
|
#
|
||||||
|
# Supported values: True, False
|
||||||
|
|
||||||
|
# d3d11.clampNegativeLodBias = False
|
||||||
|
# d3d9.clampNegativeLodBias = False
|
||||||
|
|
||||||
|
|
||||||
# Declares vertex positions as invariant in order to solve
|
# Declares vertex positions as invariant in order to solve
|
||||||
|
@ -266,6 +308,32 @@
|
||||||
# d3d11.enableContextLock = False
|
# d3d11.enableContextLock = False
|
||||||
|
|
||||||
|
|
||||||
|
# Exposes or hides support for driver command lists
|
||||||
|
#
|
||||||
|
# Some games use the feature flag to decide whether to use deferred
|
||||||
|
# contexts or not. We enable this by default, but in some situations
|
||||||
|
# this can lead to issues if games detect an AMD GPU where command
|
||||||
|
# lists are not natively supported on Windows.
|
||||||
|
#
|
||||||
|
# Supported values: True, False
|
||||||
|
|
||||||
|
# d3d11.exposeDriverCommandLists = True
|
||||||
|
|
||||||
|
|
||||||
|
# Reproducible Command Stream
|
||||||
|
#
|
||||||
|
# Ensure that for the same D3D commands the output VK commands
|
||||||
|
# don't change between runs. Useful for comparative benchmarking,
|
||||||
|
# can negatively affect performance and can break some games
|
||||||
|
# that don't use queries correctly.
|
||||||
|
#
|
||||||
|
# Supported values:
|
||||||
|
# - True/False
|
||||||
|
|
||||||
|
# d3d11.reproducibleCommandStream = False
|
||||||
|
# d3d9.reproducibleCommandStream = False
|
||||||
|
|
||||||
|
|
||||||
# Sets number of pipeline compiler threads.
|
# Sets number of pipeline compiler threads.
|
||||||
#
|
#
|
||||||
# If the graphics pipeline library feature is enabled, the given
|
# If the graphics pipeline library feature is enabled, the given
|
||||||
|
@ -294,6 +362,17 @@
|
||||||
# dxvk.useRawSsbo = Auto
|
# dxvk.useRawSsbo = Auto
|
||||||
|
|
||||||
|
|
||||||
|
# Changes memory chunk size.
|
||||||
|
#
|
||||||
|
# Can be used to override the maximum memory chunk size.
|
||||||
|
#
|
||||||
|
# Supported values:
|
||||||
|
# - 0 to use the defaults
|
||||||
|
# - any positive integer to limit the chunk size, in MiB
|
||||||
|
|
||||||
|
# dxvk.maxChunkSize = 0
|
||||||
|
|
||||||
|
|
||||||
# Controls graphics pipeline library behaviour
|
# Controls graphics pipeline library behaviour
|
||||||
#
|
#
|
||||||
# Can be used to change VK_EXT_graphics_pipeline_library usage for
|
# Can be used to change VK_EXT_graphics_pipeline_library usage for
|
||||||
|
@ -442,6 +521,7 @@
|
||||||
# Supported values:
|
# Supported values:
|
||||||
# - True/False
|
# - True/False
|
||||||
|
|
||||||
|
# d3d11.longMad = False
|
||||||
# d3d9.longMad = False
|
# d3d9.longMad = False
|
||||||
|
|
||||||
# Device Local Constant Buffers
|
# Device Local Constant Buffers
|
||||||
|
@ -455,18 +535,11 @@
|
||||||
|
|
||||||
# d3d9.deviceLocalConstantBuffers = False
|
# d3d9.deviceLocalConstantBuffers = False
|
||||||
|
|
||||||
# No Explicit Front Buffer
|
|
||||||
#
|
|
||||||
# Disables the front buffer
|
|
||||||
#
|
|
||||||
# Supported values:
|
|
||||||
# - True/False
|
|
||||||
|
|
||||||
# d3d9.noExplicitFrontBuffer = False
|
|
||||||
|
|
||||||
# Support DF formats
|
# Support DF formats
|
||||||
#
|
#
|
||||||
# Support the vendor extension DF floating point depth formats
|
# Support the vendor extension DF floating point depth formats on AMD and Intel.
|
||||||
|
# Note that this config is ignored and disabled by default on Nvidia, or when
|
||||||
|
# spoofing a Nvidia GPU, as it does not support these formats natively.
|
||||||
#
|
#
|
||||||
# Supported values:
|
# Supported values:
|
||||||
# - True/False
|
# - True/False
|
||||||
|
@ -485,7 +558,7 @@
|
||||||
# Support X4R4G4B4
|
# Support X4R4G4B4
|
||||||
#
|
#
|
||||||
# Support the X4R4G4B4 format.
|
# Support the X4R4G4B4 format.
|
||||||
# The Sims 2 is a horrible game made by complete morons.
|
# The Sims 2 is a very broken game.
|
||||||
#
|
#
|
||||||
# Supported values:
|
# Supported values:
|
||||||
# - True/False
|
# - True/False
|
||||||
|
@ -504,7 +577,7 @@
|
||||||
# Disable A8 as a Render Target
|
# Disable A8 as a Render Target
|
||||||
#
|
#
|
||||||
# Disable support for A8 format render targets
|
# Disable support for A8 format render targets
|
||||||
# Once again, The Sims 2 is a horrible game made by complete morons.
|
# Once again, The Sims 2 is a very broken game.
|
||||||
#
|
#
|
||||||
# Supported values:
|
# Supported values:
|
||||||
# - True/False
|
# - True/False
|
||||||
|
@ -544,16 +617,6 @@
|
||||||
|
|
||||||
# d3d9.forceAspectRatio = ""
|
# d3d9.forceAspectRatio = ""
|
||||||
|
|
||||||
# Allow Discard
|
|
||||||
#
|
|
||||||
# Allow the discard lock flag to be used
|
|
||||||
# Useful if some apps use this incorrectly.
|
|
||||||
#
|
|
||||||
# Supported values:
|
|
||||||
# - True/False
|
|
||||||
|
|
||||||
# d3d9.allowDiscard = True
|
|
||||||
|
|
||||||
# Enumerate by Displays
|
# Enumerate by Displays
|
||||||
#
|
#
|
||||||
# Whether we should enumerate D3D9 adapters by display (windows behaviour)
|
# Whether we should enumerate D3D9 adapters by display (windows behaviour)
|
||||||
|
@ -565,16 +628,17 @@
|
||||||
|
|
||||||
# d3d9.enumerateByDisplays = True
|
# d3d9.enumerateByDisplays = True
|
||||||
|
|
||||||
# APITrace Mode
|
# Cached Dynamic Buffers
|
||||||
#
|
#
|
||||||
# Makes all host visible buffers cached and coherent
|
# Allocates dynamic resources in D3DPOOL_DEFAULT in
|
||||||
# Improves performance when apitracing, but also can impact
|
# cached system memory rather than uncached memory or host-visible
|
||||||
# some dumb games.
|
# VRAM, in order to allow fast readback from the CPU. This is only
|
||||||
|
# useful for buggy applications, and may reduce GPU-bound performance.
|
||||||
#
|
#
|
||||||
# Supported values:
|
# Supported values:
|
||||||
# - True/False
|
# - True/False
|
||||||
|
|
||||||
# d3d9.apitraceMode = False
|
# d3d9.cachedDynamicBuffers = False
|
||||||
|
|
||||||
# Seamless Cubes
|
# Seamless Cubes
|
||||||
#
|
#
|
||||||
|
@ -604,3 +668,37 @@
|
||||||
# DO NOT CHANGE THIS UNLESS YOU HAVE A VERY GOOD REASON.
|
# DO NOT CHANGE THIS UNLESS YOU HAVE A VERY GOOD REASON.
|
||||||
|
|
||||||
# d3d9.textureMemory = 100
|
# d3d9.textureMemory = 100
|
||||||
|
|
||||||
|
# Hide integrated graphics from applications
|
||||||
|
#
|
||||||
|
# Only has an effect when dedicated GPUs are present on the system. It is
|
||||||
|
# not recommended to use this option at all unless absolutely necessary for
|
||||||
|
# a game to work; prefer using DXVK_FILTER_DEVICE_NAME whenever possible.
|
||||||
|
#
|
||||||
|
# Supported values:
|
||||||
|
# - True/False
|
||||||
|
|
||||||
|
# dxvk.hideIntegratedGraphics = False
|
||||||
|
|
||||||
|
# Trigger DEVICELOST when losing focus
|
||||||
|
#
|
||||||
|
# D3D9 requires the application to call Device::Reset after
|
||||||
|
# it loses focus in fullscreen.
|
||||||
|
# Some games rely on observing a D3DERR_DEVICELOST or D3DERR_NOTRESET.
|
||||||
|
# Others don't handle it correctly.
|
||||||
|
#
|
||||||
|
# Supported values:
|
||||||
|
# - True/False
|
||||||
|
|
||||||
|
# d3d9.deviceLossOnFocusLoss = False
|
||||||
|
|
||||||
|
# Reject Device::Reset if any losable resource is still alive
|
||||||
|
#
|
||||||
|
# D3D9 rejects Device::Reset if there's still any alive resources of specific types.
|
||||||
|
# (State blocks, additional swapchains, D3DPOOL_DEFAULT resources)
|
||||||
|
# Some games leak resources leading to a hang.
|
||||||
|
#
|
||||||
|
# Supported values:
|
||||||
|
# - True/False
|
||||||
|
|
||||||
|
# d3d9.countLosableResources = True
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
install_subdir(
|
||||||
|
'directx',
|
||||||
|
install_dir: get_option('includedir') / 'dxvk',
|
||||||
|
strip_directory: true,
|
||||||
|
exclude_files: '.git'
|
||||||
|
)
|
||||||
|
|
||||||
|
install_subdir(
|
||||||
|
'windows',
|
||||||
|
install_dir: get_option('includedir') / 'dxvk',
|
||||||
|
strip_directory: true,
|
||||||
|
)
|
||||||
|
|
||||||
|
install_headers(
|
||||||
|
'wsi/native_wsi.h',
|
||||||
|
'wsi/native_sdl2.h',
|
||||||
|
'wsi/native_glfw.h',
|
||||||
|
subdir: 'dxvk/wsi',
|
||||||
|
)
|
|
@ -12,6 +12,10 @@ struct IUnknown {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
virtual HRESULT QueryInterface(REFIID riid, void** ppvObject) = 0;
|
virtual HRESULT QueryInterface(REFIID riid, void** ppvObject) = 0;
|
||||||
|
template<class Q>
|
||||||
|
HRESULT STDMETHODCALLTYPE QueryInterface(Q **pp) {
|
||||||
|
return QueryInterface(__uuidof(Q), (void **)pp);
|
||||||
|
}
|
||||||
|
|
||||||
virtual ULONG AddRef() = 0;
|
virtual ULONG AddRef() = 0;
|
||||||
virtual ULONG Release() = 0;
|
virtual ULONG Release() = 0;
|
||||||
|
|
|
@ -23,10 +23,16 @@ typedef uint32_t UINT;
|
||||||
|
|
||||||
typedef int32_t LONG;
|
typedef int32_t LONG;
|
||||||
typedef uint32_t ULONG;
|
typedef uint32_t ULONG;
|
||||||
|
typedef int32_t *LPLONG;
|
||||||
|
|
||||||
typedef int32_t HRESULT;
|
typedef int32_t HRESULT;
|
||||||
|
|
||||||
typedef wchar_t WCHAR;
|
typedef wchar_t WCHAR;
|
||||||
|
typedef WCHAR *NWPSTR, *LPWSTR, *PWSTR;
|
||||||
|
typedef unsigned char UCHAR, *PUCHAR;
|
||||||
|
|
||||||
|
typedef char CHAR;
|
||||||
|
typedef const CHAR *LPCSTR, *PCSTR;
|
||||||
|
|
||||||
typedef INT BOOL;
|
typedef INT BOOL;
|
||||||
typedef BOOL WINBOOL;
|
typedef BOOL WINBOOL;
|
||||||
|
@ -35,11 +41,13 @@ typedef uint16_t UINT16;
|
||||||
typedef uint32_t UINT32;
|
typedef uint32_t UINT32;
|
||||||
typedef uint64_t UINT64;
|
typedef uint64_t UINT64;
|
||||||
typedef void VOID;
|
typedef void VOID;
|
||||||
|
typedef void* PVOID;
|
||||||
typedef void* LPVOID;
|
typedef void* LPVOID;
|
||||||
typedef const void* LPCVOID;
|
typedef const void* LPCVOID;
|
||||||
|
|
||||||
typedef size_t SIZE_T;
|
typedef size_t SIZE_T;
|
||||||
|
|
||||||
|
typedef int8_t INT8;
|
||||||
typedef uint8_t UINT8;
|
typedef uint8_t UINT8;
|
||||||
typedef uint8_t BYTE;
|
typedef uint8_t BYTE;
|
||||||
|
|
||||||
|
@ -47,7 +55,13 @@ typedef int16_t SHORT;
|
||||||
typedef uint16_t USHORT;
|
typedef uint16_t USHORT;
|
||||||
|
|
||||||
typedef int64_t LONGLONG;
|
typedef int64_t LONGLONG;
|
||||||
|
typedef int64_t INT64;
|
||||||
|
|
||||||
typedef uint64_t ULONGLONG;
|
typedef uint64_t ULONGLONG;
|
||||||
|
typedef uint64_t UINT64;
|
||||||
|
|
||||||
|
typedef intptr_t LONG_PTR;
|
||||||
|
typedef uintptr_t ULONG_PTR;
|
||||||
|
|
||||||
typedef float FLOAT;
|
typedef float FLOAT;
|
||||||
|
|
||||||
|
@ -66,9 +80,11 @@ typedef GUID IID;
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
#define REFIID const IID&
|
#define REFIID const IID&
|
||||||
#define REFGUID const GUID&
|
#define REFGUID const GUID&
|
||||||
|
#define REFCLSID const GUID&
|
||||||
#else
|
#else
|
||||||
#define REFIID const IID*
|
#define REFIID const IID*
|
||||||
#define REFGUID const GUID*
|
#define REFGUID const GUID*
|
||||||
|
#define REFCLSID const GUID* const
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -86,6 +102,7 @@ inline bool operator!=(const GUID& a, const GUID& b) { return std::memcmp(&a, &b
|
||||||
|
|
||||||
typedef uint32_t DWORD;
|
typedef uint32_t DWORD;
|
||||||
typedef uint16_t WORD;
|
typedef uint16_t WORD;
|
||||||
|
typedef DWORD *LPDWORD;
|
||||||
|
|
||||||
typedef void* HANDLE;
|
typedef void* HANDLE;
|
||||||
typedef HANDLE HMONITOR;
|
typedef HANDLE HMONITOR;
|
||||||
|
@ -107,6 +124,12 @@ typedef uint32_t UINT_PTR;
|
||||||
typedef INT_PTR* PINT_PTR;
|
typedef INT_PTR* PINT_PTR;
|
||||||
typedef UINT_PTR* PUINT_PTR;
|
typedef UINT_PTR* PUINT_PTR;
|
||||||
|
|
||||||
|
#ifdef STRICT
|
||||||
|
#define DECLARE_HANDLE(a) typedef struct a##__ { int unused; } *a
|
||||||
|
#else /*STRICT*/
|
||||||
|
#define DECLARE_HANDLE(a) typedef HANDLE a
|
||||||
|
#endif /*STRICT*/
|
||||||
|
|
||||||
typedef char* LPSTR;
|
typedef char* LPSTR;
|
||||||
typedef wchar_t* LPWSTR;
|
typedef wchar_t* LPWSTR;
|
||||||
typedef const char* LPCSTR;
|
typedef const char* LPCSTR;
|
||||||
|
@ -129,12 +152,12 @@ typedef struct RECT {
|
||||||
LONG top;
|
LONG top;
|
||||||
LONG right;
|
LONG right;
|
||||||
LONG bottom;
|
LONG bottom;
|
||||||
} RECT;
|
} RECT,*PRECT,*NPRECT,*LPRECT;
|
||||||
|
|
||||||
typedef struct SIZE {
|
typedef struct SIZE {
|
||||||
LONG cx;
|
LONG cx;
|
||||||
LONG cy;
|
LONG cy;
|
||||||
} SIZE;
|
} SIZE,*PSIZE,*LPSIZE;
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
struct {
|
struct {
|
||||||
|
@ -166,7 +189,7 @@ typedef struct PALETTEENTRY {
|
||||||
BYTE peGreen;
|
BYTE peGreen;
|
||||||
BYTE peBlue;
|
BYTE peBlue;
|
||||||
BYTE peFlags;
|
BYTE peFlags;
|
||||||
} PALETTEENTRY;
|
} PALETTEENTRY, *PPALETTEENTRY, *LPPALETTEENTRY;
|
||||||
|
|
||||||
typedef struct RGNDATAHEADER {
|
typedef struct RGNDATAHEADER {
|
||||||
DWORD dwSize;
|
DWORD dwSize;
|
||||||
|
@ -179,7 +202,7 @@ typedef struct RGNDATAHEADER {
|
||||||
typedef struct RGNDATA {
|
typedef struct RGNDATA {
|
||||||
RGNDATAHEADER rdh;
|
RGNDATAHEADER rdh;
|
||||||
char Buffer[1];
|
char Buffer[1];
|
||||||
} RGNDATA;
|
} RGNDATA,*PRGNDATA,*NPRGNDATA,*LPRGNDATA;
|
||||||
|
|
||||||
// Ignore these.
|
// Ignore these.
|
||||||
#define STDMETHODCALLTYPE
|
#define STDMETHODCALLTYPE
|
||||||
|
@ -191,6 +214,11 @@ typedef struct RGNDATA {
|
||||||
#define TRUE 1
|
#define TRUE 1
|
||||||
#define FALSE 0
|
#define FALSE 0
|
||||||
|
|
||||||
|
#define WAIT_TIMEOUT 0x00000102
|
||||||
|
#define WAIT_FAILED 0xffffffff
|
||||||
|
#define WAIT_OBJECT_0 0
|
||||||
|
#define WAIT_ABANDONED 0x00000080
|
||||||
|
|
||||||
#define interface struct
|
#define interface struct
|
||||||
#define MIDL_INTERFACE(x) struct
|
#define MIDL_INTERFACE(x) struct
|
||||||
|
|
||||||
|
@ -278,6 +306,7 @@ typedef struct RGNDATA {
|
||||||
#define THIS_
|
#define THIS_
|
||||||
#define THIS
|
#define THIS
|
||||||
|
|
||||||
|
#define __C89_NAMELESSSTRUCTNAME
|
||||||
#define __C89_NAMELESSUNIONNAME
|
#define __C89_NAMELESSUNIONNAME
|
||||||
#define __C89_NAMELESSUNIONNAME1
|
#define __C89_NAMELESSUNIONNAME1
|
||||||
#define __C89_NAMELESSUNIONNAME2
|
#define __C89_NAMELESSUNIONNAME2
|
||||||
|
@ -290,17 +319,35 @@ typedef struct RGNDATA {
|
||||||
#define __C89_NAMELESS
|
#define __C89_NAMELESS
|
||||||
#define DUMMYUNIONNAME
|
#define DUMMYUNIONNAME
|
||||||
#define DUMMYSTRUCTNAME
|
#define DUMMYSTRUCTNAME
|
||||||
|
#define DUMMYUNIONNAME1
|
||||||
|
#define DUMMYUNIONNAME2
|
||||||
|
#define DUMMYUNIONNAME3
|
||||||
|
#define DUMMYUNIONNAME4
|
||||||
|
#define DUMMYUNIONNAME5
|
||||||
|
#define DUMMYUNIONNAME6
|
||||||
|
#define DUMMYUNIONNAME7
|
||||||
|
#define DUMMYUNIONNAME8
|
||||||
|
#define DUMMYUNIONNAME9
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
#define DECLARE_INTERFACE(x) struct x
|
#define DECLARE_INTERFACE(x) struct x
|
||||||
#define DECLARE_INTERFACE_(x, y) struct x : public y
|
#define DECLARE_INTERFACE_(x, y) struct x : public y
|
||||||
#else
|
#else
|
||||||
|
#ifdef CONST_VTABLE
|
||||||
#define DECLARE_INTERFACE(x) \
|
#define DECLARE_INTERFACE(x) \
|
||||||
typedef interface x { \
|
typedef interface x { \
|
||||||
const struct x##Vtbl *lpVtbl; \
|
const struct x##Vtbl *lpVtbl; \
|
||||||
} x; \
|
} x; \
|
||||||
typedef const struct x##Vtbl x##Vtbl; \
|
typedef const struct x##Vtbl x##Vtbl; \
|
||||||
const struct x##Vtbl
|
const struct x##Vtbl
|
||||||
|
#else
|
||||||
|
#define DECLARE_INTERFACE(x) \
|
||||||
|
typedef interface x { \
|
||||||
|
struct x##Vtbl *lpVtbl; \
|
||||||
|
} x; \
|
||||||
|
typedef struct x##Vtbl x##Vtbl; \
|
||||||
|
struct x##Vtbl
|
||||||
|
#endif // CONST_VTABLE
|
||||||
#define DECLARE_INTERFACE_(x, y) DECLARE_INTERFACE(x)
|
#define DECLARE_INTERFACE_(x, y) DECLARE_INTERFACE(x)
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
|
|
||||||
|
@ -327,3 +374,25 @@ typedef struct RGNDATA {
|
||||||
|
|
||||||
#define FAILED(hr) ((HRESULT)(hr) < 0)
|
#define FAILED(hr) ((HRESULT)(hr) < 0)
|
||||||
#define SUCCEEDED(hr) ((HRESULT)(hr) >= 0)
|
#define SUCCEEDED(hr) ((HRESULT)(hr) >= 0)
|
||||||
|
|
||||||
|
#define RtlZeroMemory(Destination,Length) memset((Destination),0,(Length))
|
||||||
|
#define ZeroMemory RtlZeroMemory
|
||||||
|
|
||||||
|
#ifndef DEFINE_ENUM_FLAG_OPERATORS
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
# define DEFINE_ENUM_FLAG_OPERATORS(type) \
|
||||||
|
extern "C++" \
|
||||||
|
{ \
|
||||||
|
inline type operator &(type x, type y) { return (type)((int)x & (int)y); } \
|
||||||
|
inline type operator &=(type &x, type y) { return (type &)((int &)x &= (int)y); } \
|
||||||
|
inline type operator ~(type x) { return (type)~(int)x; } \
|
||||||
|
inline type operator |(type x, type y) { return (type)((int)x | (int)y); } \
|
||||||
|
inline type operator |=(type &x, type y) { return (type &)((int &)x |= (int)y); } \
|
||||||
|
inline type operator ^(type x, type y) { return (type)((int)x ^ (int)y); } \
|
||||||
|
inline type operator ^=(type &x, type y) { return (type &)((int &)x ^= (int)y); } \
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
# define DEFINE_ENUM_FLAG_OPERATORS(type)
|
||||||
|
#endif
|
||||||
|
#endif /* DEFINE_ENUM_FLAG_OPERATORS */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL.h>
|
||||||
|
|
||||||
namespace dxvk::wsi {
|
namespace dxvk::wsi {
|
||||||
|
|
||||||
|
@ -22,4 +22,4 @@ namespace dxvk::wsi {
|
||||||
return reinterpret_cast<HMONITOR>(static_cast<intptr_t>(displayId + 1));
|
return reinterpret_cast<HMONITOR>(static_cast<intptr_t>(displayId + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 0bcc624926a25a2a273d07877fd25a6ff5ba1cfb
|
Subproject commit 8b246ff75c6615ba4532fe4fde20f1be090c3764
|
|
@ -1 +1 @@
|
||||||
Subproject commit 98f440ce6868c94f5ec6e198cc1adda4760e8849
|
Subproject commit 46dc0f6e514f5730784bb2cac2a7c731636839e8
|
112
meson.build
112
meson.build
|
@ -1,11 +1,13 @@
|
||||||
project('dxvk', ['c', 'cpp'], version : 'v2.1', meson_version : '>= 0.49', default_options : [ 'cpp_std=c++17', 'warning_level=2' ])
|
project('dxvk', ['c', 'cpp'], version : 'v2.3.1', meson_version : '>= 0.58', default_options : [ 'cpp_std=c++17', 'warning_level=2' ])
|
||||||
|
|
||||||
|
pkg = import('pkgconfig')
|
||||||
cpu_family = target_machine.cpu_family()
|
cpu_family = target_machine.cpu_family()
|
||||||
platform = target_machine.system()
|
platform = target_machine.system()
|
||||||
|
fs = import('fs')
|
||||||
|
|
||||||
cpp = meson.get_compiler('cpp')
|
cpp = meson.get_compiler('cpp')
|
||||||
cc = meson.get_compiler('c')
|
cc = meson.get_compiler('c')
|
||||||
dxvk_is_msvc = cpp.get_id() == 'msvc'
|
dxvk_is_msvc = cpp.get_argument_syntax() == 'msvc'
|
||||||
|
|
||||||
compiler_args = [
|
compiler_args = [
|
||||||
'-msse',
|
'-msse',
|
||||||
|
@ -33,44 +35,61 @@ if get_option('build_id')
|
||||||
]
|
]
|
||||||
endif
|
endif
|
||||||
|
|
||||||
dxvk_include_dirs = [
|
dxvk_include_dirs = ['./include']
|
||||||
'./include',
|
if fs.is_dir('./include/vulkan/include')
|
||||||
'./include/vulkan/include',
|
dxvk_include_dirs += ['./include/vulkan/include']
|
||||||
'./include/spirv/include'
|
elif not cpp.check_header('vulkan/vulkan.h')
|
||||||
]
|
error('Missing Vulkan-Headers')
|
||||||
|
endif
|
||||||
|
if fs.is_dir('./include/spirv/include')
|
||||||
|
dxvk_include_dirs += ['./include/spirv/include']
|
||||||
|
elif not cpp.check_header('spirv/unified1/spirv.hpp')
|
||||||
|
error('Missing SPIRV-Headers')
|
||||||
|
endif
|
||||||
|
|
||||||
proj_displayinfo = subproject('libdisplay-info')
|
dep_displayinfo = dependency(
|
||||||
dep_displayinfo = proj_displayinfo.get_variable('di_dep')
|
'libdisplay-info',
|
||||||
|
version: ['>= 0.0.0', '< 0.2.0'],
|
||||||
|
fallback: ['libdisplay-info', 'di_dep'],
|
||||||
|
default_options: ['default_library=static'],
|
||||||
|
)
|
||||||
|
|
||||||
if platform == 'windows'
|
if platform == 'windows'
|
||||||
|
dxvk_so_version = {'name_prefix': ''}
|
||||||
|
|
||||||
compiler_args += [
|
compiler_args += [
|
||||||
'-DNOMINMAX',
|
'-DNOMINMAX',
|
||||||
'-D_WIN32_WINNT=0xa00',
|
'-D_WIN32_WINNT=0xa00',
|
||||||
]
|
]
|
||||||
|
|
||||||
link_args += [
|
if not dxvk_is_msvc
|
||||||
'-static',
|
|
||||||
'-static-libgcc',
|
|
||||||
'-static-libstdc++',
|
|
||||||
# We need to set the section alignment for debug symbols to
|
|
||||||
# work properly as well as avoiding a memcpy from the Wine loader.
|
|
||||||
'-Wl,--file-alignment=4096',
|
|
||||||
]
|
|
||||||
|
|
||||||
# Wine's built-in back traces only work with dwarf2 symbols
|
|
||||||
if get_option('debug')
|
|
||||||
compiler_args += [
|
|
||||||
'-gstrict-dwarf',
|
|
||||||
'-gdwarf-2',
|
|
||||||
]
|
|
||||||
endif
|
|
||||||
|
|
||||||
# Enable stdcall fixup on 32-bit
|
|
||||||
if cpu_family == 'x86'
|
|
||||||
link_args += [
|
link_args += [
|
||||||
'-Wl,--enable-stdcall-fixup',
|
'-static',
|
||||||
'-Wl,--add-stdcall-alias',
|
'-static-libgcc',
|
||||||
]
|
'-static-libstdc++',
|
||||||
|
# We need to set the section alignment for debug symbols to
|
||||||
|
# work properly as well as avoiding a memcpy from the Wine loader.
|
||||||
|
'-Wl,--file-alignment=4096',
|
||||||
|
]
|
||||||
|
|
||||||
|
# Wine's built-in back traces only work with dwarf4 symbols
|
||||||
|
if get_option('debug')
|
||||||
|
compiler_args += [
|
||||||
|
'-gdwarf-4',
|
||||||
|
]
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Enable stdcall fixup on 32-bit
|
||||||
|
if cpu_family == 'x86'
|
||||||
|
link_args += [
|
||||||
|
'-Wl,--enable-stdcall-fixup',
|
||||||
|
'-Wl,--kill-at',
|
||||||
|
]
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
link_args += [
|
||||||
|
'/FILEALIGN:4096',
|
||||||
|
]
|
||||||
endif
|
endif
|
||||||
|
|
||||||
lib_d3d9 = cpp.find_library('d3d9')
|
lib_d3d9 = cpp.find_library('d3d9')
|
||||||
|
@ -99,10 +118,13 @@ if platform == 'windows'
|
||||||
)
|
)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
dxvk_wsi = 'win32'
|
|
||||||
dxvk_name_prefix = ''
|
dxvk_name_prefix = ''
|
||||||
compiler_args += ['-DDXVK_WSI_WIN32']
|
compiler_args += ['-DDXVK_WSI_WIN32']
|
||||||
else
|
else
|
||||||
|
dxvk_abi_version = '0'
|
||||||
|
dxvk_version = meson.project_version().strip('v').split('.')
|
||||||
|
dxvk_so_version = {'version': dxvk_abi_version + '.' + dxvk_version[0] + dxvk_version[1] + dxvk_version[2]}
|
||||||
|
|
||||||
wrc = find_program('touch')
|
wrc = find_program('touch')
|
||||||
wrc_generator = generator(wrc, output : [ '@BASENAME@_ignored.h' ], arguments : [ '@OUTPUT@' ] )
|
wrc_generator = generator(wrc, output : [ '@BASENAME@_ignored.h' ], arguments : [ '@OUTPUT@' ] )
|
||||||
|
|
||||||
|
@ -112,17 +134,20 @@ else
|
||||||
'./include/native/directx'
|
'./include/native/directx'
|
||||||
]
|
]
|
||||||
|
|
||||||
dxvk_wsi = get_option('dxvk_native_wsi')
|
lib_sdl2 = dependency('SDL2', required: false)
|
||||||
|
lib_glfw = dependency('glfw', required: false)
|
||||||
if dxvk_wsi == 'sdl2'
|
if lib_sdl2.found()
|
||||||
lib_sdl2 = cpp.find_library('SDL2')
|
|
||||||
compiler_args += ['-DDXVK_WSI_SDL2']
|
compiler_args += ['-DDXVK_WSI_SDL2']
|
||||||
elif dxvk_wsi == 'glfw'
|
endif
|
||||||
lib_glfw = cpp.find_library('glfw')
|
if lib_glfw.found()
|
||||||
compiler_args += ['-DDXVK_WSI_GLFW']
|
compiler_args += ['-DDXVK_WSI_GLFW']
|
||||||
endif
|
endif
|
||||||
|
if (not lib_sdl2.found() and not lib_glfw.found())
|
||||||
|
error('SDL2 or GLFW are required to build dxvk-native')
|
||||||
|
endif
|
||||||
|
|
||||||
dxvk_name_prefix = 'libdxvk_'
|
dxvk_name_prefix = 'dxvk_'
|
||||||
|
dxvk_pkg_prefix = 'dxvk-'
|
||||||
|
|
||||||
link_args += [
|
link_args += [
|
||||||
'-static-libgcc',
|
'-static-libgcc',
|
||||||
|
@ -138,13 +163,12 @@ add_project_link_arguments(cpp.get_supported_link_arguments(link_args), language
|
||||||
add_project_link_arguments(cc.get_supported_link_arguments(link_args), language: 'c')
|
add_project_link_arguments(cc.get_supported_link_arguments(link_args), language: 'c')
|
||||||
|
|
||||||
exe_ext = ''
|
exe_ext = ''
|
||||||
dll_ext = ''
|
|
||||||
def_spec_ext = '.def'
|
def_spec_ext = '.def'
|
||||||
|
|
||||||
glsl_compiler = find_program('glslangValidator')
|
glsl_compiler = find_program('glslang', 'glslangValidator')
|
||||||
glsl_args = [
|
glsl_args = [
|
||||||
'--quiet',
|
'--quiet',
|
||||||
'--target-env', 'vulkan1.2',
|
'--target-env', 'vulkan1.3',
|
||||||
'--vn', '@BASENAME@',
|
'--vn', '@BASENAME@',
|
||||||
'--depfile', '@DEPFILE@',
|
'--depfile', '@DEPFILE@',
|
||||||
'@INPUT@',
|
'@INPUT@',
|
||||||
|
@ -163,4 +187,8 @@ dxvk_version = vcs_tag(
|
||||||
output: 'version.h',
|
output: 'version.h',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if platform != 'windows'
|
||||||
|
subdir('include/native')
|
||||||
|
endif
|
||||||
|
|
||||||
subdir('src')
|
subdir('src')
|
||||||
|
|
|
@ -56,13 +56,14 @@ function build_arch {
|
||||||
opt_strip=--strip
|
opt_strip=--strip
|
||||||
fi
|
fi
|
||||||
|
|
||||||
CC="$CC -m$1" CXX="$CXX -m$1" meson setup \
|
CC="$CC -m$1" CXX="$CXX -m$1" meson setup \
|
||||||
--buildtype "release" \
|
--buildtype "release" \
|
||||||
--prefix "$DXVK_BUILD_DIR/usr" \
|
--prefix "$DXVK_BUILD_DIR/usr" \
|
||||||
$opt_strip \
|
$opt_strip \
|
||||||
--bindir "$2" \
|
--bindir "$2" \
|
||||||
--libdir "$2" \
|
--libdir "$2" \
|
||||||
-Dbuild_id=$opt_buildid \
|
-Dbuild_id=$opt_buildid \
|
||||||
|
--force-fallback-for=libdisplay-info \
|
||||||
"$DXVK_BUILD_DIR/build.$1"
|
"$DXVK_BUILD_DIR/build.$1"
|
||||||
|
|
||||||
cd "$DXVK_BUILD_DIR/build.$1"
|
cd "$DXVK_BUILD_DIR/build.$1"
|
||||||
|
|
|
@ -9,10 +9,14 @@ extern "C" {
|
||||||
HRESULT __stdcall D3D11CoreCreateDevice(
|
HRESULT __stdcall D3D11CoreCreateDevice(
|
||||||
IDXGIFactory* pFactory,
|
IDXGIFactory* pFactory,
|
||||||
IDXGIAdapter* pAdapter,
|
IDXGIAdapter* pAdapter,
|
||||||
|
D3D_DRIVER_TYPE DriverType,
|
||||||
|
HMODULE Software,
|
||||||
UINT Flags,
|
UINT Flags,
|
||||||
const D3D_FEATURE_LEVEL* pFeatureLevels,
|
const D3D_FEATURE_LEVEL* pFeatureLevels,
|
||||||
UINT FeatureLevels,
|
UINT FeatureLevels,
|
||||||
ID3D11Device** ppDevice);
|
UINT SDKVersion,
|
||||||
|
ID3D11Device** ppDevice,
|
||||||
|
D3D_FEATURE_LEVEL* pFeatureLevel);
|
||||||
|
|
||||||
|
|
||||||
DLLEXPORT HRESULT __stdcall D3D10CoreCreateDevice(
|
DLLEXPORT HRESULT __stdcall D3D10CoreCreateDevice(
|
||||||
|
@ -31,8 +35,8 @@ extern "C" {
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
return hr;
|
return hr;
|
||||||
|
|
||||||
hr = D3D11CoreCreateDevice(pFactory, pAdapter,
|
hr = D3D11CoreCreateDevice(pFactory, pAdapter, D3D_DRIVER_TYPE_UNKNOWN,
|
||||||
Flags, &FeatureLevel, 1, &d3d11Device);
|
nullptr, Flags, &FeatureLevel, 1, D3D11_SDK_VERSION, &d3d11Device, nullptr);
|
||||||
|
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
return hr;
|
return hr;
|
||||||
|
|
|
@ -7,21 +7,31 @@ d3d10_core_src = [
|
||||||
d3d10_core_ld_args = []
|
d3d10_core_ld_args = []
|
||||||
d3d10_core_link_depends = []
|
d3d10_core_link_depends = []
|
||||||
|
|
||||||
if platform != 'windows'
|
if platform == 'windows'
|
||||||
|
d3d10_d3d11_dep = lib_d3d11
|
||||||
|
else
|
||||||
d3d10_core_ld_args += [ '-Wl,--version-script', join_paths(meson.current_source_dir(), 'd3d10core.sym') ]
|
d3d10_core_ld_args += [ '-Wl,--version-script', join_paths(meson.current_source_dir(), 'd3d10core.sym') ]
|
||||||
d3d10_core_link_depends += files('d3d10core.sym')
|
d3d10_core_link_depends += files('d3d10core.sym')
|
||||||
|
d3d10_d3d11_dep = d3d11_dep
|
||||||
endif
|
endif
|
||||||
|
|
||||||
d3d10_core_dll = shared_library('d3d10core'+dll_ext, d3d10_core_src, d3d10_core_res,
|
d3d10_core_dll = shared_library(dxvk_name_prefix+'d3d10core', d3d10_core_src, d3d10_core_res,
|
||||||
name_prefix : dxvk_name_prefix,
|
dependencies : [ d3d10_d3d11_dep ],
|
||||||
dependencies : [ d3d11_dep ],
|
|
||||||
include_directories : dxvk_include_path,
|
include_directories : dxvk_include_path,
|
||||||
install : true,
|
install : true,
|
||||||
vs_module_defs : 'd3d10core'+def_spec_ext,
|
vs_module_defs : 'd3d10core'+def_spec_ext,
|
||||||
link_args : d3d10_core_ld_args,
|
link_args : d3d10_core_ld_args,
|
||||||
link_depends : [ d3d10_core_link_depends ],
|
link_depends : [ d3d10_core_link_depends ],
|
||||||
|
kwargs : dxvk_so_version,
|
||||||
)
|
)
|
||||||
|
|
||||||
d3d10_core_dep = declare_dependency(
|
d3d10_core_dep = declare_dependency(
|
||||||
link_with : [ d3d10_core_dll ],
|
link_with : [ d3d10_core_dll ],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if platform != 'windows'
|
||||||
|
pkg.generate(d3d10_core_dll,
|
||||||
|
filebase: dxvk_pkg_prefix + 'd3d10core',
|
||||||
|
subdirs: 'dxvk',
|
||||||
|
)
|
||||||
|
endif
|
||||||
|
|
|
@ -58,8 +58,11 @@ namespace dxvk {
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::warn("D3D11BlendState::QueryInterface: Unknown interface query");
|
if (logQueryInterfaceError(__uuidof(ID3D11BlendState), riid)) {
|
||||||
Logger::warn(str::format(riid));
|
Logger::warn("D3D11BlendState::QueryInterface: Unknown interface query");
|
||||||
|
Logger::warn(str::format(riid));
|
||||||
|
}
|
||||||
|
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,10 +8,11 @@ namespace dxvk {
|
||||||
|
|
||||||
D3D11Buffer::D3D11Buffer(
|
D3D11Buffer::D3D11Buffer(
|
||||||
D3D11Device* pDevice,
|
D3D11Device* pDevice,
|
||||||
const D3D11_BUFFER_DESC* pDesc)
|
const D3D11_BUFFER_DESC* pDesc,
|
||||||
|
const D3D11_ON_12_RESOURCE_INFO* p11on12Info)
|
||||||
: D3D11DeviceChild<ID3D11Buffer>(pDevice),
|
: D3D11DeviceChild<ID3D11Buffer>(pDevice),
|
||||||
m_desc (*pDesc),
|
m_desc (*pDesc),
|
||||||
m_resource (this),
|
m_resource (this, pDevice),
|
||||||
m_d3d10 (this) {
|
m_d3d10 (this) {
|
||||||
DxvkBufferCreateInfo info;
|
DxvkBufferCreateInfo info;
|
||||||
info.flags = 0;
|
info.flags = 0;
|
||||||
|
@ -83,17 +84,27 @@ namespace dxvk {
|
||||||
info.access |= VK_ACCESS_HOST_WRITE_BIT;
|
info.access |= VK_ACCESS_HOST_WRITE_BIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(pDesc->MiscFlags & D3D11_RESOURCE_MISC_TILE_POOL)) {
|
if (p11on12Info) {
|
||||||
|
m_11on12 = *p11on12Info;
|
||||||
|
|
||||||
|
DxvkBufferImportInfo importInfo;
|
||||||
|
importInfo.buffer = VkBuffer(m_11on12.VulkanHandle);
|
||||||
|
importInfo.offset = m_11on12.VulkanOffset;
|
||||||
|
|
||||||
|
if (m_desc.CPUAccessFlags)
|
||||||
|
m_11on12.Resource->Map(0, nullptr, &importInfo.mapPtr);
|
||||||
|
|
||||||
|
m_buffer = m_parent->GetDXVKDevice()->importBuffer(info, importInfo, GetMemoryFlags());
|
||||||
|
m_mapped = m_buffer->getSliceHandle();
|
||||||
|
|
||||||
|
m_mapMode = DetermineMapMode();
|
||||||
|
} else if (!(pDesc->MiscFlags & D3D11_RESOURCE_MISC_TILE_POOL)) {
|
||||||
// Create the buffer and set the entire buffer slice as mapped,
|
// Create the buffer and set the entire buffer slice as mapped,
|
||||||
// so that we only have to update it when invalidating the buffer
|
// so that we only have to update it when invalidating the buffer
|
||||||
m_buffer = m_parent->GetDXVKDevice()->createBuffer(info, GetMemoryFlags());
|
m_buffer = m_parent->GetDXVKDevice()->createBuffer(info, GetMemoryFlags());
|
||||||
m_mapped = m_buffer->getSliceHandle();
|
m_mapped = m_buffer->getSliceHandle();
|
||||||
|
|
||||||
m_mapMode = DetermineMapMode();
|
m_mapMode = DetermineMapMode();
|
||||||
|
|
||||||
// For Stream Output buffers we need a counter
|
|
||||||
if (pDesc->BindFlags & D3D11_BIND_STREAM_OUTPUT)
|
|
||||||
m_soCounter = CreateSoCounterBuffer();
|
|
||||||
} else {
|
} else {
|
||||||
m_sparseAllocator = m_parent->GetDXVKDevice()->createSparsePageAllocator();
|
m_sparseAllocator = m_parent->GetDXVKDevice()->createSparsePageAllocator();
|
||||||
m_sparseAllocator->setCapacity(info.size / SparseMemoryPageSize);
|
m_sparseAllocator->setCapacity(info.size / SparseMemoryPageSize);
|
||||||
|
@ -101,11 +112,16 @@ namespace dxvk {
|
||||||
m_mapped = DxvkBufferSliceHandle();
|
m_mapped = DxvkBufferSliceHandle();
|
||||||
m_mapMode = D3D11_COMMON_BUFFER_MAP_MODE_NONE;
|
m_mapMode = D3D11_COMMON_BUFFER_MAP_MODE_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For Stream Output buffers we need a counter
|
||||||
|
if (pDesc->BindFlags & D3D11_BIND_STREAM_OUTPUT)
|
||||||
|
m_soCounter = CreateSoCounterBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
D3D11Buffer::~D3D11Buffer() {
|
D3D11Buffer::~D3D11Buffer() {
|
||||||
|
if (m_desc.CPUAccessFlags && m_11on12.Resource != nullptr)
|
||||||
|
m_11on12.Resource->Unmap(0, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -138,8 +154,11 @@ namespace dxvk {
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::warn("D3D11Buffer::QueryInterface: Unknown interface query");
|
if (logQueryInterfaceError(__uuidof(ID3D11Buffer), riid)) {
|
||||||
Logger::warn(str::format(riid));
|
Logger::warn("D3D11Buffer::QueryInterface: Unknown interface query");
|
||||||
|
Logger::warn(str::format(riid));
|
||||||
|
}
|
||||||
|
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,6 +257,36 @@ namespace dxvk {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HRESULT D3D11Buffer::GetDescFromD3D12(
|
||||||
|
ID3D12Resource* pResource,
|
||||||
|
const D3D11_RESOURCE_FLAGS* pResourceFlags,
|
||||||
|
D3D11_BUFFER_DESC* pBufferDesc) {
|
||||||
|
D3D12_RESOURCE_DESC desc12 = pResource->GetDesc();
|
||||||
|
|
||||||
|
pBufferDesc->ByteWidth = desc12.Width;
|
||||||
|
pBufferDesc->Usage = D3D11_USAGE_DEFAULT;
|
||||||
|
pBufferDesc->BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||||
|
pBufferDesc->MiscFlags = 0;
|
||||||
|
pBufferDesc->CPUAccessFlags = 0;
|
||||||
|
pBufferDesc->StructureByteStride = 0;
|
||||||
|
|
||||||
|
if (desc12.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET)
|
||||||
|
pBufferDesc->BindFlags |= D3D11_BIND_RENDER_TARGET;
|
||||||
|
|
||||||
|
if (desc12.Flags & D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS)
|
||||||
|
pBufferDesc->BindFlags |= D3D11_BIND_UNORDERED_ACCESS;
|
||||||
|
|
||||||
|
if (pResourceFlags) {
|
||||||
|
pBufferDesc->BindFlags = pResourceFlags->BindFlags;
|
||||||
|
pBufferDesc->MiscFlags |= pResourceFlags->MiscFlags;
|
||||||
|
pBufferDesc->CPUAccessFlags = pResourceFlags->CPUAccessFlags;
|
||||||
|
pBufferDesc->StructureByteStride = pResourceFlags->StructureByteStride;
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
BOOL D3D11Buffer::CheckFormatFeatureSupport(
|
BOOL D3D11Buffer::CheckFormatFeatureSupport(
|
||||||
VkFormat Format,
|
VkFormat Format,
|
||||||
VkFormatFeatureFlags2 Features) const {
|
VkFormatFeatureFlags2 Features) const {
|
||||||
|
@ -290,6 +339,7 @@ namespace dxvk {
|
||||||
|| (m_parent->GetOptions()->cachedDynamicResources & m_desc.BindFlags);
|
|| (m_parent->GetOptions()->cachedDynamicResources & m_desc.BindFlags);
|
||||||
|
|
||||||
if ((memoryFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) && useCached) {
|
if ((memoryFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) && useCached) {
|
||||||
|
memoryFlags &= ~VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
|
||||||
memoryFlags |= VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
|
memoryFlags |= VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
|
||||||
| VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
|
| VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
#include "d3d11_device_child.h"
|
#include "d3d11_device_child.h"
|
||||||
#include "d3d11_interfaces.h"
|
#include "d3d11_interfaces.h"
|
||||||
|
#include "d3d11_on_12.h"
|
||||||
#include "d3d11_resource.h"
|
#include "d3d11_resource.h"
|
||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
@ -41,7 +42,9 @@ namespace dxvk {
|
||||||
|
|
||||||
D3D11Buffer(
|
D3D11Buffer(
|
||||||
D3D11Device* pDevice,
|
D3D11Device* pDevice,
|
||||||
const D3D11_BUFFER_DESC* pDesc);
|
const D3D11_BUFFER_DESC* pDesc,
|
||||||
|
const D3D11_ON_12_RESOURCE_INFO* p11on12Info);
|
||||||
|
|
||||||
~D3D11Buffer();
|
~D3D11Buffer();
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE QueryInterface(
|
HRESULT STDMETHODCALLTYPE QueryInterface(
|
||||||
|
@ -142,6 +145,14 @@ namespace dxvk {
|
||||||
: DxvkCsThread::SynchronizeAll;
|
: DxvkCsThread::SynchronizeAll;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Retrieves D3D11on12 resource info
|
||||||
|
* \returns 11on12 resource info
|
||||||
|
*/
|
||||||
|
D3D11_ON_12_RESOURCE_INFO Get11on12Info() const {
|
||||||
|
return m_11on12;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Normalizes buffer description
|
* \brief Normalizes buffer description
|
||||||
*
|
*
|
||||||
|
@ -151,9 +162,23 @@ namespace dxvk {
|
||||||
static HRESULT NormalizeBufferProperties(
|
static HRESULT NormalizeBufferProperties(
|
||||||
D3D11_BUFFER_DESC* pDesc);
|
D3D11_BUFFER_DESC* pDesc);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Initializes D3D11 buffer description from D3D12
|
||||||
|
*
|
||||||
|
* \param [in] pResource D3D12 resource
|
||||||
|
* \param [in] pResourceFlags D3D11 flag overrides
|
||||||
|
* \param [out] pBufferDesc D3D11 buffer description
|
||||||
|
* \returns \c S_OK if the parameters are valid
|
||||||
|
*/
|
||||||
|
static HRESULT GetDescFromD3D12(
|
||||||
|
ID3D12Resource* pResource,
|
||||||
|
const D3D11_RESOURCE_FLAGS* pResourceFlags,
|
||||||
|
D3D11_BUFFER_DESC* pBufferDesc);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
D3D11_BUFFER_DESC m_desc;
|
D3D11_BUFFER_DESC m_desc;
|
||||||
|
D3D11_ON_12_RESOURCE_INFO m_11on12;
|
||||||
D3D11_COMMON_BUFFER_MAP_MODE m_mapMode;
|
D3D11_COMMON_BUFFER_MAP_MODE m_mapMode;
|
||||||
|
|
||||||
Rc<DxvkBuffer> m_buffer;
|
Rc<DxvkBuffer> m_buffer;
|
||||||
|
|
|
@ -28,8 +28,11 @@ namespace dxvk {
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::warn("D3D11ClassLinkage::QueryInterface: Unknown interface query");
|
if (logQueryInterfaceError(__uuidof(ID3D11ClassLinkage), riid)) {
|
||||||
Logger::warn(str::format(riid));
|
Logger::warn("D3D11ClassLinkage::QueryInterface: Unknown interface query");
|
||||||
|
Logger::warn(str::format(riid));
|
||||||
|
}
|
||||||
|
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,8 +30,11 @@ namespace dxvk {
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::warn("D3D11CommandList::QueryInterface: Unknown interface query");
|
if (logQueryInterfaceError(__uuidof(ID3D11CommandList), riid)) {
|
||||||
Logger::warn(str::format(riid));
|
Logger::warn("D3D11CommandList::QueryInterface: Unknown interface query");
|
||||||
|
Logger::warn(str::format(riid));
|
||||||
|
}
|
||||||
|
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,8 +61,11 @@ namespace dxvk {
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::warn("D3D11DeviceContext::QueryInterface: Unknown interface query");
|
if (logQueryInterfaceError(__uuidof(ID3D11DeviceContext), riid)) {
|
||||||
Logger::warn(str::format(riid));
|
Logger::warn("D3D11DeviceContext::QueryInterface: Unknown interface query");
|
||||||
|
Logger::warn(str::format(riid));
|
||||||
|
}
|
||||||
|
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -383,11 +386,16 @@ namespace dxvk {
|
||||||
const UINT Values[4]) {
|
const UINT Values[4]) {
|
||||||
D3D10DeviceLock lock = LockContext();
|
D3D10DeviceLock lock = LockContext();
|
||||||
|
|
||||||
auto uav = static_cast<D3D11UnorderedAccessView*>(pUnorderedAccessView);
|
if (!pUnorderedAccessView)
|
||||||
|
|
||||||
if (!uav)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
Com<ID3D11UnorderedAccessView> qiUav;
|
||||||
|
|
||||||
|
if (FAILED(pUnorderedAccessView->QueryInterface(IID_PPV_ARGS(&qiUav))))
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto uav = static_cast<D3D11UnorderedAccessView*>(qiUav.ptr());
|
||||||
|
|
||||||
// Gather UAV format info. We'll use this to determine
|
// Gather UAV format info. We'll use this to determine
|
||||||
// whether we need to create a temporary view or not.
|
// whether we need to create a temporary view or not.
|
||||||
D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
|
D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
|
||||||
|
@ -403,15 +411,22 @@ namespace dxvk {
|
||||||
|
|
||||||
VkClearValue clearValue;
|
VkClearValue clearValue;
|
||||||
|
|
||||||
// R11G11B10 is a special case since there's no corresponding
|
if (uavDesc.Format == DXGI_FORMAT_R11G11B10_FLOAT) {
|
||||||
// integer format with the same bit layout. Use R32 instead.
|
// R11G11B10 is a special case since there's no corresponding
|
||||||
if (uavFormat == VK_FORMAT_B10G11R11_UFLOAT_PACK32) {
|
// integer format with the same bit layout. Use R32 instead.
|
||||||
clearValue.color.uint32[0] = ((Values[0] & 0x7FF) << 0)
|
clearValue.color.uint32[0] = ((Values[0] & 0x7FF) << 0)
|
||||||
| ((Values[1] & 0x7FF) << 11)
|
| ((Values[1] & 0x7FF) << 11)
|
||||||
| ((Values[2] & 0x3FF) << 22);
|
| ((Values[2] & 0x3FF) << 22);
|
||||||
clearValue.color.uint32[1] = 0;
|
clearValue.color.uint32[1] = 0;
|
||||||
clearValue.color.uint32[2] = 0;
|
clearValue.color.uint32[2] = 0;
|
||||||
clearValue.color.uint32[3] = 0;
|
clearValue.color.uint32[3] = 0;
|
||||||
|
} else if (uavDesc.Format == DXGI_FORMAT_A8_UNORM) {
|
||||||
|
// We need to use R8_UINT to clear A8_UNORM images,
|
||||||
|
// so remap the alpha component to the red channel.
|
||||||
|
clearValue.color.uint32[0] = Values[3];
|
||||||
|
clearValue.color.uint32[1] = 0;
|
||||||
|
clearValue.color.uint32[2] = 0;
|
||||||
|
clearValue.color.uint32[3] = 0;
|
||||||
} else {
|
} else {
|
||||||
clearValue.color.uint32[0] = Values[0];
|
clearValue.color.uint32[0] = Values[0];
|
||||||
clearValue.color.uint32[1] = Values[1];
|
clearValue.color.uint32[1] = Values[1];
|
||||||
|
@ -913,6 +928,34 @@ namespace dxvk {
|
||||||
const void* pSrcData,
|
const void* pSrcData,
|
||||||
UINT SrcRowPitch,
|
UINT SrcRowPitch,
|
||||||
UINT SrcDepthPitch) {
|
UINT SrcDepthPitch) {
|
||||||
|
if (IsDeferred && unlikely(pDstBox != nullptr) && unlikely(!m_parent->GetOptions()->exposeDriverCommandLists)) {
|
||||||
|
// If called from a deferred context and native command list support is not
|
||||||
|
// exposed, we need to apply the destination box to the source pointer. This
|
||||||
|
// only applies to UpdateSubresource, not to UpdateSubresource1. See MSDN:
|
||||||
|
// https://msdn.microsoft.com/en-us/library/windows/desktop/ff476486(v=vs.85).aspx)
|
||||||
|
size_t srcOffset = pDstBox->left;
|
||||||
|
|
||||||
|
// For textures, the offset logic needs to take the format into account.
|
||||||
|
// Ignore that multi-planar images exist, this is hairy enough already.
|
||||||
|
D3D11CommonTexture* dstTexture = GetCommonTexture(pDstResource);
|
||||||
|
|
||||||
|
if (dstTexture) {
|
||||||
|
auto dstFormat = dstTexture->GetPackedFormat();
|
||||||
|
auto dstFormatInfo = lookupFormatInfo(dstFormat);
|
||||||
|
|
||||||
|
size_t blockSize = dstFormatInfo->elementSize;
|
||||||
|
|
||||||
|
VkOffset3D offset;
|
||||||
|
offset.x = pDstBox->left / dstFormatInfo->blockSize.width;
|
||||||
|
offset.y = pDstBox->top / dstFormatInfo->blockSize.height;
|
||||||
|
offset.z = pDstBox->front / dstFormatInfo->blockSize.depth;
|
||||||
|
|
||||||
|
srcOffset = offset.x * blockSize + offset.y * SrcRowPitch + offset.z * SrcDepthPitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
pSrcData = reinterpret_cast<const char*>(pSrcData) + srcOffset;
|
||||||
|
}
|
||||||
|
|
||||||
UpdateResource(pDstResource, DstSubresource, pDstBox,
|
UpdateResource(pDstResource, DstSubresource, pDstBox,
|
||||||
pSrcData, SrcRowPitch, SrcDepthPitch, 0);
|
pSrcData, SrcRowPitch, SrcDepthPitch, 0);
|
||||||
}
|
}
|
||||||
|
@ -3386,8 +3429,24 @@ namespace dxvk {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static VkDepthBiasRepresentationEXT FormatToDepthBiasRepresentation(DXGI_FORMAT format) {
|
||||||
|
switch (format) {
|
||||||
|
default:
|
||||||
|
case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
|
||||||
|
case DXGI_FORMAT_D32_FLOAT:
|
||||||
|
return VK_DEPTH_BIAS_REPRESENTATION_LEAST_REPRESENTABLE_VALUE_FORMAT_EXT;
|
||||||
|
|
||||||
|
case DXGI_FORMAT_D24_UNORM_S8_UINT:
|
||||||
|
case DXGI_FORMAT_D16_UNORM:
|
||||||
|
return VK_DEPTH_BIAS_REPRESENTATION_LEAST_REPRESENTABLE_VALUE_FORCE_UNORM_EXT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template<typename ContextType>
|
template<typename ContextType>
|
||||||
void D3D11CommonContext<ContextType>::BindFramebuffer() {
|
void D3D11CommonContext<ContextType>::BindFramebuffer() {
|
||||||
|
DxvkDepthBiasRepresentation depthBiasRepresentation =
|
||||||
|
{ VK_DEPTH_BIAS_REPRESENTATION_LEAST_REPRESENTABLE_VALUE_FORMAT_EXT,
|
||||||
|
m_device->features().extDepthBiasControl.depthBiasExact };
|
||||||
DxvkRenderTargets attachments;
|
DxvkRenderTargets attachments;
|
||||||
uint32_t sampleCount = 0;
|
uint32_t sampleCount = 0;
|
||||||
|
|
||||||
|
@ -3408,12 +3467,17 @@ namespace dxvk {
|
||||||
m_state.om.dsv->GetImageView(),
|
m_state.om.dsv->GetImageView(),
|
||||||
m_state.om.dsv->GetRenderLayout() };
|
m_state.om.dsv->GetRenderLayout() };
|
||||||
sampleCount = m_state.om.dsv->GetSampleCount();
|
sampleCount = m_state.om.dsv->GetSampleCount();
|
||||||
|
|
||||||
|
if (m_device->features().extDepthBiasControl.leastRepresentableValueForceUnormRepresentation)
|
||||||
|
depthBiasRepresentation.depthBiasRepresentation = FormatToDepthBiasRepresentation(m_state.om.dsv->GetViewFormat());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create and bind the framebuffer object to the context
|
// Create and bind the framebuffer object to the context
|
||||||
EmitCs([
|
EmitCs([
|
||||||
cAttachments = std::move(attachments)
|
cAttachments = std::move(attachments),
|
||||||
|
cRepresentation = depthBiasRepresentation
|
||||||
] (DxvkContext* ctx) mutable {
|
] (DxvkContext* ctx) mutable {
|
||||||
|
ctx->setDepthBiasRepresentation(cRepresentation);
|
||||||
ctx->bindRenderTargets(Forwarder::move(cAttachments), 0u);
|
ctx->bindRenderTargets(Forwarder::move(cAttachments), 0u);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -5377,6 +5441,7 @@ namespace dxvk {
|
||||||
pRsState->conservativeMode = VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT;
|
pRsState->conservativeMode = VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT;
|
||||||
pRsState->sampleCount = 0;
|
pRsState->sampleCount = 0;
|
||||||
pRsState->flatShading = VK_FALSE;
|
pRsState->flatShading = VK_FALSE;
|
||||||
|
pRsState->lineMode = VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1130,7 +1130,7 @@ namespace dxvk {
|
||||||
if (likely(pBuffer != nullptr))
|
if (likely(pBuffer != nullptr))
|
||||||
bufferSize = static_cast<D3D11Buffer*>(pBuffer)->Desc()->ByteWidth;
|
bufferSize = static_cast<D3D11Buffer*>(pBuffer)->Desc()->ByteWidth;
|
||||||
|
|
||||||
return bufferSize >= Offset + Size;
|
return uint64_t(bufferSize) >= uint64_t(Offset) + uint64_t(Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -19,6 +19,7 @@ namespace dxvk {
|
||||||
m_csThread(Device, Device->createContext(DxvkContextType::Primary)),
|
m_csThread(Device, Device->createContext(DxvkContextType::Primary)),
|
||||||
m_maxImplicitDiscardSize(pParent->GetOptions()->maxImplicitDiscardSize),
|
m_maxImplicitDiscardSize(pParent->GetOptions()->maxImplicitDiscardSize),
|
||||||
m_submissionFence(new sync::CallbackFence()),
|
m_submissionFence(new sync::CallbackFence()),
|
||||||
|
m_flushTracker(pParent->GetOptions()->reproducibleCommandStream),
|
||||||
m_multithread(this, false, pParent->GetOptions()->enableContextLock),
|
m_multithread(this, false, pParent->GetOptions()->enableContextLock),
|
||||||
m_videoContext(this, Device) {
|
m_videoContext(this, Device) {
|
||||||
EmitCs([
|
EmitCs([
|
||||||
|
@ -49,7 +50,7 @@ namespace dxvk {
|
||||||
if (this_thread::isInModuleDetachment())
|
if (this_thread::isInModuleDetachment())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ExecuteFlush(GpuFlushType::ExplicitFlush, nullptr);
|
ExecuteFlush(GpuFlushType::ExplicitFlush, nullptr, true);
|
||||||
SynchronizeCsThread(DxvkCsThread::SynchronizeAll);
|
SynchronizeCsThread(DxvkCsThread::SynchronizeAll);
|
||||||
SynchronizeDevice();
|
SynchronizeDevice();
|
||||||
}
|
}
|
||||||
|
@ -150,7 +151,7 @@ namespace dxvk {
|
||||||
query->NotifyEnd();
|
query->NotifyEnd();
|
||||||
|
|
||||||
if (query->IsStalling())
|
if (query->IsStalling())
|
||||||
ExecuteFlush(GpuFlushType::ImplicitSynchronization, nullptr);
|
ExecuteFlush(GpuFlushType::ImplicitSynchronization, nullptr, false);
|
||||||
else if (query->IsEvent())
|
else if (query->IsEvent())
|
||||||
ConsiderFlush(GpuFlushType::ImplicitStrongHint);
|
ConsiderFlush(GpuFlushType::ImplicitStrongHint);
|
||||||
}
|
}
|
||||||
|
@ -160,7 +161,7 @@ namespace dxvk {
|
||||||
void STDMETHODCALLTYPE D3D11ImmediateContext::Flush() {
|
void STDMETHODCALLTYPE D3D11ImmediateContext::Flush() {
|
||||||
D3D10DeviceLock lock = LockContext();
|
D3D10DeviceLock lock = LockContext();
|
||||||
|
|
||||||
ExecuteFlush(GpuFlushType::ExplicitFlush, nullptr);
|
ExecuteFlush(GpuFlushType::ExplicitFlush, nullptr, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -169,7 +170,7 @@ namespace dxvk {
|
||||||
HANDLE hEvent) {
|
HANDLE hEvent) {
|
||||||
D3D10DeviceLock lock = LockContext();
|
D3D10DeviceLock lock = LockContext();
|
||||||
|
|
||||||
ExecuteFlush(GpuFlushType::ExplicitFlush, hEvent);
|
ExecuteFlush(GpuFlushType::ExplicitFlush, hEvent, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -189,7 +190,7 @@ namespace dxvk {
|
||||||
ctx->signalFence(cFence, cValue);
|
ctx->signalFence(cFence, cValue);
|
||||||
});
|
});
|
||||||
|
|
||||||
ExecuteFlush(GpuFlushType::ExplicitFlush, nullptr);
|
ExecuteFlush(GpuFlushType::ExplicitFlush, nullptr, true);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,7 +204,7 @@ namespace dxvk {
|
||||||
if (!fence)
|
if (!fence)
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
|
|
||||||
ExecuteFlush(GpuFlushType::ExplicitFlush, nullptr);
|
ExecuteFlush(GpuFlushType::ExplicitFlush, nullptr, true);
|
||||||
|
|
||||||
EmitCs([
|
EmitCs([
|
||||||
cFence = fence->GetFence(),
|
cFence = fence->GetFence(),
|
||||||
|
@ -753,6 +754,74 @@ namespace dxvk {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void D3D11ImmediateContext::Acquire11on12Resource(
|
||||||
|
ID3D11Resource* pResource,
|
||||||
|
VkImageLayout SrcLayout) {
|
||||||
|
D3D10DeviceLock lock = LockContext();
|
||||||
|
|
||||||
|
auto texture = GetCommonTexture(pResource);
|
||||||
|
auto buffer = GetCommonBuffer(pResource);
|
||||||
|
|
||||||
|
if (buffer) {
|
||||||
|
EmitCs([
|
||||||
|
cBuffer = buffer->GetBuffer()
|
||||||
|
] (DxvkContext* ctx) {
|
||||||
|
ctx->emitBufferBarrier(cBuffer,
|
||||||
|
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
|
||||||
|
VK_ACCESS_MEMORY_WRITE_BIT | VK_ACCESS_MEMORY_READ_BIT,
|
||||||
|
cBuffer->info().stages,
|
||||||
|
cBuffer->info().access);
|
||||||
|
});
|
||||||
|
} else if (texture) {
|
||||||
|
EmitCs([
|
||||||
|
cImage = texture->GetImage(),
|
||||||
|
cLayout = SrcLayout
|
||||||
|
] (DxvkContext* ctx) {
|
||||||
|
ctx->emitImageBarrier(cImage, cLayout,
|
||||||
|
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
|
||||||
|
VK_ACCESS_MEMORY_WRITE_BIT | VK_ACCESS_MEMORY_READ_BIT,
|
||||||
|
cImage->info().layout,
|
||||||
|
cImage->info().stages,
|
||||||
|
cImage->info().access);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void D3D11ImmediateContext::Release11on12Resource(
|
||||||
|
ID3D11Resource* pResource,
|
||||||
|
VkImageLayout DstLayout) {
|
||||||
|
D3D10DeviceLock lock = LockContext();
|
||||||
|
|
||||||
|
auto texture = GetCommonTexture(pResource);
|
||||||
|
auto buffer = GetCommonBuffer(pResource);
|
||||||
|
|
||||||
|
if (buffer) {
|
||||||
|
EmitCs([
|
||||||
|
cBuffer = buffer->GetBuffer()
|
||||||
|
] (DxvkContext* ctx) {
|
||||||
|
ctx->emitBufferBarrier(cBuffer,
|
||||||
|
cBuffer->info().stages,
|
||||||
|
cBuffer->info().access,
|
||||||
|
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
|
||||||
|
VK_ACCESS_MEMORY_WRITE_BIT | VK_ACCESS_MEMORY_READ_BIT);
|
||||||
|
});
|
||||||
|
} else if (texture) {
|
||||||
|
EmitCs([
|
||||||
|
cImage = texture->GetImage(),
|
||||||
|
cLayout = DstLayout
|
||||||
|
] (DxvkContext* ctx) {
|
||||||
|
ctx->emitImageBarrier(cImage,
|
||||||
|
cImage->info().layout,
|
||||||
|
cImage->info().stages,
|
||||||
|
cImage->info().access,
|
||||||
|
cLayout, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
|
||||||
|
VK_ACCESS_MEMORY_WRITE_BIT | VK_ACCESS_MEMORY_READ_BIT);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void D3D11ImmediateContext::SynchronizeCsThread(uint64_t SequenceNumber) {
|
void D3D11ImmediateContext::SynchronizeCsThread(uint64_t SequenceNumber) {
|
||||||
D3D10DeviceLock lock = LockContext();
|
D3D10DeviceLock lock = LockContext();
|
||||||
|
|
||||||
|
@ -811,7 +880,7 @@ namespace dxvk {
|
||||||
if (isInUse) {
|
if (isInUse) {
|
||||||
// Make sure pending commands using the resource get
|
// Make sure pending commands using the resource get
|
||||||
// executed on the the GPU if we have to wait for it
|
// executed on the the GPU if we have to wait for it
|
||||||
ExecuteFlush(GpuFlushType::ImplicitSynchronization, nullptr);
|
ExecuteFlush(GpuFlushType::ImplicitSynchronization, nullptr, false);
|
||||||
SynchronizeCsThread(SequenceNumber);
|
SynchronizeCsThread(SequenceNumber);
|
||||||
|
|
||||||
m_device->waitForResource(Resource, access);
|
m_device->waitForResource(Resource, access);
|
||||||
|
@ -865,13 +934,19 @@ namespace dxvk {
|
||||||
uint64_t submissionId = m_submissionFence->value();
|
uint64_t submissionId = m_submissionFence->value();
|
||||||
|
|
||||||
if (m_flushTracker.considerFlush(FlushType, chunkId, submissionId))
|
if (m_flushTracker.considerFlush(FlushType, chunkId, submissionId))
|
||||||
ExecuteFlush(FlushType, nullptr);
|
ExecuteFlush(FlushType, nullptr, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void D3D11ImmediateContext::ExecuteFlush(
|
void D3D11ImmediateContext::ExecuteFlush(
|
||||||
GpuFlushType FlushType,
|
GpuFlushType FlushType,
|
||||||
HANDLE hEvent) {
|
HANDLE hEvent,
|
||||||
|
BOOL Synchronize) {
|
||||||
|
bool synchronizeSubmission = Synchronize && m_parent->Is11on12Device();
|
||||||
|
|
||||||
|
if (synchronizeSubmission)
|
||||||
|
m_submitStatus.result = VK_NOT_READY;
|
||||||
|
|
||||||
// Flush init context so that new resources are fully initialized
|
// Flush init context so that new resources are fully initialized
|
||||||
// before the app can access them in any way. This has to happen
|
// before the app can access them in any way. This has to happen
|
||||||
// unconditionally since we may otherwise deadlock on Map.
|
// unconditionally since we may otherwise deadlock on Map.
|
||||||
|
@ -892,10 +967,11 @@ namespace dxvk {
|
||||||
|
|
||||||
EmitCs<false>([
|
EmitCs<false>([
|
||||||
cSubmissionFence = m_submissionFence,
|
cSubmissionFence = m_submissionFence,
|
||||||
cSubmissionId = submissionId
|
cSubmissionId = submissionId,
|
||||||
|
cSubmissionStatus = synchronizeSubmission ? &m_submitStatus : nullptr
|
||||||
] (DxvkContext* ctx) {
|
] (DxvkContext* ctx) {
|
||||||
ctx->signal(cSubmissionFence, cSubmissionId);
|
ctx->signal(cSubmissionFence, cSubmissionId);
|
||||||
ctx->flushCommandList();
|
ctx->flushCommandList(cSubmissionStatus);
|
||||||
});
|
});
|
||||||
|
|
||||||
FlushCsChunk();
|
FlushCsChunk();
|
||||||
|
@ -903,6 +979,11 @@ namespace dxvk {
|
||||||
// Notify flush tracker about the flush
|
// Notify flush tracker about the flush
|
||||||
m_flushSeqNum = m_csSeqNum;
|
m_flushSeqNum = m_csSeqNum;
|
||||||
m_flushTracker.notifyFlush(m_flushSeqNum, submissionId);
|
m_flushTracker.notifyFlush(m_flushSeqNum, submissionId);
|
||||||
|
|
||||||
|
// If necessary, block calling thread until the
|
||||||
|
// Vulkan queue submission is performed.
|
||||||
|
if (synchronizeSubmission)
|
||||||
|
m_device->waitForSubmission(&m_submitStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ namespace dxvk {
|
||||||
friend class D3D11CommonContext<D3D11ImmediateContext>;
|
friend class D3D11CommonContext<D3D11ImmediateContext>;
|
||||||
friend class D3D11SwapChain;
|
friend class D3D11SwapChain;
|
||||||
friend class D3D11VideoContext;
|
friend class D3D11VideoContext;
|
||||||
|
friend class D3D11DXGIKeyedMutex;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
D3D11ImmediateContext(
|
D3D11ImmediateContext(
|
||||||
|
@ -77,9 +78,21 @@ namespace dxvk {
|
||||||
ID3DDeviceContextState* pState,
|
ID3DDeviceContextState* pState,
|
||||||
ID3DDeviceContextState** ppPreviousState);
|
ID3DDeviceContextState** ppPreviousState);
|
||||||
|
|
||||||
|
void Acquire11on12Resource(
|
||||||
|
ID3D11Resource* pResource,
|
||||||
|
VkImageLayout SrcLayout);
|
||||||
|
|
||||||
|
void Release11on12Resource(
|
||||||
|
ID3D11Resource* pResource,
|
||||||
|
VkImageLayout DstLayout);
|
||||||
|
|
||||||
void SynchronizeCsThread(
|
void SynchronizeCsThread(
|
||||||
uint64_t SequenceNumber);
|
uint64_t SequenceNumber);
|
||||||
|
|
||||||
|
D3D10Multithread& GetMultithread() {
|
||||||
|
return m_multithread;
|
||||||
|
}
|
||||||
|
|
||||||
D3D10DeviceLock LockContext() {
|
D3D10DeviceLock LockContext() {
|
||||||
return m_multithread.AcquireLock();
|
return m_multithread.AcquireLock();
|
||||||
}
|
}
|
||||||
|
@ -95,6 +108,7 @@ namespace dxvk {
|
||||||
|
|
||||||
Rc<sync::CallbackFence> m_submissionFence;
|
Rc<sync::CallbackFence> m_submissionFence;
|
||||||
uint64_t m_submissionId = 0ull;
|
uint64_t m_submissionId = 0ull;
|
||||||
|
DxvkSubmitStatus m_submitStatus;
|
||||||
|
|
||||||
uint64_t m_flushSeqNum = 0ull;
|
uint64_t m_flushSeqNum = 0ull;
|
||||||
GpuFlushTracker m_flushTracker;
|
GpuFlushTracker m_flushTracker;
|
||||||
|
@ -165,7 +179,8 @@ namespace dxvk {
|
||||||
|
|
||||||
void ExecuteFlush(
|
void ExecuteFlush(
|
||||||
GpuFlushType FlushType,
|
GpuFlushType FlushType,
|
||||||
HANDLE hEvent);
|
HANDLE hEvent,
|
||||||
|
BOOL Synchronize);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -37,12 +37,15 @@ namespace dxvk {
|
||||||
|
|
||||||
if (riid == __uuidof(ID3D10DeviceChild)
|
if (riid == __uuidof(ID3D10DeviceChild)
|
||||||
|| riid == __uuidof(ID3D10DepthStencilState)) {
|
|| riid == __uuidof(ID3D10DepthStencilState)) {
|
||||||
*ppvObject = ref(this);
|
*ppvObject = ref(&m_d3d10);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::warn("D3D11DepthStencilState::QueryInterface: Unknown interface query");
|
if (logQueryInterfaceError(__uuidof(ID3D11DepthStencilState), riid)) {
|
||||||
Logger::warn(str::format(riid));
|
Logger::warn("D3D11DepthStencilState::QueryInterface: Unknown interface query");
|
||||||
|
Logger::warn(str::format(riid));
|
||||||
|
}
|
||||||
|
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,10 +45,10 @@ namespace dxvk {
|
||||||
m_dxvkDevice (pContainer->GetDXVKDevice()),
|
m_dxvkDevice (pContainer->GetDXVKDevice()),
|
||||||
m_dxvkAdapter (m_dxvkDevice->adapter()),
|
m_dxvkAdapter (m_dxvkDevice->adapter()),
|
||||||
m_d3d11Formats (m_dxvkDevice),
|
m_d3d11Formats (m_dxvkDevice),
|
||||||
m_d3d11Options (m_dxvkDevice->instance()->config(), m_dxvkDevice),
|
m_d3d11Options (m_dxvkDevice->instance()->config()),
|
||||||
m_dxbcOptions (m_dxvkDevice, m_d3d11Options),
|
m_dxbcOptions (m_dxvkDevice, m_d3d11Options),
|
||||||
m_maxFeatureLevel (GetMaxFeatureLevel(m_dxvkDevice->instance(), m_dxvkDevice->adapter())),
|
m_maxFeatureLevel (GetMaxFeatureLevel(m_dxvkDevice->instance(), m_dxvkDevice->adapter())),
|
||||||
m_deviceFeatures (m_dxvkDevice->instance(), m_dxvkDevice->adapter(), m_featureLevel) {
|
m_deviceFeatures (m_dxvkDevice->instance(), m_dxvkDevice->adapter(), m_d3d11Options, m_featureLevel) {
|
||||||
m_initializer = new D3D11Initializer(this);
|
m_initializer = new D3D11Initializer(this);
|
||||||
m_context = new D3D11ImmediateContext(this, m_dxvkDevice);
|
m_context = new D3D11ImmediateContext(this, m_dxvkDevice);
|
||||||
m_d3d10Device = new D3D10Device(this, m_context.ptr());
|
m_d3d10Device = new D3D10Device(this, m_context.ptr());
|
||||||
|
@ -100,7 +100,7 @@ namespace dxvk {
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const Com<D3D11Buffer> buffer = new D3D11Buffer(this, &desc);
|
const Com<D3D11Buffer> buffer = new D3D11Buffer(this, &desc, nullptr);
|
||||||
|
|
||||||
if (!(desc.MiscFlags & D3D11_RESOURCE_MISC_TILE_POOL))
|
if (!(desc.MiscFlags & D3D11_RESOURCE_MISC_TILE_POOL))
|
||||||
m_initializer->InitBuffer(buffer.ptr(), pInitialData);
|
m_initializer->InitBuffer(buffer.ptr(), pInitialData);
|
||||||
|
@ -149,7 +149,7 @@ namespace dxvk {
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const Com<D3D11Texture1D> texture = new D3D11Texture1D(this, &desc);
|
const Com<D3D11Texture1D> texture = new D3D11Texture1D(this, &desc, nullptr);
|
||||||
m_initializer->InitTexture(texture->GetCommonTexture(), pInitialData);
|
m_initializer->InitTexture(texture->GetCommonTexture(), pInitialData);
|
||||||
*ppTexture1D = texture.ref();
|
*ppTexture1D = texture.ref();
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
@ -229,7 +229,7 @@ namespace dxvk {
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Com<D3D11Texture2D> texture = new D3D11Texture2D(this, &desc, nullptr);
|
Com<D3D11Texture2D> texture = new D3D11Texture2D(this, &desc, nullptr, nullptr);
|
||||||
m_initializer->InitTexture(texture->GetCommonTexture(), pInitialData);
|
m_initializer->InitTexture(texture->GetCommonTexture(), pInitialData);
|
||||||
*ppTexture2D = texture.ref();
|
*ppTexture2D = texture.ref();
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
@ -308,7 +308,7 @@ namespace dxvk {
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Com<D3D11Texture3D> texture = new D3D11Texture3D(this, &desc);
|
Com<D3D11Texture3D> texture = new D3D11Texture3D(this, &desc, nullptr);
|
||||||
m_initializer->InitTexture(texture->GetCommonTexture(), pInitialData);
|
m_initializer->InitTexture(texture->GetCommonTexture(), pInitialData);
|
||||||
*ppTexture3D = texture.ref();
|
*ppTexture3D = texture.ref();
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
@ -1348,7 +1348,7 @@ namespace dxvk {
|
||||||
m_deviceFeatures = D3D11DeviceFeatures(
|
m_deviceFeatures = D3D11DeviceFeatures(
|
||||||
m_dxvkDevice->instance(),
|
m_dxvkDevice->instance(),
|
||||||
m_dxvkDevice->adapter(),
|
m_dxvkDevice->adapter(),
|
||||||
m_featureLevel);
|
m_d3d11Options, m_featureLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pChosenFeatureLevel)
|
if (pChosenFeatureLevel)
|
||||||
|
@ -1832,6 +1832,11 @@ namespace dxvk {
|
||||||
DXGI_VK_FORMAT_MODE Mode) const {
|
DXGI_VK_FORMAT_MODE Mode) const {
|
||||||
return m_d3d11Formats.GetFormatFamily(Format, Mode);
|
return m_d3d11Formats.GetFormatFamily(Format, Mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool D3D11Device::Is11on12Device() const {
|
||||||
|
return m_container->Is11on12Device();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void D3D11Device::FlushInitContext() {
|
void D3D11Device::FlushInitContext() {
|
||||||
|
@ -1948,6 +1953,11 @@ namespace dxvk {
|
||||||
enabled.core.features.shaderFloat64 = supported.core.features.shaderFloat64;
|
enabled.core.features.shaderFloat64 = supported.core.features.shaderFloat64;
|
||||||
enabled.core.features.shaderInt64 = supported.core.features.shaderInt64;
|
enabled.core.features.shaderInt64 = supported.core.features.shaderInt64;
|
||||||
|
|
||||||
|
// Depth bias control
|
||||||
|
enabled.extDepthBiasControl.depthBiasControl = supported.extDepthBiasControl.depthBiasControl;
|
||||||
|
enabled.extDepthBiasControl.depthBiasExact = supported.extDepthBiasControl.depthBiasExact;
|
||||||
|
enabled.extDepthBiasControl.leastRepresentableValueForceUnormRepresentation = supported.extDepthBiasControl.leastRepresentableValueForceUnormRepresentation;
|
||||||
|
|
||||||
return enabled;
|
return enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2299,10 +2309,14 @@ namespace dxvk {
|
||||||
d3d11Desc.CPUAccessFlags = metadata.CPUAccessFlags;
|
d3d11Desc.CPUAccessFlags = metadata.CPUAccessFlags;
|
||||||
d3d11Desc.MiscFlags = metadata.MiscFlags;
|
d3d11Desc.MiscFlags = metadata.MiscFlags;
|
||||||
d3d11Desc.TextureLayout = metadata.TextureLayout;
|
d3d11Desc.TextureLayout = metadata.TextureLayout;
|
||||||
|
if ((d3d11Desc.MiscFlags & D3D11_RESOURCE_MISC_SHARED_NTHANDLE) && !(d3d11Desc.MiscFlags & (D3D11_RESOURCE_MISC_SHARED | D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX))) {
|
||||||
|
Logger::warn("Fixing up wrong MiscFlags");
|
||||||
|
d3d11Desc.MiscFlags |= D3D11_RESOURCE_MISC_SHARED;
|
||||||
|
}
|
||||||
|
|
||||||
// Only 2D textures may be shared
|
// Only 2D textures may be shared
|
||||||
try {
|
try {
|
||||||
const Com<D3D11Texture2D> texture = new D3D11Texture2D(this, &d3d11Desc, hResource);
|
const Com<D3D11Texture2D> texture = new D3D11Texture2D(this, &d3d11Desc, nullptr, hResource);
|
||||||
texture->QueryInterface(ReturnedInterface, ppResource);
|
texture->QueryInterface(ReturnedInterface, ppResource);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
@ -3057,18 +3071,22 @@ namespace dxvk {
|
||||||
|
|
||||||
D3D11DXGIDevice::D3D11DXGIDevice(
|
D3D11DXGIDevice::D3D11DXGIDevice(
|
||||||
IDXGIAdapter* pAdapter,
|
IDXGIAdapter* pAdapter,
|
||||||
const Rc<DxvkInstance>& pDxvkInstance,
|
ID3D12Device* pD3D12Device,
|
||||||
const Rc<DxvkAdapter>& pDxvkAdapter,
|
ID3D12CommandQueue* pD3D12Queue,
|
||||||
|
Rc<DxvkInstance> pDxvkInstance,
|
||||||
|
Rc<DxvkAdapter> pDxvkAdapter,
|
||||||
|
Rc<DxvkDevice> pDxvkDevice,
|
||||||
D3D_FEATURE_LEVEL FeatureLevel,
|
D3D_FEATURE_LEVEL FeatureLevel,
|
||||||
UINT FeatureFlags)
|
UINT FeatureFlags)
|
||||||
: m_dxgiAdapter (pAdapter),
|
: m_dxgiAdapter (pAdapter),
|
||||||
m_dxvkInstance (pDxvkInstance),
|
m_dxvkInstance (pDxvkInstance),
|
||||||
m_dxvkAdapter (pDxvkAdapter),
|
m_dxvkAdapter (pDxvkAdapter),
|
||||||
m_dxvkDevice (CreateDevice(FeatureLevel)),
|
m_dxvkDevice (pDxvkDevice),
|
||||||
m_d3d11Device (this, FeatureLevel, FeatureFlags),
|
m_d3d11Device (this, FeatureLevel, FeatureFlags),
|
||||||
m_d3d11DeviceExt(this, &m_d3d11Device),
|
m_d3d11DeviceExt(this, &m_d3d11Device),
|
||||||
m_d3d11Interop (this, &m_d3d11Device),
|
m_d3d11Interop (this, &m_d3d11Device),
|
||||||
m_d3d11Video (this, &m_d3d11Device),
|
m_d3d11Video (this, &m_d3d11Device),
|
||||||
|
m_d3d11on12 (this, &m_d3d11Device, pD3D12Device, pD3D12Queue),
|
||||||
m_metaDevice (this),
|
m_metaDevice (this),
|
||||||
m_dxvkFactory (this, &m_d3d11Device) {
|
m_dxvkFactory (this, &m_d3d11Device) {
|
||||||
|
|
||||||
|
@ -3076,7 +3094,7 @@ namespace dxvk {
|
||||||
|
|
||||||
|
|
||||||
D3D11DXGIDevice::~D3D11DXGIDevice() {
|
D3D11DXGIDevice::~D3D11DXGIDevice() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3140,6 +3158,13 @@ namespace dxvk {
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_d3d11on12.Is11on12Device()) {
|
||||||
|
if (riid == __uuidof(ID3D11On12Device)) {
|
||||||
|
*ppvObject = ref(&m_d3d11on12);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (riid == __uuidof(ID3D10Multithread)) {
|
if (riid == __uuidof(ID3D10Multithread)) {
|
||||||
Com<ID3D11DeviceContext> context;
|
Com<ID3D11DeviceContext> context;
|
||||||
m_d3d11Device.GetImmediateContext(&context);
|
m_d3d11Device.GetImmediateContext(&context);
|
||||||
|
@ -3153,8 +3178,11 @@ namespace dxvk {
|
||||||
if (riid == GUID{0xd56e2a4c,0x5127,0x8437,{0x65,0x8a,0x98,0xc5,0xbb,0x78,0x94,0x98}})
|
if (riid == GUID{0xd56e2a4c,0x5127,0x8437,{0x65,0x8a,0x98,0xc5,0xbb,0x78,0x94,0x98}})
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
|
|
||||||
Logger::warn("D3D11DXGIDevice::QueryInterface: Unknown interface query");
|
if (logQueryInterfaceError(__uuidof(IDXGIDXVKDevice), riid)) {
|
||||||
Logger::warn(str::format(riid));
|
Logger::warn("D3D11DXGIDevice::QueryInterface: Unknown interface query");
|
||||||
|
Logger::warn(str::format(riid));
|
||||||
|
}
|
||||||
|
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3383,8 +3411,9 @@ namespace dxvk {
|
||||||
|
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE D3D11DXGIDevice::EnqueueSetEvent(HANDLE hEvent) {
|
HRESULT STDMETHODCALLTYPE D3D11DXGIDevice::EnqueueSetEvent(HANDLE hEvent) {
|
||||||
Logger::err("D3D11DXGIDevice::EnqueueSetEvent: Not implemented");
|
auto immediateContext = m_d3d11Device.GetContext();
|
||||||
return DXGI_ERROR_UNSUPPORTED;
|
immediateContext->Flush1(D3D11_CONTEXT_TYPE_ALL, hEvent);
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3400,10 +3429,4 @@ namespace dxvk {
|
||||||
return m_dxvkDevice;
|
return m_dxvkDevice;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Rc<DxvkDevice> D3D11DXGIDevice::CreateDevice(D3D_FEATURE_LEVEL FeatureLevel) {
|
|
||||||
DxvkDeviceFeatures deviceFeatures = D3D11Device::GetDeviceFeatures(m_dxvkAdapter);
|
|
||||||
return m_dxvkAdapter->createDevice(m_dxvkInstance, deviceFeatures);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "d3d11_initializer.h"
|
#include "d3d11_initializer.h"
|
||||||
#include "d3d11_interfaces.h"
|
#include "d3d11_interfaces.h"
|
||||||
#include "d3d11_interop.h"
|
#include "d3d11_interop.h"
|
||||||
|
#include "d3d11_on_12.h"
|
||||||
#include "d3d11_options.h"
|
#include "d3d11_options.h"
|
||||||
#include "d3d11_shader.h"
|
#include "d3d11_shader.h"
|
||||||
#include "d3d11_state.h"
|
#include "d3d11_state.h"
|
||||||
|
@ -420,7 +421,13 @@ namespace dxvk {
|
||||||
D3D10Device* GetD3D10Interface() const {
|
D3D10Device* GetD3D10Interface() const {
|
||||||
return m_d3d10Device;
|
return m_d3d10Device;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
D3D11ImmediateContext* GetContext() const {
|
||||||
|
return m_context.ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Is11on12Device() const;
|
||||||
|
|
||||||
static D3D_FEATURE_LEVEL GetMaxFeatureLevel(
|
static D3D_FEATURE_LEVEL GetMaxFeatureLevel(
|
||||||
const Rc<DxvkInstance>& Instance,
|
const Rc<DxvkInstance>& Instance,
|
||||||
const Rc<DxvkAdapter>& Adapter);
|
const Rc<DxvkAdapter>& Adapter);
|
||||||
|
@ -430,7 +437,7 @@ namespace dxvk {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
IDXGIObject* m_container;
|
D3D11DXGIDevice* m_container;
|
||||||
|
|
||||||
D3D_FEATURE_LEVEL m_featureLevel;
|
D3D_FEATURE_LEVEL m_featureLevel;
|
||||||
UINT m_featureFlags;
|
UINT m_featureFlags;
|
||||||
|
@ -764,8 +771,11 @@ namespace dxvk {
|
||||||
|
|
||||||
D3D11DXGIDevice(
|
D3D11DXGIDevice(
|
||||||
IDXGIAdapter* pAdapter,
|
IDXGIAdapter* pAdapter,
|
||||||
const Rc<DxvkInstance>& pDxvkInstance,
|
ID3D12Device* pD3D12Device,
|
||||||
const Rc<DxvkAdapter>& pDxvkAdapter,
|
ID3D12CommandQueue* pD3D12Queue,
|
||||||
|
Rc<DxvkInstance> pDxvkInstance,
|
||||||
|
Rc<DxvkAdapter> pDxvkAdapter,
|
||||||
|
Rc<DxvkDevice> pDxvkDevice,
|
||||||
D3D_FEATURE_LEVEL FeatureLevel,
|
D3D_FEATURE_LEVEL FeatureLevel,
|
||||||
UINT FeatureFlags);
|
UINT FeatureFlags);
|
||||||
|
|
||||||
|
@ -834,6 +844,10 @@ namespace dxvk {
|
||||||
|
|
||||||
Rc<DxvkDevice> STDMETHODCALLTYPE GetDXVKDevice();
|
Rc<DxvkDevice> STDMETHODCALLTYPE GetDXVKDevice();
|
||||||
|
|
||||||
|
BOOL Is11on12Device() const {
|
||||||
|
return m_d3d11on12.Is11on12Device();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Com<IDXGIAdapter> m_dxgiAdapter;
|
Com<IDXGIAdapter> m_dxgiAdapter;
|
||||||
|
@ -846,14 +860,13 @@ namespace dxvk {
|
||||||
D3D11DeviceExt m_d3d11DeviceExt;
|
D3D11DeviceExt m_d3d11DeviceExt;
|
||||||
D3D11VkInterop m_d3d11Interop;
|
D3D11VkInterop m_d3d11Interop;
|
||||||
D3D11VideoDevice m_d3d11Video;
|
D3D11VideoDevice m_d3d11Video;
|
||||||
|
D3D11on12Device m_d3d11on12;
|
||||||
DXGIDXVKDevice m_metaDevice;
|
DXGIDXVKDevice m_metaDevice;
|
||||||
|
|
||||||
DXGIVkSwapChainFactory m_dxvkFactory;
|
DXGIVkSwapChainFactory m_dxvkFactory;
|
||||||
|
|
||||||
uint32_t m_frameLatency = DefaultFrameLatency;
|
uint32_t m_frameLatency = DefaultFrameLatency;
|
||||||
|
|
||||||
Rc<DxvkDevice> CreateDevice(D3D_FEATURE_LEVEL FeatureLevel);
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ namespace dxvk {
|
||||||
D3D11DeviceFeatures::D3D11DeviceFeatures(
|
D3D11DeviceFeatures::D3D11DeviceFeatures(
|
||||||
const Rc<DxvkInstance>& Instance,
|
const Rc<DxvkInstance>& Instance,
|
||||||
const Rc<DxvkAdapter>& Adapter,
|
const Rc<DxvkAdapter>& Adapter,
|
||||||
|
const D3D11Options& Options,
|
||||||
D3D_FEATURE_LEVEL FeatureLevel)
|
D3D_FEATURE_LEVEL FeatureLevel)
|
||||||
: m_features (Adapter->features()),
|
: m_features (Adapter->features()),
|
||||||
m_properties (Adapter->devicePropertiesExt()) {
|
m_properties (Adapter->devicePropertiesExt()) {
|
||||||
|
@ -107,7 +108,7 @@ namespace dxvk {
|
||||||
m_gpuVirtualAddress.MaxGPUVirtualAddressBitsPerProcess = 40;
|
m_gpuVirtualAddress.MaxGPUVirtualAddressBitsPerProcess = 40;
|
||||||
|
|
||||||
// Marker support only depends on the debug utils extension
|
// Marker support only depends on the debug utils extension
|
||||||
m_marker.Profile = Instance->extensions().extDebugUtils;
|
m_marker.Profile = static_cast<bool>(Instance->extensions().extDebugUtils);
|
||||||
|
|
||||||
// DXVK will keep all shaders in memory once created, and all Vulkan
|
// DXVK will keep all shaders in memory once created, and all Vulkan
|
||||||
// drivers that we know of that can run DXVK have an on-disk cache.
|
// drivers that we know of that can run DXVK have an on-disk cache.
|
||||||
|
@ -118,11 +119,11 @@ namespace dxvk {
|
||||||
m_shaderMinPrecision.PixelShaderMinPrecision = 0;
|
m_shaderMinPrecision.PixelShaderMinPrecision = 0;
|
||||||
m_shaderMinPrecision.AllOtherShaderStagesMinPrecision = 0;
|
m_shaderMinPrecision.AllOtherShaderStagesMinPrecision = 0;
|
||||||
|
|
||||||
// Report native support for command lists here so that we do not actually have
|
// Report native support for command lists by default. Deferred context
|
||||||
// to re-implement the UpdateSubresource bug from the D3D11 runtime, see MSDN:
|
// usage can be beneficial for us as ExecuteCommandList has low overhead,
|
||||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/ff476486(v=vs.85).aspx)
|
// and we avoid having to deal with known UpdateSubresource bugs this way.
|
||||||
m_threading.DriverConcurrentCreates = TRUE;
|
m_threading.DriverConcurrentCreates = TRUE;
|
||||||
m_threading.DriverCommandLists = TRUE;
|
m_threading.DriverCommandLists = Options.exposeDriverCommandLists;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -182,7 +183,8 @@ namespace dxvk {
|
||||||
D3D_FEATURE_LEVEL D3D11DeviceFeatures::GetMaxFeatureLevel(
|
D3D_FEATURE_LEVEL D3D11DeviceFeatures::GetMaxFeatureLevel(
|
||||||
const Rc<DxvkInstance>& Instance,
|
const Rc<DxvkInstance>& Instance,
|
||||||
const Rc<DxvkAdapter>& Adapter) {
|
const Rc<DxvkAdapter>& Adapter) {
|
||||||
D3D11DeviceFeatures features(Instance, Adapter, D3D_FEATURE_LEVEL_12_1);
|
D3D11Options options(Instance->config());
|
||||||
|
D3D11DeviceFeatures features(Instance, Adapter, options, D3D_FEATURE_LEVEL_12_1);
|
||||||
return features.GetMaxFeatureLevel();
|
return features.GetMaxFeatureLevel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "d3d11_include.h"
|
#include "d3d11_include.h"
|
||||||
|
#include "d3d11_options.h"
|
||||||
|
|
||||||
#include "../dxvk/dxvk_adapter.h"
|
#include "../dxvk/dxvk_adapter.h"
|
||||||
#include "../dxvk/dxvk_instance.h"
|
#include "../dxvk/dxvk_instance.h"
|
||||||
|
@ -21,6 +22,7 @@ namespace dxvk {
|
||||||
D3D11DeviceFeatures(
|
D3D11DeviceFeatures(
|
||||||
const Rc<DxvkInstance>& Instance,
|
const Rc<DxvkInstance>& Instance,
|
||||||
const Rc<DxvkAdapter>& Adapter,
|
const Rc<DxvkAdapter>& Adapter,
|
||||||
|
const D3D11Options& Options,
|
||||||
D3D_FEATURE_LEVEL FeatureLevel);
|
D3D_FEATURE_LEVEL FeatureLevel);
|
||||||
|
|
||||||
~D3D11DeviceFeatures();
|
~D3D11DeviceFeatures();
|
||||||
|
|
|
@ -48,8 +48,11 @@ namespace dxvk {
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::warn("D3D11Fence: Unknown interface query");
|
if (logQueryInterfaceError(__uuidof(ID3D11Fence), riid)) {
|
||||||
Logger::warn(str::format(riid));
|
Logger::warn("D3D11Fence: Unknown interface query");
|
||||||
|
Logger::warn(str::format(riid));
|
||||||
|
}
|
||||||
|
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -150,11 +150,8 @@ namespace dxvk {
|
||||||
HRESULT D3D11GDISurface::CreateReadbackResource() {
|
HRESULT D3D11GDISurface::CreateReadbackResource() {
|
||||||
auto tex = GetCommonTexture(m_resource);
|
auto tex = GetCommonTexture(m_resource);
|
||||||
|
|
||||||
Com<ID3D11Device> device;
|
Com<ID3D11Device> device;
|
||||||
Com<ID3D11DeviceContext> context;
|
|
||||||
|
|
||||||
m_resource->GetDevice(&device);
|
m_resource->GetDevice(&device);
|
||||||
device->GetImmediateContext(&context);
|
|
||||||
|
|
||||||
D3D11_RESOURCE_DIMENSION dim = { };
|
D3D11_RESOURCE_DIMENSION dim = { };
|
||||||
m_resource->GetType(&dim);
|
m_resource->GetType(&dim);
|
||||||
|
|
|
@ -49,6 +49,8 @@ namespace dxvk {
|
||||||
InitHostVisibleTexture(pTexture, pInitialData);
|
InitHostVisibleTexture(pTexture, pInitialData);
|
||||||
else
|
else
|
||||||
InitDeviceLocalTexture(pTexture, pInitialData);
|
InitDeviceLocalTexture(pTexture, pInitialData);
|
||||||
|
|
||||||
|
SyncKeyedMutex(pTexture->GetInterface());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -278,10 +280,20 @@ namespace dxvk {
|
||||||
|
|
||||||
|
|
||||||
void D3D11Initializer::FlushInternal() {
|
void D3D11Initializer::FlushInternal() {
|
||||||
m_context->flushCommandList();
|
m_context->flushCommandList(nullptr);
|
||||||
|
|
||||||
m_transferCommands = 0;
|
m_transferCommands = 0;
|
||||||
m_transferMemory = 0;
|
m_transferMemory = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void D3D11Initializer::SyncKeyedMutex(ID3D11Resource *pResource) {
|
||||||
|
Com<IDXGIKeyedMutex> keyedMutex;
|
||||||
|
if (pResource->QueryInterface(__uuidof(IDXGIKeyedMutex), reinterpret_cast<void**>(&keyedMutex)) != S_OK)
|
||||||
|
return;
|
||||||
|
|
||||||
|
keyedMutex->AcquireSync(0, 0);
|
||||||
|
keyedMutex->ReleaseSync(0);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -71,6 +71,8 @@ namespace dxvk {
|
||||||
void FlushImplicit();
|
void FlushImplicit();
|
||||||
void FlushInternal();
|
void FlushInternal();
|
||||||
|
|
||||||
|
void SyncKeyedMutex(ID3D11Resource *pResource);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
|
@ -46,8 +46,11 @@ namespace dxvk {
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::warn("D3D11InputLayout::QueryInterface: Unknown interface query");
|
if (logQueryInterfaceError(__uuidof(ID3D11InputLayout), riid)) {
|
||||||
Logger::warn(str::format(riid));
|
Logger::warn("D3D11InputLayout::QueryInterface: Unknown interface query");
|
||||||
|
Logger::warn(str::format(riid));
|
||||||
|
}
|
||||||
|
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -183,13 +183,7 @@ ID3D11VkExtContext1 : public ID3D11VkExtContext {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifndef _MSC_VER
|
||||||
struct __declspec(uuid("bb8a4fb9-3935-4762-b44b-35189a26414a")) ID3D11VkExtShader;
|
|
||||||
struct __declspec(uuid("8a6e3c42-f74c-45b7-8265-a231b677ca17")) ID3D11VkExtDevice;
|
|
||||||
struct __declspec(uuid("cfcf64ef-9586-46d0-bca4-97cf2ca61b06")) ID3D11VkExtDevice1;
|
|
||||||
struct __declspec(uuid("fd0bca13-5cb6-4c3a-987e-4750de2ca791")) ID3D11VkExtContext;
|
|
||||||
struct __declspec(uuid("874b09b2-ae0b-41d8-8476-5f3b7a0e879d")) ID3D11VkExtContext1;
|
|
||||||
#else
|
|
||||||
__CRT_UUID_DECL(ID3D11VkExtShader, 0xbb8a4fb9,0x3935,0x4762,0xb4,0x4b,0x35,0x18,0x9a,0x26,0x41,0x4a);
|
__CRT_UUID_DECL(ID3D11VkExtShader, 0xbb8a4fb9,0x3935,0x4762,0xb4,0x4b,0x35,0x18,0x9a,0x26,0x41,0x4a);
|
||||||
__CRT_UUID_DECL(ID3D11VkExtDevice, 0x8a6e3c42,0xf74c,0x45b7,0x82,0x65,0xa2,0x31,0xb6,0x77,0xca,0x17);
|
__CRT_UUID_DECL(ID3D11VkExtDevice, 0x8a6e3c42,0xf74c,0x45b7,0x82,0x65,0xa2,0x31,0xb6,0x77,0xca,0x17);
|
||||||
__CRT_UUID_DECL(ID3D11VkExtDevice1, 0xcfcf64ef,0x9586,0x46d0,0xbc,0xa4,0x97,0xcf,0x2c,0xa6,0x1b,0x06);
|
__CRT_UUID_DECL(ID3D11VkExtDevice1, 0xcfcf64ef,0x9586,0x46d0,0xbc,0xa4,0x97,0xcf,0x2c,0xa6,0x1b,0x06);
|
||||||
|
|
|
@ -75,21 +75,15 @@ namespace dxvk {
|
||||||
const VkImageSubresourceRange* pSubresources,
|
const VkImageSubresourceRange* pSubresources,
|
||||||
VkImageLayout OldLayout,
|
VkImageLayout OldLayout,
|
||||||
VkImageLayout NewLayout) {
|
VkImageLayout NewLayout) {
|
||||||
Com<ID3D11DeviceContext> deviceContext = nullptr;
|
auto immediateContext = m_device->GetContext();
|
||||||
m_device->GetImmediateContext(&deviceContext);
|
|
||||||
|
|
||||||
auto immediateContext = static_cast<D3D11ImmediateContext*>(deviceContext.ptr());
|
|
||||||
|
|
||||||
immediateContext->TransitionSurfaceLayout(
|
immediateContext->TransitionSurfaceLayout(
|
||||||
pSurface, pSubresources, OldLayout, NewLayout);
|
pSurface, pSubresources, OldLayout, NewLayout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void STDMETHODCALLTYPE D3D11VkInterop::FlushRenderingCommands() {
|
void STDMETHODCALLTYPE D3D11VkInterop::FlushRenderingCommands() {
|
||||||
Com<ID3D11DeviceContext> deviceContext = nullptr;
|
auto immediateContext = m_device->GetContext();
|
||||||
m_device->GetImmediateContext(&deviceContext);
|
|
||||||
|
|
||||||
auto immediateContext = static_cast<D3D11ImmediateContext*>(deviceContext.ptr());
|
|
||||||
immediateContext->Flush();
|
immediateContext->Flush();
|
||||||
immediateContext->SynchronizeCsThread(DxvkCsThread::SynchronizeAll);
|
immediateContext->SynchronizeCsThread(DxvkCsThread::SynchronizeAll);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ namespace dxvk {
|
||||||
extern "C" {
|
extern "C" {
|
||||||
using namespace dxvk;
|
using namespace dxvk;
|
||||||
|
|
||||||
DLLEXPORT HRESULT __stdcall D3D11CoreCreateDevice(
|
HRESULT D3D11InternalCreateDevice(
|
||||||
IDXGIFactory* pFactory,
|
IDXGIFactory* pFactory,
|
||||||
IDXGIAdapter* pAdapter,
|
IDXGIAdapter* pAdapter,
|
||||||
UINT Flags,
|
UINT Flags,
|
||||||
|
@ -34,11 +34,11 @@ extern "C" {
|
||||||
dxvkAdapter = dxgiVkAdapter->GetDXVKAdapter();
|
dxvkAdapter = dxgiVkAdapter->GetDXVKAdapter();
|
||||||
dxvkInstance = dxgiVkAdapter->GetDXVKInstance();
|
dxvkInstance = dxgiVkAdapter->GetDXVKInstance();
|
||||||
} else {
|
} else {
|
||||||
Logger::warn("D3D11CoreCreateDevice: Adapter is not a DXVK adapter");
|
Logger::warn("D3D11InternalCreateDevice: Adapter is not a DXVK adapter");
|
||||||
DXGI_ADAPTER_DESC desc;
|
DXGI_ADAPTER_DESC desc;
|
||||||
pAdapter->GetDesc(&desc);
|
pAdapter->GetDesc(&desc);
|
||||||
|
|
||||||
dxvkInstance = new DxvkInstance();
|
dxvkInstance = new DxvkInstance(0);
|
||||||
dxvkAdapter = dxvkInstance->findAdapterByLuid(&desc.AdapterLuid);
|
dxvkAdapter = dxvkInstance->findAdapterByLuid(&desc.AdapterLuid);
|
||||||
|
|
||||||
if (dxvkAdapter == nullptr)
|
if (dxvkAdapter == nullptr)
|
||||||
|
@ -70,7 +70,7 @@ extern "C" {
|
||||||
D3D_FEATURE_LEVEL minFeatureLevel = D3D_FEATURE_LEVEL();
|
D3D_FEATURE_LEVEL minFeatureLevel = D3D_FEATURE_LEVEL();
|
||||||
D3D_FEATURE_LEVEL devFeatureLevel = D3D_FEATURE_LEVEL();
|
D3D_FEATURE_LEVEL devFeatureLevel = D3D_FEATURE_LEVEL();
|
||||||
|
|
||||||
Logger::info(str::format("D3D11CoreCreateDevice: Maximum supported feature level: ", maxFeatureLevel));
|
Logger::info(str::format("D3D11InternalCreateDevice: Maximum supported feature level: ", maxFeatureLevel));
|
||||||
|
|
||||||
for (uint32_t flId = 0 ; flId < FeatureLevels; flId++) {
|
for (uint32_t flId = 0 ; flId < FeatureLevels; flId++) {
|
||||||
minFeatureLevel = pFeatureLevels[flId];
|
minFeatureLevel = pFeatureLevels[flId];
|
||||||
|
@ -82,21 +82,26 @@ extern "C" {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!devFeatureLevel) {
|
if (!devFeatureLevel) {
|
||||||
Logger::err(str::format("D3D11CoreCreateDevice: Minimum required feature level ", minFeatureLevel, " not supported"));
|
Logger::err(str::format("D3D11InternalCreateDevice: Minimum required feature level ", minFeatureLevel, " not supported"));
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Logger::info(str::format("D3D11CoreCreateDevice: Using feature level ", devFeatureLevel));
|
Logger::info(str::format("D3D11InternalCreateDevice: Using feature level ", devFeatureLevel));
|
||||||
|
|
||||||
|
DxvkDeviceFeatures deviceFeatures = D3D11Device::GetDeviceFeatures(dxvkAdapter);
|
||||||
|
Rc<DxvkDevice> dxvkDevice = dxvkAdapter->createDevice(dxvkInstance, deviceFeatures);
|
||||||
|
|
||||||
Com<D3D11DXGIDevice> device = new D3D11DXGIDevice(
|
Com<D3D11DXGIDevice> device = new D3D11DXGIDevice(
|
||||||
pAdapter, dxvkInstance, dxvkAdapter, devFeatureLevel, Flags);
|
pAdapter, nullptr, nullptr,
|
||||||
|
dxvkInstance, dxvkAdapter, dxvkDevice,
|
||||||
|
devFeatureLevel, Flags);
|
||||||
|
|
||||||
return device->QueryInterface(
|
return device->QueryInterface(
|
||||||
__uuidof(ID3D11Device),
|
__uuidof(ID3D11Device),
|
||||||
reinterpret_cast<void**>(ppDevice));
|
reinterpret_cast<void**>(ppDevice));
|
||||||
} catch (const DxvkError& e) {
|
} catch (const DxvkError& e) {
|
||||||
Logger::err("D3D11CoreCreateDevice: Failed to create D3D11 device");
|
Logger::err("D3D11InternalCreateDevice: Failed to create D3D11 device");
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -168,7 +173,7 @@ extern "C" {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the actual device
|
// Create the actual device
|
||||||
hr = D3D11CoreCreateDevice(
|
hr = D3D11InternalCreateDevice(
|
||||||
dxgiFactory.ptr(), dxgiAdapter.ptr(),
|
dxgiFactory.ptr(), dxgiAdapter.ptr(),
|
||||||
Flags, pFeatureLevels, FeatureLevels,
|
Flags, pFeatureLevels, FeatureLevels,
|
||||||
&device);
|
&device);
|
||||||
|
@ -207,6 +212,25 @@ extern "C" {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DLLEXPORT HRESULT __stdcall D3D11CoreCreateDevice(
|
||||||
|
IDXGIFactory* pFactory,
|
||||||
|
IDXGIAdapter* pAdapter,
|
||||||
|
D3D_DRIVER_TYPE DriverType,
|
||||||
|
HMODULE Software,
|
||||||
|
UINT Flags,
|
||||||
|
const D3D_FEATURE_LEVEL* pFeatureLevels,
|
||||||
|
UINT FeatureLevels,
|
||||||
|
UINT SDKVersion,
|
||||||
|
ID3D11Device** ppDevice,
|
||||||
|
D3D_FEATURE_LEVEL* pFeatureLevel) {
|
||||||
|
return D3D11InternalCreateDeviceAndSwapChain(
|
||||||
|
pAdapter, DriverType, Software, Flags,
|
||||||
|
pFeatureLevels, FeatureLevels, SDKVersion,
|
||||||
|
nullptr, nullptr,
|
||||||
|
ppDevice, pFeatureLevel, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
DLLEXPORT HRESULT __stdcall D3D11CreateDevice(
|
DLLEXPORT HRESULT __stdcall D3D11CreateDevice(
|
||||||
IDXGIAdapter* pAdapter,
|
IDXGIAdapter* pAdapter,
|
||||||
D3D_DRIVER_TYPE DriverType,
|
D3D_DRIVER_TYPE DriverType,
|
||||||
|
@ -258,12 +282,169 @@ extern "C" {
|
||||||
ID3D11Device** ppDevice,
|
ID3D11Device** ppDevice,
|
||||||
ID3D11DeviceContext** ppImmediateContext,
|
ID3D11DeviceContext** ppImmediateContext,
|
||||||
D3D_FEATURE_LEVEL* pChosenFeatureLevel) {
|
D3D_FEATURE_LEVEL* pChosenFeatureLevel) {
|
||||||
static bool s_errorShown = false;
|
InitReturnPtr(ppDevice);
|
||||||
|
InitReturnPtr(ppImmediateContext);
|
||||||
|
|
||||||
if (!std::exchange(s_errorShown, true))
|
if (pChosenFeatureLevel)
|
||||||
Logger::err("D3D11On12CreateDevice: Not implemented");
|
*pChosenFeatureLevel = D3D_FEATURE_LEVEL(0);
|
||||||
|
|
||||||
return E_NOTIMPL;
|
if (!pDevice)
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
// Figure out D3D12 objects
|
||||||
|
Com<ID3D12Device> d3d12Device;
|
||||||
|
Com<ID3D12CommandQueue> d3d12Queue;
|
||||||
|
|
||||||
|
if (FAILED(pDevice->QueryInterface(__uuidof(ID3D12Device), reinterpret_cast<void**>(&d3d12Device)))) {
|
||||||
|
Logger::err("D3D11On12CreateDevice: Device is not a valid D3D12 device");
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NodeMask & (NodeMask - 1)) {
|
||||||
|
Logger::err("D3D11On12CreateDevice: Invalid node mask");
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!NumQueues || !ppCommandQueues || !ppCommandQueues[0]) {
|
||||||
|
Logger::err("D3D11On12CreateDevice: No command queue specified");
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NumQueues > 1) {
|
||||||
|
// Not sure what to do with more than one graphics queue
|
||||||
|
Logger::warn("D3D11On12CreateDevice: Only one queue supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FAILED(ppCommandQueues[0]->QueryInterface(__uuidof(ID3D12CommandQueue), reinterpret_cast<void**>(&d3d12Queue)))) {
|
||||||
|
Logger::err("D3D11On12CreateDevice: Queue is not a valid D3D12 command queue");
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine feature level for the D3D11 device
|
||||||
|
std::array<D3D_FEATURE_LEVEL, 4> defaultFeatureLevels = {{
|
||||||
|
D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_11_1,
|
||||||
|
D3D_FEATURE_LEVEL_12_0, D3D_FEATURE_LEVEL_12_1,
|
||||||
|
}};
|
||||||
|
|
||||||
|
D3D12_FEATURE_DATA_FEATURE_LEVELS featureLevel = { };
|
||||||
|
|
||||||
|
if (!FeatureLevels || !pFeatureLevels) {
|
||||||
|
featureLevel.NumFeatureLevels = defaultFeatureLevels.size();
|
||||||
|
featureLevel.pFeatureLevelsRequested = defaultFeatureLevels.data();
|
||||||
|
} else {
|
||||||
|
featureLevel.NumFeatureLevels = FeatureLevels;
|
||||||
|
featureLevel.pFeatureLevelsRequested = pFeatureLevels;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT hr = d3d12Device->CheckFeatureSupport(D3D12_FEATURE_FEATURE_LEVELS, &featureLevel, sizeof(featureLevel));
|
||||||
|
|
||||||
|
if (FAILED(hr) || !featureLevel.MaxSupportedFeatureLevel) {
|
||||||
|
Logger::err(str::format("D3D11On12CreateDevice: Minimum required feature level not supported"));
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger::info(str::format("D3D11On12CreateDevice: Chosen feature level: ", featureLevel.MaxSupportedFeatureLevel));
|
||||||
|
|
||||||
|
Com<ID3D12DXVKInteropDevice> interopDevice;
|
||||||
|
|
||||||
|
if (FAILED(d3d12Device->QueryInterface(__uuidof(ID3D12DXVKInteropDevice), reinterpret_cast<void**>(&interopDevice)))) {
|
||||||
|
Logger::err("D3D11On12CreateDevice: Device not a vkd3d-proton device.");
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
Com<IDXGIAdapter> dxgiAdapter;
|
||||||
|
|
||||||
|
if (FAILED(interopDevice->GetDXGIAdapter(IID_PPV_ARGS(&dxgiAdapter)))) {
|
||||||
|
Logger::err("D3D11On12CreateDevice: Failed to query DXGI adapter.");
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Initialize DXVK instance
|
||||||
|
DxvkInstanceImportInfo instanceInfo = { };
|
||||||
|
DxvkDeviceImportInfo deviceInfo = { };
|
||||||
|
VkPhysicalDevice vulkanAdapter = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
interopDevice->GetVulkanHandles(&instanceInfo.instance, &vulkanAdapter, &deviceInfo.device);
|
||||||
|
|
||||||
|
uint32_t instanceExtensionCount = 0;
|
||||||
|
interopDevice->GetInstanceExtensions(&instanceExtensionCount, nullptr);
|
||||||
|
|
||||||
|
std::vector<const char*> instanceExtensions(instanceExtensionCount);
|
||||||
|
interopDevice->GetInstanceExtensions(&instanceExtensionCount, instanceExtensions.data());
|
||||||
|
|
||||||
|
instanceInfo.extensionCount = instanceExtensions.size();
|
||||||
|
instanceInfo.extensionNames = instanceExtensions.data();
|
||||||
|
|
||||||
|
Rc<DxvkInstance> dxvkInstance = new DxvkInstance(instanceInfo, 0);
|
||||||
|
|
||||||
|
// Find adapter by physical device handle
|
||||||
|
Rc<DxvkAdapter> dxvkAdapter;
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < dxvkInstance->adapterCount(); i++) {
|
||||||
|
Rc<DxvkAdapter> curr = dxvkInstance->enumAdapters(i);
|
||||||
|
|
||||||
|
if (curr->handle() == vulkanAdapter)
|
||||||
|
dxvkAdapter = std::move(curr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dxvkAdapter == nullptr) {
|
||||||
|
Logger::err("D3D11On12CreateDevice: No matching adapter found");
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
interopDevice->GetVulkanQueueInfo(d3d12Queue.ptr(), &deviceInfo.queue, &deviceInfo.queueFamily);
|
||||||
|
interopDevice->GetDeviceFeatures(&deviceInfo.features);
|
||||||
|
|
||||||
|
uint32_t deviceExtensionCount = 0;
|
||||||
|
interopDevice->GetDeviceExtensions(&deviceExtensionCount, nullptr);
|
||||||
|
|
||||||
|
std::vector<const char*> deviceExtensions(deviceExtensionCount);
|
||||||
|
interopDevice->GetDeviceExtensions(&deviceExtensionCount, deviceExtensions.data());
|
||||||
|
|
||||||
|
deviceInfo.extensionCount = deviceExtensions.size();
|
||||||
|
deviceInfo.extensionNames = deviceExtensions.data();
|
||||||
|
|
||||||
|
deviceInfo.queueCallback = [
|
||||||
|
cDevice = interopDevice,
|
||||||
|
cQueue = d3d12Queue
|
||||||
|
] (bool doLock) {
|
||||||
|
HRESULT hr = doLock
|
||||||
|
? cDevice->LockCommandQueue(cQueue.ptr())
|
||||||
|
: cDevice->UnlockCommandQueue(cQueue.ptr());
|
||||||
|
|
||||||
|
if (FAILED(hr))
|
||||||
|
Logger::err(str::format("Failed to lock vkd3d-proton device queue: ", hr));
|
||||||
|
};
|
||||||
|
|
||||||
|
Rc<DxvkDevice> dxvkDevice = dxvkAdapter->importDevice(dxvkInstance, deviceInfo);
|
||||||
|
|
||||||
|
// Create and return the actual D3D11 device
|
||||||
|
Com<D3D11DXGIDevice> device = new D3D11DXGIDevice(
|
||||||
|
dxgiAdapter.ptr(), d3d12Device.ptr(), d3d12Queue.ptr(),
|
||||||
|
dxvkInstance, dxvkAdapter, dxvkDevice,
|
||||||
|
featureLevel.MaxSupportedFeatureLevel, Flags);
|
||||||
|
|
||||||
|
Com<ID3D11Device> d3d11Device;
|
||||||
|
device->QueryInterface(__uuidof(ID3D11Device), reinterpret_cast<void**>(&d3d11Device));
|
||||||
|
|
||||||
|
if (ppDevice)
|
||||||
|
*ppDevice = d3d11Device.ref();
|
||||||
|
|
||||||
|
if (ppImmediateContext)
|
||||||
|
d3d11Device->GetImmediateContext(ppImmediateContext);
|
||||||
|
|
||||||
|
if (pChosenFeatureLevel)
|
||||||
|
*pChosenFeatureLevel = d3d11Device->GetFeatureLevel();
|
||||||
|
|
||||||
|
if (!ppDevice && !ppImmediateContext)
|
||||||
|
return S_FALSE;
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
} catch (const DxvkError& e) {
|
||||||
|
Logger::err("D3D11On12CreateDevice: Failed to create D3D11 device");
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,150 @@
|
||||||
|
#include "d3d11_context_imm.h"
|
||||||
|
#include "d3d11_device.h"
|
||||||
|
#include "d3d11_on_12.h"
|
||||||
|
|
||||||
|
namespace dxvk {
|
||||||
|
|
||||||
|
D3D11on12Device::D3D11on12Device(
|
||||||
|
D3D11DXGIDevice* pContainer,
|
||||||
|
D3D11Device* pDevice,
|
||||||
|
ID3D12Device* pD3D12Device,
|
||||||
|
ID3D12CommandQueue* pD3D12Queue)
|
||||||
|
: m_container (pContainer),
|
||||||
|
m_device (pDevice),
|
||||||
|
m_d3d12Device (pD3D12Device),
|
||||||
|
m_d3d12Queue (pD3D12Queue) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
D3D11on12Device::~D3D11on12Device() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ULONG STDMETHODCALLTYPE D3D11on12Device::AddRef() {
|
||||||
|
return m_container->AddRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ULONG STDMETHODCALLTYPE D3D11on12Device::Release() {
|
||||||
|
return m_container->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HRESULT STDMETHODCALLTYPE D3D11on12Device::QueryInterface(
|
||||||
|
REFIID riid,
|
||||||
|
void** ppvObject) {
|
||||||
|
return m_container->QueryInterface(riid, ppvObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HRESULT STDMETHODCALLTYPE D3D11on12Device::CreateWrappedResource(
|
||||||
|
IUnknown* pResource12,
|
||||||
|
const D3D11_RESOURCE_FLAGS* pResourceFlags,
|
||||||
|
D3D12_RESOURCE_STATES InputState,
|
||||||
|
D3D12_RESOURCE_STATES OutputState,
|
||||||
|
REFIID riid,
|
||||||
|
void** ppResource11) {
|
||||||
|
Com<ID3D12DXVKInteropDevice> interopDevice;
|
||||||
|
m_d3d12Device->QueryInterface(__uuidof(ID3D12DXVKInteropDevice), reinterpret_cast<void**>(&interopDevice));
|
||||||
|
|
||||||
|
D3D11_ON_12_RESOURCE_INFO info = { };
|
||||||
|
info.InputState = InputState;
|
||||||
|
info.OutputState = OutputState;
|
||||||
|
info.IsWrappedResource = TRUE;
|
||||||
|
|
||||||
|
// 11on12 technically allows importing D3D12 heaps as tile pools,
|
||||||
|
// but we don't support importing sparse resources at this time.
|
||||||
|
if (FAILED(pResource12->QueryInterface(__uuidof(ID3D12Resource), reinterpret_cast<void**>(&info.Resource)))) {
|
||||||
|
Logger::err("D3D11on12Device::CreateWrappedResource: Resource not a valid D3D12 resource");
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Query Vulkan resource handle and buffer offset as necessary
|
||||||
|
if (FAILED(interopDevice->GetVulkanResourceInfo(info.Resource.ptr(), &info.VulkanHandle, &info.VulkanOffset))) {
|
||||||
|
Logger::err("D3D11on12Device::CreateWrappedResource: Failed to retrieve Vulkan resource info");
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
Com<ID3D11Resource> resource;
|
||||||
|
D3D12_RESOURCE_DESC desc = info.Resource->GetDesc();
|
||||||
|
|
||||||
|
if (desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) {
|
||||||
|
D3D11_BUFFER_DESC bufferDesc;
|
||||||
|
|
||||||
|
if (FAILED(D3D11Buffer::GetDescFromD3D12(info.Resource.ptr(), pResourceFlags, &bufferDesc)))
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
resource = new D3D11Buffer(m_device, &bufferDesc, &info);
|
||||||
|
} else {
|
||||||
|
D3D11_COMMON_TEXTURE_DESC textureDesc;
|
||||||
|
|
||||||
|
if (FAILED(D3D11CommonTexture::GetDescFromD3D12(info.Resource.ptr(), pResourceFlags, &textureDesc)))
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
switch (desc.Dimension) {
|
||||||
|
case D3D12_RESOURCE_DIMENSION_TEXTURE1D:
|
||||||
|
resource = new D3D11Texture1D(m_device, &textureDesc, &info);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case D3D12_RESOURCE_DIMENSION_TEXTURE2D:
|
||||||
|
resource = new D3D11Texture2D(m_device, &textureDesc, &info, nullptr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case D3D12_RESOURCE_DIMENSION_TEXTURE3D:
|
||||||
|
resource = new D3D11Texture3D(m_device, &textureDesc, &info);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Logger::err("D3D11on12Device::CreateWrappedResource: Unhandled resource dimension");
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return resource->QueryInterface(riid, ppResource11);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void STDMETHODCALLTYPE D3D11on12Device::ReleaseWrappedResources(
|
||||||
|
ID3D11Resource* const* ppResources,
|
||||||
|
UINT ResourceCount) {
|
||||||
|
Com<ID3D12DXVKInteropDevice> interopDevice;
|
||||||
|
m_d3d12Device->QueryInterface(__uuidof(ID3D12DXVKInteropDevice), reinterpret_cast<void**>(&interopDevice));
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < ResourceCount; i++) {
|
||||||
|
D3D11_ON_12_RESOURCE_INFO info;
|
||||||
|
|
||||||
|
if (FAILED(GetResource11on12Info(ppResources[i], &info)) || !info.IsWrappedResource) {
|
||||||
|
Logger::warn("D3D11on12Device::ReleaseWrappedResources: Resource not a wrapped resource, skipping");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkImageLayout layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
|
interopDevice->GetVulkanImageLayout(info.Resource.ptr(), info.OutputState, &layout);
|
||||||
|
m_device->GetContext()->Release11on12Resource(ppResources[i], layout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void STDMETHODCALLTYPE D3D11on12Device::AcquireWrappedResources(
|
||||||
|
ID3D11Resource* const* ppResources,
|
||||||
|
UINT ResourceCount) {
|
||||||
|
Com<ID3D12DXVKInteropDevice> interopDevice;
|
||||||
|
m_d3d12Device->QueryInterface(__uuidof(ID3D12DXVKInteropDevice), reinterpret_cast<void**>(&interopDevice));
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < ResourceCount; i++) {
|
||||||
|
D3D11_ON_12_RESOURCE_INFO info;
|
||||||
|
|
||||||
|
if (FAILED(GetResource11on12Info(ppResources[i], &info)) || !info.IsWrappedResource) {
|
||||||
|
Logger::warn("D3D11on12Device::AcquireWrappedResources: Resource not a wrapped resource, skipping");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkImageLayout layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
|
interopDevice->GetVulkanImageLayout(info.Resource.ptr(), info.InputState, &layout);
|
||||||
|
m_device->GetContext()->Acquire11on12Resource(ppResources[i], layout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "d3d11_on_12_interfaces.h"
|
||||||
|
|
||||||
|
#include "../util/log/log.h"
|
||||||
|
|
||||||
|
namespace dxvk {
|
||||||
|
|
||||||
|
class D3D11Device;
|
||||||
|
class D3D11DXGIDevice;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Resource info for 11on12 resources
|
||||||
|
*/
|
||||||
|
struct D3D11_ON_12_RESOURCE_INFO {
|
||||||
|
Com<ID3D12Resource> Resource;
|
||||||
|
UINT64 VulkanHandle = 0;
|
||||||
|
UINT64 VulkanOffset = 0;
|
||||||
|
BOOL IsWrappedResource = FALSE;
|
||||||
|
D3D12_RESOURCE_STATES InputState = D3D12_RESOURCE_STATE_COMMON;
|
||||||
|
D3D12_RESOURCE_STATES OutputState = D3D12_RESOURCE_STATE_COMMON;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class D3D11on12Device : public ID3D11On12Device {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
D3D11on12Device(
|
||||||
|
D3D11DXGIDevice* pContainer,
|
||||||
|
D3D11Device* pDevice,
|
||||||
|
ID3D12Device* pD3D12Device,
|
||||||
|
ID3D12CommandQueue* pD3D12Queue);
|
||||||
|
|
||||||
|
~D3D11on12Device();
|
||||||
|
|
||||||
|
ULONG STDMETHODCALLTYPE AddRef();
|
||||||
|
|
||||||
|
ULONG STDMETHODCALLTYPE Release();
|
||||||
|
|
||||||
|
HRESULT STDMETHODCALLTYPE QueryInterface(
|
||||||
|
REFIID riid,
|
||||||
|
void** ppvObject);
|
||||||
|
|
||||||
|
HRESULT STDMETHODCALLTYPE CreateWrappedResource(
|
||||||
|
IUnknown* pResource12,
|
||||||
|
const D3D11_RESOURCE_FLAGS* pResourceFlags,
|
||||||
|
D3D12_RESOURCE_STATES InputState,
|
||||||
|
D3D12_RESOURCE_STATES OutputState,
|
||||||
|
REFIID riid,
|
||||||
|
void** ppResource11);
|
||||||
|
|
||||||
|
void STDMETHODCALLTYPE ReleaseWrappedResources(
|
||||||
|
ID3D11Resource* const* ppResources,
|
||||||
|
UINT ResourceCount);
|
||||||
|
|
||||||
|
void STDMETHODCALLTYPE AcquireWrappedResources(
|
||||||
|
ID3D11Resource* const* ppResources,
|
||||||
|
UINT ResourceCount);
|
||||||
|
|
||||||
|
bool Is11on12Device() const {
|
||||||
|
return m_d3d12Device != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
D3D11DXGIDevice* m_container;
|
||||||
|
D3D11Device* m_device;
|
||||||
|
|
||||||
|
Com<ID3D12Device> m_d3d12Device;
|
||||||
|
Com<ID3D12CommandQueue> m_d3d12Queue;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../vulkan/vulkan_loader.h"
|
||||||
|
|
||||||
|
#include <d3d11on12.h>
|
||||||
|
|
||||||
|
MIDL_INTERFACE("39da4e09-bd1c-4198-9fae-86bbe3be41fd")
|
||||||
|
ID3D12DXVKInteropDevice : public IUnknown {
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE GetDXGIAdapter(
|
||||||
|
REFIID iid,
|
||||||
|
void** ppvObject) = 0;
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE GetInstanceExtensions(
|
||||||
|
UINT* pExtensionCount,
|
||||||
|
const char** ppExtensions) = 0;
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE GetDeviceExtensions(
|
||||||
|
UINT* pExtensionCount,
|
||||||
|
const char** ppExtensions) = 0;
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE GetDeviceFeatures(
|
||||||
|
const VkPhysicalDeviceFeatures2** ppFeatures) = 0;
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE GetVulkanHandles(
|
||||||
|
VkInstance* pVkInstance,
|
||||||
|
VkPhysicalDevice* pVkPhysicalDevice,
|
||||||
|
VkDevice* pVkDevice) = 0;
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE GetVulkanQueueInfo(
|
||||||
|
ID3D12CommandQueue* pCommandQueue,
|
||||||
|
VkQueue* pVkQueue,
|
||||||
|
UINT32* pVkQueueFamily) = 0;
|
||||||
|
|
||||||
|
virtual void STDMETHODCALLTYPE GetVulkanImageLayout(
|
||||||
|
ID3D12Resource* pResource,
|
||||||
|
D3D12_RESOURCE_STATES State,
|
||||||
|
VkImageLayout* pVkLayout) = 0;
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE GetVulkanResourceInfo(
|
||||||
|
ID3D12Resource* pResource,
|
||||||
|
UINT64* pVkHandle,
|
||||||
|
UINT64* pBufferOffset) = 0;
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE LockCommandQueue(
|
||||||
|
ID3D12CommandQueue* pCommandQueue) = 0;
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE UnlockCommandQueue(
|
||||||
|
ID3D12CommandQueue* pCommandQueue) = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef _MSC_VER
|
||||||
|
__CRT_UUID_DECL(ID3D12DXVKInteropDevice, 0x39da4e09, 0xbd1c, 0x4198, 0x9f,0xae, 0x86,0xbb,0xe3,0xbe,0x41,0xfd)
|
||||||
|
#endif
|
|
@ -12,7 +12,7 @@ namespace dxvk {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
D3D11Options::D3D11Options(const Config& config, const Rc<DxvkDevice>& device) {
|
D3D11Options::D3D11Options(const Config& config) {
|
||||||
this->dcSingleUseMode = config.getOption<bool>("d3d11.dcSingleUseMode", true);
|
this->dcSingleUseMode = config.getOption<bool>("d3d11.dcSingleUseMode", true);
|
||||||
this->zeroInitWorkgroupMemory = config.getOption<bool>("d3d11.zeroInitWorkgroupMemory", false);
|
this->zeroInitWorkgroupMemory = config.getOption<bool>("d3d11.zeroInitWorkgroupMemory", false);
|
||||||
this->forceVolatileTgsmAccess = config.getOption<bool>("d3d11.forceVolatileTgsmAccess", false);
|
this->forceVolatileTgsmAccess = config.getOption<bool>("d3d11.forceVolatileTgsmAccess", false);
|
||||||
|
@ -21,6 +21,7 @@ namespace dxvk {
|
||||||
this->maxTessFactor = config.getOption<int32_t>("d3d11.maxTessFactor", 0);
|
this->maxTessFactor = config.getOption<int32_t>("d3d11.maxTessFactor", 0);
|
||||||
this->samplerAnisotropy = config.getOption<int32_t>("d3d11.samplerAnisotropy", -1);
|
this->samplerAnisotropy = config.getOption<int32_t>("d3d11.samplerAnisotropy", -1);
|
||||||
this->samplerLodBias = config.getOption<float>("d3d11.samplerLodBias", 0.0f);
|
this->samplerLodBias = config.getOption<float>("d3d11.samplerLodBias", 0.0f);
|
||||||
|
this->clampNegativeLodBias = config.getOption<bool>("d3d11.clampNegativeLodBias", false);
|
||||||
this->invariantPosition = config.getOption<bool>("d3d11.invariantPosition", true);
|
this->invariantPosition = config.getOption<bool>("d3d11.invariantPosition", true);
|
||||||
this->floatControls = config.getOption<bool>("d3d11.floatControls", true);
|
this->floatControls = config.getOption<bool>("d3d11.floatControls", true);
|
||||||
this->forceSampleRateShading = config.getOption<bool>("d3d11.forceSampleRateShading", false);
|
this->forceSampleRateShading = config.getOption<bool>("d3d11.forceSampleRateShading", false);
|
||||||
|
@ -30,8 +31,9 @@ namespace dxvk {
|
||||||
this->numBackBuffers = config.getOption<int32_t>("dxgi.numBackBuffers", 0);
|
this->numBackBuffers = config.getOption<int32_t>("dxgi.numBackBuffers", 0);
|
||||||
this->maxFrameLatency = config.getOption<int32_t>("dxgi.maxFrameLatency", 0);
|
this->maxFrameLatency = config.getOption<int32_t>("dxgi.maxFrameLatency", 0);
|
||||||
this->maxFrameRate = config.getOption<int32_t>("dxgi.maxFrameRate", 0);
|
this->maxFrameRate = config.getOption<int32_t>("dxgi.maxFrameRate", 0);
|
||||||
this->syncInterval = config.getOption<int32_t>("dxgi.syncInterval", -1);
|
this->exposeDriverCommandLists = config.getOption<bool>("d3d11.exposeDriverCommandLists", true);
|
||||||
this->tearFree = config.getOption<Tristate>("dxgi.tearFree", Tristate::Auto);
|
this->longMad = config.getOption<bool>("d3d11.longMad", false);
|
||||||
|
this->reproducibleCommandStream = config.getOption<bool>("d3d11.reproducibleCommandStream", false);
|
||||||
|
|
||||||
// Clamp LOD bias so that people don't abuse this in unintended ways
|
// Clamp LOD bias so that people don't abuse this in unintended ways
|
||||||
this->samplerLodBias = dxvk::fclamp(this->samplerLodBias, -2.0f, 1.0f);
|
this->samplerLodBias = dxvk::fclamp(this->samplerLodBias, -2.0f, 1.0f);
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
struct D3D11Options {
|
struct D3D11Options {
|
||||||
D3D11Options(const Config& config, const Rc<DxvkDevice>& device);
|
D3D11Options(const Config& config);
|
||||||
|
|
||||||
/// Enables speed hack for mapping on deferred contexts
|
/// Enables speed hack for mapping on deferred contexts
|
||||||
///
|
///
|
||||||
|
@ -63,6 +63,9 @@ namespace dxvk {
|
||||||
/// Enforces the given LOD bias for all samplers.
|
/// Enforces the given LOD bias for all samplers.
|
||||||
float samplerLodBias;
|
float samplerLodBias;
|
||||||
|
|
||||||
|
/// Clamps negative LOD bias
|
||||||
|
bool clampNegativeLodBias;
|
||||||
|
|
||||||
/// Declare vertex positions in shaders as invariant
|
/// Declare vertex positions in shaders as invariant
|
||||||
bool invariantPosition;
|
bool invariantPosition;
|
||||||
|
|
||||||
|
@ -73,14 +76,6 @@ namespace dxvk {
|
||||||
/// Overrides DXGI_SWAP_CHAIN_DESC::BufferCount.
|
/// Overrides DXGI_SWAP_CHAIN_DESC::BufferCount.
|
||||||
int32_t numBackBuffers;
|
int32_t numBackBuffers;
|
||||||
|
|
||||||
/// Sync interval. Overrides the value
|
|
||||||
/// passed to IDXGISwapChain::Present.
|
|
||||||
int32_t syncInterval;
|
|
||||||
|
|
||||||
/// Tear-free mode if vsync is disabled
|
|
||||||
/// Tearing mode if vsync is enabled
|
|
||||||
Tristate tearFree;
|
|
||||||
|
|
||||||
/// Override maximum frame latency if the app specifies
|
/// Override maximum frame latency if the app specifies
|
||||||
/// a higher value. May help with frame timing issues.
|
/// a higher value. May help with frame timing issues.
|
||||||
int32_t maxFrameLatency;
|
int32_t maxFrameLatency;
|
||||||
|
@ -118,8 +113,21 @@ namespace dxvk {
|
||||||
/// race conditions.
|
/// race conditions.
|
||||||
bool enableContextLock;
|
bool enableContextLock;
|
||||||
|
|
||||||
|
/// Whether to expose the driver command list feature. Enabled by
|
||||||
|
/// default and generally beneficial, but some games may assume that
|
||||||
|
/// this is not supported when running on an AMD GPU.
|
||||||
|
bool exposeDriverCommandLists;
|
||||||
|
|
||||||
/// Shader dump path
|
/// Shader dump path
|
||||||
std::string shaderDumpPath;
|
std::string shaderDumpPath;
|
||||||
|
|
||||||
|
/// Should we make our Mads a FFma or do it the long way with an FMul and an FAdd?
|
||||||
|
bool longMad;
|
||||||
|
|
||||||
|
/// Ensure that for the same D3D commands the output VK commands
|
||||||
|
/// don't change between runs. Useful for comparative benchmarking,
|
||||||
|
/// can negatively affect performance.
|
||||||
|
bool reproducibleCommandStream;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
|
@ -120,8 +120,11 @@ namespace dxvk {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::warn("D3D11Query: Unknown interface query");
|
if (logQueryInterfaceError(__uuidof(ID3D11Query), riid)) {
|
||||||
Logger::warn(str::format(riid));
|
Logger::warn("D3D11Query: Unknown interface query");
|
||||||
|
Logger::warn(str::format(riid));
|
||||||
|
}
|
||||||
|
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,13 +38,22 @@ namespace dxvk {
|
||||||
m_state.conservativeMode = DecodeConservativeRasterizationMode(desc.ConservativeRaster);
|
m_state.conservativeMode = DecodeConservativeRasterizationMode(desc.ConservativeRaster);
|
||||||
m_state.sampleCount = VkSampleCountFlags(desc.ForcedSampleCount);
|
m_state.sampleCount = VkSampleCountFlags(desc.ForcedSampleCount);
|
||||||
m_state.flatShading = VK_FALSE;
|
m_state.flatShading = VK_FALSE;
|
||||||
|
m_state.lineMode = VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT;
|
||||||
|
|
||||||
m_depthBias.depthBiasConstant = float(desc.DepthBias);
|
m_depthBias.depthBiasConstant = float(desc.DepthBias);
|
||||||
m_depthBias.depthBiasSlope = desc.SlopeScaledDepthBias;
|
m_depthBias.depthBiasSlope = desc.SlopeScaledDepthBias;
|
||||||
m_depthBias.depthBiasClamp = desc.DepthBiasClamp;
|
m_depthBias.depthBiasClamp = desc.DepthBiasClamp;
|
||||||
|
|
||||||
if (desc.AntialiasedLineEnable)
|
// Set up line rasterization mode
|
||||||
Logger::err("D3D11RasterizerState: Antialiased lines not supported");
|
const auto& features = device->GetDXVKDevice()->features();
|
||||||
|
|
||||||
|
if (desc.MultisampleEnable) {
|
||||||
|
if (features.extLineRasterization.rectangularLines)
|
||||||
|
m_state.lineMode = VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT;
|
||||||
|
} else if (desc.AntialiasedLineEnable) {
|
||||||
|
if (features.extLineRasterization.smoothLines)
|
||||||
|
m_state.lineMode = VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -74,8 +83,11 @@ namespace dxvk {
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::warn("D3D11RasterizerState::QueryInterface: Unknown interface query");
|
if (logQueryInterfaceError(__uuidof(ID3D11RasterizerState), riid)) {
|
||||||
Logger::warn(str::format(riid));
|
Logger::warn("D3D11RasterizerState::QueryInterface: Unknown interface query");
|
||||||
|
Logger::warn(str::format(riid));
|
||||||
|
}
|
||||||
|
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,138 @@
|
||||||
#include "d3d11_buffer.h"
|
#include "d3d11_buffer.h"
|
||||||
#include "d3d11_texture.h"
|
#include "d3d11_texture.h"
|
||||||
#include "d3d11_resource.h"
|
#include "d3d11_resource.h"
|
||||||
|
#include "d3d11_context_imm.h"
|
||||||
|
#include "d3d11_device.h"
|
||||||
|
|
||||||
#include "../util/util_shared_res.h"
|
#include "../util/util_shared_res.h"
|
||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
|
D3D11DXGIKeyedMutex::D3D11DXGIKeyedMutex(
|
||||||
|
ID3D11Resource* pResource,
|
||||||
|
D3D11Device* pDevice)
|
||||||
|
: m_resource(pResource),
|
||||||
|
m_device(pDevice) {
|
||||||
|
|
||||||
|
m_supported = m_device->GetDXVKDevice()->features().khrWin32KeyedMutex
|
||||||
|
&& m_device->GetDXVKDevice()->vkd()->wine_vkAcquireKeyedMutex != nullptr
|
||||||
|
&& m_device->GetDXVKDevice()->vkd()->wine_vkReleaseKeyedMutex != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
D3D11DXGIKeyedMutex::~D3D11DXGIKeyedMutex() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ULONG STDMETHODCALLTYPE D3D11DXGIKeyedMutex::AddRef() {
|
||||||
|
return m_resource->AddRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ULONG STDMETHODCALLTYPE D3D11DXGIKeyedMutex::Release() {
|
||||||
|
return m_resource->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HRESULT STDMETHODCALLTYPE D3D11DXGIKeyedMutex::QueryInterface(
|
||||||
|
REFIID riid,
|
||||||
|
void** ppvObject) {
|
||||||
|
return m_resource->QueryInterface(riid, ppvObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HRESULT STDMETHODCALLTYPE D3D11DXGIKeyedMutex::GetPrivateData(
|
||||||
|
REFGUID Name,
|
||||||
|
UINT* pDataSize,
|
||||||
|
void* pData) {
|
||||||
|
return m_resource->GetPrivateData(Name, pDataSize, pData);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HRESULT STDMETHODCALLTYPE D3D11DXGIKeyedMutex::SetPrivateData(
|
||||||
|
REFGUID Name,
|
||||||
|
UINT DataSize,
|
||||||
|
const void* pData) {
|
||||||
|
return m_resource->SetPrivateData(Name, DataSize, pData);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HRESULT STDMETHODCALLTYPE D3D11DXGIKeyedMutex::SetPrivateDataInterface(
|
||||||
|
REFGUID Name,
|
||||||
|
const IUnknown* pUnknown) {
|
||||||
|
return m_resource->SetPrivateDataInterface(Name, pUnknown);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HRESULT STDMETHODCALLTYPE D3D11DXGIKeyedMutex::GetParent(
|
||||||
|
REFIID riid,
|
||||||
|
void** ppParent) {
|
||||||
|
return GetDevice(riid, ppParent);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HRESULT STDMETHODCALLTYPE D3D11DXGIKeyedMutex::GetDevice(
|
||||||
|
REFIID riid,
|
||||||
|
void** ppDevice) {
|
||||||
|
Com<ID3D11Device> device;
|
||||||
|
m_resource->GetDevice(&device);
|
||||||
|
return device->QueryInterface(riid, ppDevice);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HRESULT STDMETHODCALLTYPE D3D11DXGIKeyedMutex::AcquireSync(
|
||||||
|
UINT64 Key,
|
||||||
|
DWORD dwMilliseconds) {
|
||||||
|
if (!m_supported) {
|
||||||
|
if (!m_warned) {
|
||||||
|
m_warned = true;
|
||||||
|
Logger::err("D3D11DXGIKeyedMutex::AcquireSync: Not supported");
|
||||||
|
}
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
D3D11CommonTexture* texture = GetCommonTexture(m_resource);
|
||||||
|
Rc<DxvkDevice> dxvkDevice = m_device->GetDXVKDevice();
|
||||||
|
|
||||||
|
VkResult vr = dxvkDevice->vkd()->wine_vkAcquireKeyedMutex(dxvkDevice->handle(), texture->GetImage()->memory().memory(), Key, dwMilliseconds);
|
||||||
|
switch (vr) {
|
||||||
|
case VK_SUCCESS: return S_OK;
|
||||||
|
case VK_TIMEOUT: return WAIT_TIMEOUT;
|
||||||
|
default: return DXGI_ERROR_INVALID_CALL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT STDMETHODCALLTYPE D3D11DXGIKeyedMutex::ReleaseSync(
|
||||||
|
UINT64 Key) {
|
||||||
|
if (!m_supported)
|
||||||
|
return S_OK;
|
||||||
|
|
||||||
|
D3D11CommonTexture* texture = GetCommonTexture(m_resource);
|
||||||
|
Rc<DxvkDevice> dxvkDevice = m_device->GetDXVKDevice();
|
||||||
|
|
||||||
|
{
|
||||||
|
D3D11ImmediateContext* context = m_device->GetContext();
|
||||||
|
D3D10Multithread& multithread = context->GetMultithread();
|
||||||
|
static bool s_errorShown = false;
|
||||||
|
|
||||||
|
if (!multithread.GetMultithreadProtected() && !std::exchange(s_errorShown, true))
|
||||||
|
Logger::warn("D3D11DXGIKeyedMutex::ReleaseSync: Called without context locking enabled.");
|
||||||
|
|
||||||
|
D3D10DeviceLock lock = context->LockContext();
|
||||||
|
context->WaitForResource(texture->GetImage(), DxvkCsThread::SynchronizeAll, D3D11_MAP_READ_WRITE, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dxvkDevice->vkd()->wine_vkReleaseKeyedMutex(dxvkDevice->handle(), texture->GetImage()->memory().memory(), Key) == VK_SUCCESS
|
||||||
|
? S_OK
|
||||||
|
: DXGI_ERROR_INVALID_CALL;
|
||||||
|
}
|
||||||
|
|
||||||
D3D11DXGIResource::D3D11DXGIResource(
|
D3D11DXGIResource::D3D11DXGIResource(
|
||||||
ID3D11Resource* pResource)
|
ID3D11Resource* pResource,
|
||||||
: m_resource(pResource) {
|
D3D11Device* pDevice)
|
||||||
|
: m_resource(pResource),
|
||||||
|
m_keyedMutex(pResource, pDevice) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,9 +208,15 @@ namespace dxvk {
|
||||||
HRESULT STDMETHODCALLTYPE D3D11DXGIResource::GetSharedHandle(
|
HRESULT STDMETHODCALLTYPE D3D11DXGIResource::GetSharedHandle(
|
||||||
HANDLE* pSharedHandle) {
|
HANDLE* pSharedHandle) {
|
||||||
auto texture = GetCommonTexture(m_resource);
|
auto texture = GetCommonTexture(m_resource);
|
||||||
if (texture == nullptr || pSharedHandle == nullptr || !(texture->Desc()->MiscFlags & D3D11_RESOURCE_MISC_SHARED))
|
if (texture == nullptr || pSharedHandle == nullptr ||
|
||||||
|
(texture->Desc()->MiscFlags & D3D11_RESOURCE_MISC_SHARED_NTHANDLE))
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
if (!(texture->Desc()->MiscFlags & (D3D11_RESOURCE_MISC_SHARED | D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX))) {
|
||||||
|
*pSharedHandle = NULL;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
HANDLE kmtHandle = texture->GetImage()->sharedHandle();
|
HANDLE kmtHandle = texture->GetImage()->sharedHandle();
|
||||||
|
|
||||||
if (kmtHandle == INVALID_HANDLE_VALUE)
|
if (kmtHandle == INVALID_HANDLE_VALUE)
|
||||||
|
@ -143,8 +273,9 @@ namespace dxvk {
|
||||||
LPCWSTR lpName,
|
LPCWSTR lpName,
|
||||||
HANDLE* pHandle) {
|
HANDLE* pHandle) {
|
||||||
auto texture = GetCommonTexture(m_resource);
|
auto texture = GetCommonTexture(m_resource);
|
||||||
|
if (pHandle) *pHandle = nullptr;
|
||||||
if (texture == nullptr || pHandle == nullptr ||
|
if (texture == nullptr || pHandle == nullptr ||
|
||||||
!(texture->Desc()->MiscFlags & (D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX | D3D11_RESOURCE_MISC_SHARED_NTHANDLE)))
|
!(texture->Desc()->MiscFlags & D3D11_RESOURCE_MISC_SHARED_NTHANDLE))
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
|
|
||||||
if (lpName)
|
if (lpName)
|
||||||
|
@ -155,9 +286,6 @@ namespace dxvk {
|
||||||
if (handle == INVALID_HANDLE_VALUE)
|
if (handle == INVALID_HANDLE_VALUE)
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
|
|
||||||
if (texture->Desc()->MiscFlags & D3D11_RESOURCE_MISC_SHARED)
|
|
||||||
handle = openKmtHandle( handle );
|
|
||||||
|
|
||||||
*pHandle = handle;
|
*pHandle = handle;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
@ -172,6 +300,36 @@ namespace dxvk {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HRESULT D3D11DXGIResource::GetKeyedMutex(
|
||||||
|
void **ppvObject) {
|
||||||
|
auto texture = GetCommonTexture(m_resource);
|
||||||
|
if (texture == nullptr || !(texture->Desc()->MiscFlags & D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX))
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
*ppvObject = ref(&m_keyedMutex);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HRESULT GetResource11on12Info(
|
||||||
|
ID3D11Resource* pResource,
|
||||||
|
D3D11_ON_12_RESOURCE_INFO* p11on12Info) {
|
||||||
|
auto buffer = GetCommonBuffer (pResource);
|
||||||
|
auto texture = GetCommonTexture(pResource);
|
||||||
|
|
||||||
|
if (buffer != nullptr)
|
||||||
|
*p11on12Info = buffer->Get11on12Info();
|
||||||
|
else if (texture != nullptr)
|
||||||
|
*p11on12Info = texture->Get11on12Info();
|
||||||
|
else
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
if (p11on12Info->Resource == nullptr)
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
HRESULT GetCommonResourceDesc(
|
HRESULT GetCommonResourceDesc(
|
||||||
ID3D11Resource* pResource,
|
ID3D11Resource* pResource,
|
||||||
D3D11_COMMON_RESOURCE_DESC* pDesc) {
|
D3D11_COMMON_RESOURCE_DESC* pDesc) {
|
||||||
|
|
|
@ -22,6 +22,65 @@ namespace dxvk {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief IDXGIKeyedMutex implementation
|
||||||
|
*/
|
||||||
|
class D3D11DXGIKeyedMutex : public IDXGIKeyedMutex {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
D3D11DXGIKeyedMutex(
|
||||||
|
ID3D11Resource* pResource,
|
||||||
|
D3D11Device* pDevice);
|
||||||
|
|
||||||
|
~D3D11DXGIKeyedMutex();
|
||||||
|
|
||||||
|
ULONG STDMETHODCALLTYPE AddRef();
|
||||||
|
|
||||||
|
ULONG STDMETHODCALLTYPE Release();
|
||||||
|
|
||||||
|
HRESULT STDMETHODCALLTYPE QueryInterface(
|
||||||
|
REFIID riid,
|
||||||
|
void** ppvObject);
|
||||||
|
|
||||||
|
HRESULT STDMETHODCALLTYPE GetPrivateData(
|
||||||
|
REFGUID Name,
|
||||||
|
UINT* pDataSize,
|
||||||
|
void* pData);
|
||||||
|
|
||||||
|
HRESULT STDMETHODCALLTYPE SetPrivateData(
|
||||||
|
REFGUID Name,
|
||||||
|
UINT DataSize,
|
||||||
|
const void* pData);
|
||||||
|
|
||||||
|
HRESULT STDMETHODCALLTYPE SetPrivateDataInterface(
|
||||||
|
REFGUID Name,
|
||||||
|
const IUnknown* pUnknown);
|
||||||
|
|
||||||
|
HRESULT STDMETHODCALLTYPE GetParent(
|
||||||
|
REFIID riid,
|
||||||
|
void** ppParent);
|
||||||
|
|
||||||
|
HRESULT STDMETHODCALLTYPE GetDevice(
|
||||||
|
REFIID riid,
|
||||||
|
void** ppDevice);
|
||||||
|
|
||||||
|
HRESULT STDMETHODCALLTYPE AcquireSync(
|
||||||
|
UINT64 Key,
|
||||||
|
DWORD dwMilliseconds);
|
||||||
|
|
||||||
|
HRESULT STDMETHODCALLTYPE ReleaseSync(
|
||||||
|
UINT64 Key);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
ID3D11Resource* m_resource;
|
||||||
|
D3D11Device* m_device;
|
||||||
|
bool m_warned = false;
|
||||||
|
bool m_supported = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief IDXGIResource implementation for D3D11 resources
|
* \brief IDXGIResource implementation for D3D11 resources
|
||||||
*/
|
*/
|
||||||
|
@ -30,7 +89,8 @@ namespace dxvk {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
D3D11DXGIResource(
|
D3D11DXGIResource(
|
||||||
ID3D11Resource* pResource);
|
ID3D11Resource* pResource,
|
||||||
|
D3D11Device* pDevice);
|
||||||
|
|
||||||
~D3D11DXGIResource();
|
~D3D11DXGIResource();
|
||||||
|
|
||||||
|
@ -86,13 +146,27 @@ namespace dxvk {
|
||||||
UINT index,
|
UINT index,
|
||||||
IDXGISurface2** ppSurface);
|
IDXGISurface2** ppSurface);
|
||||||
|
|
||||||
|
HRESULT GetKeyedMutex(void **ppvObject);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
ID3D11Resource* m_resource;
|
ID3D11Resource* m_resource;
|
||||||
|
D3D11DXGIKeyedMutex m_keyedMutex;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Queries D3D11on12 resource info
|
||||||
|
*
|
||||||
|
* \param [in] pResource The resource to query
|
||||||
|
* \param [out] p11on12Info 11on12 info
|
||||||
|
* \returns \c S_OK on success, or \c E_INVALIDARG
|
||||||
|
*/
|
||||||
|
HRESULT GetResource11on12Info(
|
||||||
|
ID3D11Resource* pResource,
|
||||||
|
D3D11_ON_12_RESOURCE_INFO* p11on12Info);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Queries common resource description
|
* \brief Queries common resource description
|
||||||
*
|
*
|
||||||
|
@ -261,4 +335,4 @@ namespace dxvk {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,9 +47,13 @@ namespace dxvk {
|
||||||
if (desc.MaxAnisotropy > 16) info.maxAnisotropy = 16.0f;
|
if (desc.MaxAnisotropy > 16) info.maxAnisotropy = 16.0f;
|
||||||
|
|
||||||
// Enforce LOD bias specified in the device options
|
// Enforce LOD bias specified in the device options
|
||||||
if (info.minFilter == VK_FILTER_LINEAR && info.magFilter == VK_FILTER_LINEAR)
|
if (info.minFilter == VK_FILTER_LINEAR && info.magFilter == VK_FILTER_LINEAR) {
|
||||||
info.mipmapLodBias += device->GetOptions()->samplerLodBias;
|
info.mipmapLodBias += device->GetOptions()->samplerLodBias;
|
||||||
|
|
||||||
|
if (device->GetOptions()->clampNegativeLodBias)
|
||||||
|
info.mipmapLodBias = std::max(info.mipmapLodBias, 0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
// Enforce anisotropy specified in the device options
|
// Enforce anisotropy specified in the device options
|
||||||
int32_t samplerAnisotropyOption = device->GetOptions()->samplerAnisotropy;
|
int32_t samplerAnisotropyOption = device->GetOptions()->samplerAnisotropy;
|
||||||
|
|
||||||
|
@ -86,8 +90,11 @@ namespace dxvk {
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::warn("D3D11SamplerState::QueryInterface: Unknown interface query");
|
if (logQueryInterfaceError(__uuidof(ID3D11SamplerState), riid)) {
|
||||||
Logger::warn(str::format(riid));
|
Logger::warn("D3D11SamplerState::QueryInterface: Unknown interface query");
|
||||||
|
Logger::warn(str::format(riid));
|
||||||
|
}
|
||||||
|
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -134,7 +134,11 @@ namespace dxvk {
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::warn("D3D11Shader::QueryInterface: Unknown interface query");
|
if (logQueryInterfaceError(__uuidof(D3D11Interface), riid)) {
|
||||||
|
Logger::warn("D3D11Shader::QueryInterface: Unknown interface query");
|
||||||
|
Logger::warn(str::format(riid));
|
||||||
|
}
|
||||||
|
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,8 +29,11 @@ namespace dxvk {
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::warn("D3D11DeviceContextState::QueryInterface: Unknown interface query");
|
if (logQueryInterfaceError(__uuidof(ID3DDeviceContextState), riid)) {
|
||||||
Logger::warn(str::format(riid));
|
Logger::warn("D3D11DeviceContextState::QueryInterface: Unknown interface query");
|
||||||
|
Logger::warn(str::format(riid));
|
||||||
|
}
|
||||||
|
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ namespace dxvk {
|
||||||
}
|
}
|
||||||
|
|
||||||
static float ConvertMinLuminance(UINT dxgiLuminance) {
|
static float ConvertMinLuminance(UINT dxgiLuminance) {
|
||||||
return float(dxgiLuminance) / 0.0001f;
|
return float(dxgiLuminance) * 0.0001f;
|
||||||
}
|
}
|
||||||
|
|
||||||
static float ConvertLevel(UINT16 dxgiLevel) {
|
static float ConvertLevel(UINT16 dxgiLevel) {
|
||||||
|
@ -72,7 +72,7 @@ namespace dxvk {
|
||||||
CreateHud();
|
CreateHud();
|
||||||
|
|
||||||
if (!pDevice->GetOptions()->deferSurfaceCreation)
|
if (!pDevice->GetOptions()->deferSurfaceCreation)
|
||||||
RecreateSwapChain(false);
|
RecreateSwapChain();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -98,12 +98,17 @@ namespace dxvk {
|
||||||
InitReturnPtr(ppvObject);
|
InitReturnPtr(ppvObject);
|
||||||
|
|
||||||
if (riid == __uuidof(IUnknown)
|
if (riid == __uuidof(IUnknown)
|
||||||
|| riid == __uuidof(IDXGIVkSwapChain)) {
|
|| riid == __uuidof(IDXGIVkSwapChain)
|
||||||
|
|| riid == __uuidof(IDXGIVkSwapChain1)) {
|
||||||
*ppvObject = ref(this);
|
*ppvObject = ref(this);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::warn("D3D11SwapChain::QueryInterface: Unknown interface query");
|
if (logQueryInterfaceError(__uuidof(IDXGIVkSwapChain), riid)) {
|
||||||
|
Logger::warn("D3D11SwapChain::QueryInterface: Unknown interface query");
|
||||||
|
Logger::warn(str::format(riid));
|
||||||
|
}
|
||||||
|
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,12 +161,10 @@ namespace dxvk {
|
||||||
|
|
||||||
HANDLE STDMETHODCALLTYPE D3D11SwapChain::GetFrameLatencyEvent() {
|
HANDLE STDMETHODCALLTYPE D3D11SwapChain::GetFrameLatencyEvent() {
|
||||||
HANDLE result = nullptr;
|
HANDLE result = nullptr;
|
||||||
|
HANDLE processHandle = GetCurrentProcess();
|
||||||
|
|
||||||
if (!m_processHandle)
|
if (!DuplicateHandle(processHandle, m_frameLatencyEvent,
|
||||||
m_processHandle = GetCurrentProcess();
|
processHandle, &result, 0, FALSE, DUPLICATE_SAME_ACCESS)) {
|
||||||
|
|
||||||
if (!DuplicateHandle(m_processHandle, m_frameLatencyEvent,
|
|
||||||
m_processHandle, &result, 0, FALSE, DUPLICATE_SAME_ACCESS)) {
|
|
||||||
Logger::err("DxgiSwapChain::GetFrameLatencyWaitableObject: DuplicateHandle failed");
|
Logger::err("DxgiSwapChain::GetFrameLatencyWaitableObject: DuplicateHandle failed");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -251,22 +254,13 @@ namespace dxvk {
|
||||||
UINT SyncInterval,
|
UINT SyncInterval,
|
||||||
UINT PresentFlags,
|
UINT PresentFlags,
|
||||||
const DXGI_PRESENT_PARAMETERS* pPresentParameters) {
|
const DXGI_PRESENT_PARAMETERS* pPresentParameters) {
|
||||||
auto options = m_parent->GetOptions();
|
if (!(PresentFlags & DXGI_PRESENT_TEST))
|
||||||
|
m_dirty |= m_presenter->setSyncInterval(SyncInterval) != VK_SUCCESS;
|
||||||
if (options->syncInterval >= 0)
|
|
||||||
SyncInterval = options->syncInterval;
|
|
||||||
|
|
||||||
if (!(PresentFlags & DXGI_PRESENT_TEST)) {
|
|
||||||
bool vsync = SyncInterval != 0;
|
|
||||||
|
|
||||||
m_dirty |= vsync != m_vsync;
|
|
||||||
m_vsync = vsync;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
if (!m_presenter->hasSwapChain()) {
|
if (!m_presenter->hasSwapChain()) {
|
||||||
RecreateSwapChain(m_vsync);
|
RecreateSwapChain();
|
||||||
m_dirty = false;
|
m_dirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,19 +270,29 @@ namespace dxvk {
|
||||||
if (m_device->getDeviceStatus() != VK_SUCCESS)
|
if (m_device->getDeviceStatus() != VK_SUCCESS)
|
||||||
hr = DXGI_ERROR_DEVICE_RESET;
|
hr = DXGI_ERROR_DEVICE_RESET;
|
||||||
|
|
||||||
if ((PresentFlags & DXGI_PRESENT_TEST) || hr != S_OK)
|
if (PresentFlags & DXGI_PRESENT_TEST)
|
||||||
return hr;
|
return hr;
|
||||||
|
|
||||||
|
if (hr != S_OK) {
|
||||||
|
SyncFrameLatency();
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
if (std::exchange(m_dirty, false))
|
if (std::exchange(m_dirty, false))
|
||||||
RecreateSwapChain(m_vsync);
|
RecreateSwapChain();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
PresentImage(SyncInterval);
|
hr = PresentImage(SyncInterval);
|
||||||
} catch (const DxvkError& e) {
|
} catch (const DxvkError& e) {
|
||||||
Logger::err(e.message());
|
Logger::err(e.message());
|
||||||
hr = E_FAIL;
|
hr = E_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure to synchronize and release the frame latency semaphore
|
||||||
|
// even if presentation failed with STATUS_OCCLUDED, or otherwise
|
||||||
|
// applications using the semaphore may deadlock. This works because
|
||||||
|
// we do not increment the frame ID in those situations.
|
||||||
|
SyncFrameLatency();
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -330,37 +334,44 @@ namespace dxvk {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
HRESULT D3D11SwapChain::PresentImage(UINT SyncInterval) {
|
void STDMETHODCALLTYPE D3D11SwapChain::GetLastPresentCount(
|
||||||
Com<ID3D11DeviceContext> deviceContext = nullptr;
|
UINT64* pLastPresentCount) {
|
||||||
m_parent->GetImmediateContext(&deviceContext);
|
*pLastPresentCount = UINT64(m_frameId - DXGI_MAX_SWAP_CHAIN_BUFFERS);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void STDMETHODCALLTYPE D3D11SwapChain::GetFrameStatistics(
|
||||||
|
DXGI_VK_FRAME_STATISTICS* pFrameStatistics) {
|
||||||
|
std::lock_guard<dxvk::mutex> lock(m_frameStatisticsLock);
|
||||||
|
*pFrameStatistics = m_frameStatistics;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HRESULT D3D11SwapChain::PresentImage(UINT SyncInterval) {
|
||||||
// Flush pending rendering commands before
|
// Flush pending rendering commands before
|
||||||
auto immediateContext = static_cast<D3D11ImmediateContext*>(deviceContext.ptr());
|
auto immediateContext = m_parent->GetContext();
|
||||||
immediateContext->EndFrame();
|
immediateContext->EndFrame();
|
||||||
immediateContext->Flush();
|
immediateContext->Flush();
|
||||||
|
|
||||||
// Bump our frame id.
|
|
||||||
++m_frameId;
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < SyncInterval || i < 1; i++) {
|
for (uint32_t i = 0; i < SyncInterval || i < 1; i++) {
|
||||||
SynchronizePresent();
|
SynchronizePresent();
|
||||||
|
|
||||||
if (!m_presenter->hasSwapChain())
|
if (!m_presenter->hasSwapChain())
|
||||||
return DXGI_STATUS_OCCLUDED;
|
return i ? S_OK : DXGI_STATUS_OCCLUDED;
|
||||||
|
|
||||||
// Presentation semaphores and WSI swap chain image
|
// Presentation semaphores and WSI swap chain image
|
||||||
vk::PresenterInfo info = m_presenter->info();
|
PresenterInfo info = m_presenter->info();
|
||||||
vk::PresenterSync sync;
|
PresenterSync sync;
|
||||||
|
|
||||||
uint32_t imageIndex = 0;
|
uint32_t imageIndex = 0;
|
||||||
|
|
||||||
VkResult status = m_presenter->acquireNextImage(sync, imageIndex);
|
VkResult status = m_presenter->acquireNextImage(sync, imageIndex);
|
||||||
|
|
||||||
while (status != VK_SUCCESS && status != VK_SUBOPTIMAL_KHR) {
|
while (status != VK_SUCCESS && status != VK_SUBOPTIMAL_KHR) {
|
||||||
RecreateSwapChain(m_vsync);
|
RecreateSwapChain();
|
||||||
|
|
||||||
if (!m_presenter->hasSwapChain())
|
if (!m_presenter->hasSwapChain())
|
||||||
return DXGI_STATUS_OCCLUDED;
|
return i ? S_OK : DXGI_STATUS_OCCLUDED;
|
||||||
|
|
||||||
info = m_presenter->info();
|
info = m_presenter->info();
|
||||||
status = m_presenter->acquireNextImage(sync, imageIndex);
|
status = m_presenter->acquireNextImage(sync, imageIndex);
|
||||||
|
@ -371,8 +382,6 @@ namespace dxvk {
|
||||||
m_dirtyHdrMetadata = false;
|
m_dirtyHdrMetadata = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resolve back buffer if it is multisampled. We
|
|
||||||
// only have to do it only for the first frame.
|
|
||||||
m_context->beginRecording(
|
m_context->beginRecording(
|
||||||
m_device->createCommandList());
|
m_device->createCommandList());
|
||||||
|
|
||||||
|
@ -383,40 +392,45 @@ namespace dxvk {
|
||||||
if (m_hud != nullptr)
|
if (m_hud != nullptr)
|
||||||
m_hud->render(m_context, info.format, info.imageExtent);
|
m_hud->render(m_context, info.format, info.imageExtent);
|
||||||
|
|
||||||
if (i + 1 >= SyncInterval)
|
|
||||||
m_context->signal(m_frameLatencySignal, m_frameId);
|
|
||||||
|
|
||||||
SubmitPresent(immediateContext, sync, i);
|
SubmitPresent(immediateContext, sync, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
SyncFrameLatency();
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void D3D11SwapChain::SubmitPresent(
|
void D3D11SwapChain::SubmitPresent(
|
||||||
D3D11ImmediateContext* pContext,
|
D3D11ImmediateContext* pContext,
|
||||||
const vk::PresenterSync& Sync,
|
const PresenterSync& Sync,
|
||||||
uint32_t FrameId) {
|
uint32_t Repeat) {
|
||||||
auto lock = pContext->LockContext();
|
auto lock = pContext->LockContext();
|
||||||
|
|
||||||
|
// Bump frame ID as necessary
|
||||||
|
if (!Repeat)
|
||||||
|
m_frameId += 1;
|
||||||
|
|
||||||
// Present from CS thread so that we don't
|
// Present from CS thread so that we don't
|
||||||
// have to synchronize with it first.
|
// have to synchronize with it first.
|
||||||
m_presentStatus.result = VK_NOT_READY;
|
m_presentStatus.result = VK_NOT_READY;
|
||||||
|
|
||||||
pContext->EmitCs([this,
|
pContext->EmitCs([this,
|
||||||
cFrameId = FrameId,
|
cRepeat = Repeat,
|
||||||
cSync = Sync,
|
cSync = Sync,
|
||||||
cHud = m_hud,
|
cHud = m_hud,
|
||||||
|
cPresentMode = m_presenter->info().presentMode,
|
||||||
|
cFrameId = m_frameId,
|
||||||
cCommandList = m_context->endRecording()
|
cCommandList = m_context->endRecording()
|
||||||
] (DxvkContext* ctx) {
|
] (DxvkContext* ctx) {
|
||||||
cCommandList->setWsiSemaphores(cSync);
|
cCommandList->setWsiSemaphores(cSync);
|
||||||
m_device->submitCommandList(cCommandList);
|
m_device->submitCommandList(cCommandList, nullptr);
|
||||||
|
|
||||||
if (cHud != nullptr && !cFrameId)
|
if (cHud != nullptr && !cRepeat)
|
||||||
cHud->update();
|
cHud->update();
|
||||||
|
|
||||||
m_device->presentImage(m_presenter, &m_presentStatus);
|
uint64_t frameId = cRepeat ? 0 : cFrameId;
|
||||||
|
|
||||||
|
m_device->presentImage(m_presenter,
|
||||||
|
cPresentMode, frameId, &m_presentStatus);
|
||||||
});
|
});
|
||||||
|
|
||||||
pContext->FlushCsChunk();
|
pContext->FlushCsChunk();
|
||||||
|
@ -428,11 +442,11 @@ namespace dxvk {
|
||||||
VkResult status = m_device->waitForSubmission(&m_presentStatus);
|
VkResult status = m_device->waitForSubmission(&m_presentStatus);
|
||||||
|
|
||||||
if (status != VK_SUCCESS)
|
if (status != VK_SUCCESS)
|
||||||
RecreateSwapChain(m_vsync);
|
RecreateSwapChain();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void D3D11SwapChain::RecreateSwapChain(BOOL Vsync) {
|
void D3D11SwapChain::RecreateSwapChain() {
|
||||||
// Ensure that we can safely destroy the swap chain
|
// Ensure that we can safely destroy the swap chain
|
||||||
m_device->waitForSubmission(&m_presentStatus);
|
m_device->waitForSubmission(&m_presentStatus);
|
||||||
m_device->waitForIdle();
|
m_device->waitForIdle();
|
||||||
|
@ -440,11 +454,10 @@ namespace dxvk {
|
||||||
m_presentStatus.result = VK_SUCCESS;
|
m_presentStatus.result = VK_SUCCESS;
|
||||||
m_dirtyHdrMetadata = true;
|
m_dirtyHdrMetadata = true;
|
||||||
|
|
||||||
vk::PresenterDesc presenterDesc;
|
PresenterDesc presenterDesc;
|
||||||
presenterDesc.imageExtent = { m_desc.Width, m_desc.Height };
|
presenterDesc.imageExtent = { m_desc.Width, m_desc.Height };
|
||||||
presenterDesc.imageCount = PickImageCount(m_desc.BufferCount + 1);
|
presenterDesc.imageCount = PickImageCount(m_desc.BufferCount + 1);
|
||||||
presenterDesc.numFormats = PickFormats(m_desc.Format, presenterDesc.formats);
|
presenterDesc.numFormats = PickFormats(m_desc.Format, presenterDesc.formats);
|
||||||
presenterDesc.numPresentModes = PickPresentModes(Vsync, presenterDesc.presentModes);
|
|
||||||
presenterDesc.fullScreenExclusive = PickFullscreenMode();
|
presenterDesc.fullScreenExclusive = PickFullscreenMode();
|
||||||
|
|
||||||
VkResult vr = m_presenter->recreateSwapChain(presenterDesc);
|
VkResult vr = m_presenter->recreateSwapChain(presenterDesc);
|
||||||
|
@ -476,28 +489,13 @@ namespace dxvk {
|
||||||
|
|
||||||
|
|
||||||
void D3D11SwapChain::CreatePresenter() {
|
void D3D11SwapChain::CreatePresenter() {
|
||||||
DxvkDeviceQueue graphicsQueue = m_device->queues().graphics;
|
PresenterDesc presenterDesc;
|
||||||
|
|
||||||
vk::PresenterDevice presenterDevice;
|
|
||||||
presenterDevice.queueFamily = graphicsQueue.queueFamily;
|
|
||||||
presenterDevice.queue = graphicsQueue.queueHandle;
|
|
||||||
presenterDevice.adapter = m_device->adapter()->handle();
|
|
||||||
presenterDevice.features.fullScreenExclusive = m_device->features().extFullScreenExclusive;
|
|
||||||
presenterDevice.features.hdrMetadata = m_device->features().extHdrMetadata;
|
|
||||||
|
|
||||||
vk::PresenterDesc presenterDesc;
|
|
||||||
presenterDesc.imageExtent = { m_desc.Width, m_desc.Height };
|
presenterDesc.imageExtent = { m_desc.Width, m_desc.Height };
|
||||||
presenterDesc.imageCount = PickImageCount(m_desc.BufferCount + 1);
|
presenterDesc.imageCount = PickImageCount(m_desc.BufferCount + 1);
|
||||||
presenterDesc.numFormats = PickFormats(m_desc.Format, presenterDesc.formats);
|
presenterDesc.numFormats = PickFormats(m_desc.Format, presenterDesc.formats);
|
||||||
presenterDesc.numPresentModes = PickPresentModes(false, presenterDesc.presentModes);
|
|
||||||
presenterDesc.fullScreenExclusive = PickFullscreenMode();
|
presenterDesc.fullScreenExclusive = PickFullscreenMode();
|
||||||
|
|
||||||
m_presenter = new vk::Presenter(
|
m_presenter = new Presenter(m_device, m_frameLatencySignal, presenterDesc);
|
||||||
m_device->adapter()->vki(),
|
|
||||||
m_device->vkd(),
|
|
||||||
presenterDevice,
|
|
||||||
presenterDesc);
|
|
||||||
|
|
||||||
m_presenter->setFrameRateLimit(m_parent->GetOptions()->maxFrameRate);
|
m_presenter->setFrameRateLimit(m_parent->GetOptions()->maxFrameRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -512,7 +510,7 @@ namespace dxvk {
|
||||||
|
|
||||||
|
|
||||||
void D3D11SwapChain::CreateRenderTargetViews() {
|
void D3D11SwapChain::CreateRenderTargetViews() {
|
||||||
vk::PresenterInfo info = m_presenter->info();
|
PresenterInfo info = m_presenter->info();
|
||||||
|
|
||||||
m_imageViews.clear();
|
m_imageViews.clear();
|
||||||
m_imageViews.resize(info.imageCount);
|
m_imageViews.resize(info.imageCount);
|
||||||
|
@ -546,7 +544,8 @@ namespace dxvk {
|
||||||
VkImage imageHandle = m_presenter->getImage(i).image;
|
VkImage imageHandle = m_presenter->getImage(i).image;
|
||||||
|
|
||||||
Rc<DxvkImage> image = new DxvkImage(
|
Rc<DxvkImage> image = new DxvkImage(
|
||||||
m_device.ptr(), imageInfo, imageHandle);
|
m_device.ptr(), imageInfo, imageHandle,
|
||||||
|
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
||||||
|
|
||||||
m_imageViews[i] = new DxvkImageView(
|
m_imageViews[i] = new DxvkImageView(
|
||||||
m_device->vkd(), image, viewInfo);
|
m_device->vkd(), image, viewInfo);
|
||||||
|
@ -626,7 +625,8 @@ namespace dxvk {
|
||||||
subresources, VK_IMAGE_LAYOUT_UNDEFINED);
|
subresources, VK_IMAGE_LAYOUT_UNDEFINED);
|
||||||
|
|
||||||
m_device->submitCommandList(
|
m_device->submitCommandList(
|
||||||
m_context->endRecording());
|
m_context->endRecording(),
|
||||||
|
nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -652,11 +652,17 @@ namespace dxvk {
|
||||||
// Wait for the sync event so that we respect the maximum frame latency
|
// Wait for the sync event so that we respect the maximum frame latency
|
||||||
m_frameLatencySignal->wait(m_frameId - GetActualFrameLatency());
|
m_frameLatencySignal->wait(m_frameId - GetActualFrameLatency());
|
||||||
|
|
||||||
if (m_frameLatencyEvent) {
|
m_frameLatencySignal->setCallback(m_frameId, [this,
|
||||||
m_frameLatencySignal->setCallback(m_frameId, [cFrameLatencyEvent = m_frameLatencyEvent] () {
|
cFrameId = m_frameId,
|
||||||
|
cFrameLatencyEvent = m_frameLatencyEvent
|
||||||
|
] () {
|
||||||
|
if (cFrameLatencyEvent)
|
||||||
ReleaseSemaphore(cFrameLatencyEvent, 1, nullptr);
|
ReleaseSemaphore(cFrameLatencyEvent, 1, nullptr);
|
||||||
});
|
|
||||||
}
|
std::lock_guard<dxvk::mutex> lock(m_frameStatisticsLock);
|
||||||
|
m_frameStatistics.PresentCount = cFrameId - DXGI_MAX_SWAP_CHAIN_BUFFERS;
|
||||||
|
m_frameStatistics.PresentQPCTime = dxvk::high_resolution_clock::get_counter();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -672,7 +678,7 @@ namespace dxvk {
|
||||||
if (m_frameLatencyCap)
|
if (m_frameLatencyCap)
|
||||||
maxFrameLatency = std::min(maxFrameLatency, m_frameLatencyCap);
|
maxFrameLatency = std::min(maxFrameLatency, m_frameLatencyCap);
|
||||||
|
|
||||||
maxFrameLatency = std::min(maxFrameLatency, m_desc.BufferCount + 1);
|
maxFrameLatency = std::min(maxFrameLatency, m_desc.BufferCount);
|
||||||
return maxFrameLatency;
|
return maxFrameLatency;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -713,25 +719,6 @@ namespace dxvk {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint32_t D3D11SwapChain::PickPresentModes(
|
|
||||||
BOOL Vsync,
|
|
||||||
VkPresentModeKHR* pDstModes) {
|
|
||||||
uint32_t n = 0;
|
|
||||||
|
|
||||||
if (Vsync) {
|
|
||||||
if (m_parent->GetOptions()->tearFree == Tristate::False)
|
|
||||||
pDstModes[n++] = VK_PRESENT_MODE_FIFO_RELAXED_KHR;
|
|
||||||
pDstModes[n++] = VK_PRESENT_MODE_FIFO_KHR;
|
|
||||||
} else {
|
|
||||||
if (m_parent->GetOptions()->tearFree != Tristate::True)
|
|
||||||
pDstModes[n++] = VK_PRESENT_MODE_IMMEDIATE_KHR;
|
|
||||||
pDstModes[n++] = VK_PRESENT_MODE_MAILBOX_KHR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t D3D11SwapChain::PickImageCount(
|
uint32_t D3D11SwapChain::PickImageCount(
|
||||||
UINT Preferred) {
|
UINT Preferred) {
|
||||||
int32_t option = m_parent->GetOptions()->numBackBuffers;
|
int32_t option = m_parent->GetOptions()->numBackBuffers;
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace dxvk {
|
||||||
class D3D11Device;
|
class D3D11Device;
|
||||||
class D3D11DXGIDevice;
|
class D3D11DXGIDevice;
|
||||||
|
|
||||||
class D3D11SwapChain : public ComObject<IDXGIVkSwapChain> {
|
class D3D11SwapChain : public ComObject<IDXGIVkSwapChain1> {
|
||||||
constexpr static uint32_t DefaultFrameLatency = 1;
|
constexpr static uint32_t DefaultFrameLatency = 1;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -80,6 +80,12 @@ namespace dxvk {
|
||||||
HRESULT STDMETHODCALLTYPE SetHDRMetaData(
|
HRESULT STDMETHODCALLTYPE SetHDRMetaData(
|
||||||
const DXGI_VK_HDR_METADATA* pMetaData);
|
const DXGI_VK_HDR_METADATA* pMetaData);
|
||||||
|
|
||||||
|
void STDMETHODCALLTYPE GetLastPresentCount(
|
||||||
|
UINT64* pLastPresentCount);
|
||||||
|
|
||||||
|
void STDMETHODCALLTYPE GetFrameStatistics(
|
||||||
|
DXGI_VK_FRAME_STATISTICS* pFrameStatistics);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
enum BindingIds : uint32_t {
|
enum BindingIds : uint32_t {
|
||||||
|
@ -97,7 +103,7 @@ namespace dxvk {
|
||||||
Rc<DxvkDevice> m_device;
|
Rc<DxvkDevice> m_device;
|
||||||
Rc<DxvkContext> m_context;
|
Rc<DxvkContext> m_context;
|
||||||
|
|
||||||
Rc<vk::Presenter> m_presenter;
|
Rc<Presenter> m_presenter;
|
||||||
|
|
||||||
Rc<DxvkImage> m_swapImage;
|
Rc<DxvkImage> m_swapImage;
|
||||||
Rc<DxvkImageView> m_swapImageView;
|
Rc<DxvkImageView> m_swapImageView;
|
||||||
|
@ -116,27 +122,26 @@ namespace dxvk {
|
||||||
HANDLE m_frameLatencyEvent = nullptr;
|
HANDLE m_frameLatencyEvent = nullptr;
|
||||||
Rc<sync::CallbackFence> m_frameLatencySignal;
|
Rc<sync::CallbackFence> m_frameLatencySignal;
|
||||||
|
|
||||||
HANDLE m_processHandle = nullptr;
|
|
||||||
|
|
||||||
bool m_dirty = true;
|
bool m_dirty = true;
|
||||||
bool m_vsync = true;
|
|
||||||
|
|
||||||
VkColorSpaceKHR m_colorspace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
|
VkColorSpaceKHR m_colorspace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
|
||||||
|
|
||||||
std::optional<VkHdrMetadataEXT> m_hdrMetadata;
|
std::optional<VkHdrMetadataEXT> m_hdrMetadata;
|
||||||
bool m_dirtyHdrMetadata = true;
|
bool m_dirtyHdrMetadata = true;
|
||||||
|
|
||||||
|
dxvk::mutex m_frameStatisticsLock;
|
||||||
|
DXGI_VK_FRAME_STATISTICS m_frameStatistics = { };
|
||||||
|
|
||||||
HRESULT PresentImage(UINT SyncInterval);
|
HRESULT PresentImage(UINT SyncInterval);
|
||||||
|
|
||||||
void SubmitPresent(
|
void SubmitPresent(
|
||||||
D3D11ImmediateContext* pContext,
|
D3D11ImmediateContext* pContext,
|
||||||
const vk::PresenterSync& Sync,
|
const PresenterSync& Sync,
|
||||||
uint32_t FrameId);
|
uint32_t Repeat);
|
||||||
|
|
||||||
void SynchronizePresent();
|
void SynchronizePresent();
|
||||||
|
|
||||||
void RecreateSwapChain(
|
void RecreateSwapChain();
|
||||||
BOOL Vsync);
|
|
||||||
|
|
||||||
void CreateFrameLatencyEvent();
|
void CreateFrameLatencyEvent();
|
||||||
|
|
||||||
|
@ -162,10 +167,6 @@ namespace dxvk {
|
||||||
DXGI_FORMAT Format,
|
DXGI_FORMAT Format,
|
||||||
VkSurfaceFormatKHR* pDstFormats);
|
VkSurfaceFormatKHR* pDstFormats);
|
||||||
|
|
||||||
uint32_t PickPresentModes(
|
|
||||||
BOOL Vsync,
|
|
||||||
VkPresentModeKHR* pDstModes);
|
|
||||||
|
|
||||||
uint32_t PickImageCount(
|
uint32_t PickImageCount(
|
||||||
UINT Preferred);
|
UINT Preferred);
|
||||||
|
|
||||||
|
|
|
@ -11,11 +11,13 @@ namespace dxvk {
|
||||||
ID3D11Resource* pInterface,
|
ID3D11Resource* pInterface,
|
||||||
D3D11Device* pDevice,
|
D3D11Device* pDevice,
|
||||||
const D3D11_COMMON_TEXTURE_DESC* pDesc,
|
const D3D11_COMMON_TEXTURE_DESC* pDesc,
|
||||||
|
const D3D11_ON_12_RESOURCE_INFO* p11on12Info,
|
||||||
D3D11_RESOURCE_DIMENSION Dimension,
|
D3D11_RESOURCE_DIMENSION Dimension,
|
||||||
DXGI_USAGE DxgiUsage,
|
DXGI_USAGE DxgiUsage,
|
||||||
VkImage vkImage,
|
VkImage vkImage,
|
||||||
HANDLE hSharedHandle)
|
HANDLE hSharedHandle)
|
||||||
: m_interface(pInterface), m_device(pDevice), m_dimension(Dimension), m_desc(*pDesc), m_dxgiUsage(DxgiUsage) {
|
: m_interface(pInterface), m_device(pDevice), m_dimension(Dimension), m_desc(*pDesc),
|
||||||
|
m_11on12(p11on12Info ? *p11on12Info : D3D11_ON_12_RESOURCE_INFO()), m_dxgiUsage(DxgiUsage) {
|
||||||
DXGI_VK_FORMAT_MODE formatMode = GetFormatMode();
|
DXGI_VK_FORMAT_MODE formatMode = GetFormatMode();
|
||||||
DXGI_VK_FORMAT_INFO formatInfo = m_device->LookupFormat(m_desc.Format, formatMode);
|
DXGI_VK_FORMAT_INFO formatInfo = m_device->LookupFormat(m_desc.Format, formatMode);
|
||||||
DXGI_VK_FORMAT_FAMILY formatFamily = m_device->LookupFamily(m_desc.Format, formatMode);
|
DXGI_VK_FORMAT_FAMILY formatFamily = m_device->LookupFamily(m_desc.Format, formatMode);
|
||||||
|
@ -46,15 +48,21 @@ namespace dxvk {
|
||||||
if (hSharedHandle == nullptr)
|
if (hSharedHandle == nullptr)
|
||||||
hSharedHandle = INVALID_HANDLE_VALUE;
|
hSharedHandle = INVALID_HANDLE_VALUE;
|
||||||
|
|
||||||
if (m_desc.MiscFlags & (D3D11_RESOURCE_MISC_SHARED|D3D11_RESOURCE_MISC_SHARED_NTHANDLE)) {
|
const auto sharingFlags = D3D11_RESOURCE_MISC_SHARED|D3D11_RESOURCE_MISC_SHARED_NTHANDLE|D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
|
||||||
if (m_desc.MiscFlags & D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX)
|
|
||||||
Logger::warn("D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX: not supported.");
|
if (m_desc.MiscFlags & sharingFlags) {
|
||||||
|
if (pDevice->GetFeatureLevel() < D3D_FEATURE_LEVEL_10_0 ||
|
||||||
|
(m_desc.MiscFlags & (D3D11_RESOURCE_MISC_SHARED|D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX)) == (D3D11_RESOURCE_MISC_SHARED|D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX) ||
|
||||||
|
(m_desc.MiscFlags & sharingFlags) == D3D11_RESOURCE_MISC_SHARED_NTHANDLE)
|
||||||
|
throw DxvkError(str::format("D3D11: Cannot create shared texture:",
|
||||||
|
"\n MiscFlags: ", m_desc.MiscFlags,
|
||||||
|
"\n FeatureLevel: ", pDevice->GetFeatureLevel()));
|
||||||
|
|
||||||
imageInfo.shared = true;
|
imageInfo.shared = true;
|
||||||
imageInfo.sharing.mode = hSharedHandle == INVALID_HANDLE_VALUE ? DxvkSharedHandleMode::Export : DxvkSharedHandleMode::Import;
|
imageInfo.sharing.mode = hSharedHandle == INVALID_HANDLE_VALUE ? DxvkSharedHandleMode::Export : DxvkSharedHandleMode::Import;
|
||||||
imageInfo.sharing.type = (m_desc.MiscFlags & D3D11_RESOURCE_MISC_SHARED)
|
imageInfo.sharing.type = (m_desc.MiscFlags & D3D11_RESOURCE_MISC_SHARED_NTHANDLE)
|
||||||
? VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT
|
? VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
|
||||||
: VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT;
|
: VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT;
|
||||||
imageInfo.sharing.handle = hSharedHandle;
|
imageInfo.sharing.handle = hSharedHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,9 +211,12 @@ namespace dxvk {
|
||||||
// For some formats, we need to enable sampled and/or
|
// For some formats, we need to enable sampled and/or
|
||||||
// render target capabilities if available, but these
|
// render target capabilities if available, but these
|
||||||
// should in no way affect the default image layout
|
// should in no way affect the default image layout
|
||||||
imageInfo.usage |= EnableMetaCopyUsage(imageInfo.format, imageInfo.tiling);
|
|
||||||
imageInfo.usage |= EnableMetaPackUsage(imageInfo.format, m_desc.CPUAccessFlags);
|
imageInfo.usage |= EnableMetaPackUsage(imageInfo.format, m_desc.CPUAccessFlags);
|
||||||
|
imageInfo.usage |= EnableMetaCopyUsage(imageInfo.format, imageInfo.tiling);
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < imageInfo.viewFormatCount; i++)
|
||||||
|
imageInfo.usage |= EnableMetaCopyUsage(imageInfo.viewFormats[i], imageInfo.tiling);
|
||||||
|
|
||||||
// Check if we can actually create the image
|
// Check if we can actually create the image
|
||||||
if (!CheckImageSupport(&imageInfo, imageInfo.tiling)) {
|
if (!CheckImageSupport(&imageInfo, imageInfo.tiling)) {
|
||||||
throw DxvkError(str::format(
|
throw DxvkError(str::format(
|
||||||
|
@ -228,10 +239,13 @@ namespace dxvk {
|
||||||
if (m_mapMode == D3D11_COMMON_TEXTURE_MAP_MODE_DIRECT)
|
if (m_mapMode == D3D11_COMMON_TEXTURE_MAP_MODE_DIRECT)
|
||||||
memoryProperties = GetMemoryFlags();
|
memoryProperties = GetMemoryFlags();
|
||||||
|
|
||||||
if (vkImage == VK_NULL_HANDLE)
|
if (m_11on12.Resource != nullptr)
|
||||||
|
vkImage = VkImage(m_11on12.VulkanHandle);
|
||||||
|
|
||||||
|
if (!vkImage)
|
||||||
m_image = m_device->GetDXVKDevice()->createImage(imageInfo, memoryProperties);
|
m_image = m_device->GetDXVKDevice()->createImage(imageInfo, memoryProperties);
|
||||||
else
|
else
|
||||||
m_image = m_device->GetDXVKDevice()->createImageFromVkImage(imageInfo, vkImage);
|
m_image = m_device->GetDXVKDevice()->importImage(imageInfo, vkImage, memoryProperties);
|
||||||
|
|
||||||
if (imageInfo.sharing.mode == DxvkSharedHandleMode::Export)
|
if (imageInfo.sharing.mode == DxvkSharedHandleMode::Export)
|
||||||
ExportImageInfo();
|
ExportImageInfo();
|
||||||
|
@ -469,9 +483,60 @@ namespace dxvk {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HRESULT D3D11CommonTexture::GetDescFromD3D12(
|
||||||
|
ID3D12Resource* pResource,
|
||||||
|
const D3D11_RESOURCE_FLAGS* pResourceFlags,
|
||||||
|
D3D11_COMMON_TEXTURE_DESC* pTextureDesc) {
|
||||||
|
D3D12_RESOURCE_DESC desc12 = pResource->GetDesc();
|
||||||
|
|
||||||
|
pTextureDesc->Width = desc12.Width;
|
||||||
|
pTextureDesc->Height = desc12.Height;
|
||||||
|
|
||||||
|
if (desc12.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D) {
|
||||||
|
pTextureDesc->Depth = desc12.DepthOrArraySize;
|
||||||
|
pTextureDesc->ArraySize = 1;
|
||||||
|
} else {
|
||||||
|
pTextureDesc->Depth = 1;
|
||||||
|
pTextureDesc->ArraySize = desc12.DepthOrArraySize;
|
||||||
|
}
|
||||||
|
|
||||||
|
pTextureDesc->MipLevels = desc12.MipLevels;
|
||||||
|
pTextureDesc->Format = desc12.Format;
|
||||||
|
pTextureDesc->SampleDesc = desc12.SampleDesc;
|
||||||
|
pTextureDesc->Usage = D3D11_USAGE_DEFAULT;
|
||||||
|
pTextureDesc->BindFlags = 0;
|
||||||
|
pTextureDesc->CPUAccessFlags = 0;
|
||||||
|
pTextureDesc->MiscFlags = 0;
|
||||||
|
|
||||||
|
if (!(desc12.Flags & D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE))
|
||||||
|
pTextureDesc->BindFlags |= D3D11_BIND_SHADER_RESOURCE;
|
||||||
|
|
||||||
|
if (desc12.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET)
|
||||||
|
pTextureDesc->BindFlags |= D3D11_BIND_RENDER_TARGET;
|
||||||
|
|
||||||
|
if (desc12.Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL)
|
||||||
|
pTextureDesc->BindFlags |= D3D11_BIND_DEPTH_STENCIL;
|
||||||
|
|
||||||
|
if (desc12.Flags & D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS)
|
||||||
|
pTextureDesc->BindFlags |= D3D11_BIND_UNORDERED_ACCESS;
|
||||||
|
|
||||||
|
if (pResourceFlags) {
|
||||||
|
pTextureDesc->BindFlags = pResourceFlags->BindFlags;
|
||||||
|
pTextureDesc->MiscFlags |= pResourceFlags->MiscFlags;
|
||||||
|
pTextureDesc->CPUAccessFlags = pResourceFlags->CPUAccessFlags;
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
BOOL D3D11CommonTexture::CheckImageSupport(
|
BOOL D3D11CommonTexture::CheckImageSupport(
|
||||||
const DxvkImageCreateInfo* pImageInfo,
|
const DxvkImageCreateInfo* pImageInfo,
|
||||||
VkImageTiling Tiling) const {
|
VkImageTiling Tiling) const {
|
||||||
|
// D3D12 images always use optimal tiling
|
||||||
|
if (m_11on12.Resource != nullptr && Tiling != VK_IMAGE_TILING_OPTIMAL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
DxvkFormatQuery formatQuery = { };
|
DxvkFormatQuery formatQuery = { };
|
||||||
formatQuery.format = pImageInfo->format;
|
formatQuery.format = pImageInfo->format;
|
||||||
formatQuery.type = pImageInfo->type;
|
formatQuery.type = pImageInfo->type;
|
||||||
|
@ -486,7 +551,7 @@ namespace dxvk {
|
||||||
|
|
||||||
if (!properties)
|
if (!properties)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
return (pImageInfo->extent.width <= properties->maxExtent.width)
|
return (pImageInfo->extent.width <= properties->maxExtent.width)
|
||||||
&& (pImageInfo->extent.height <= properties->maxExtent.height)
|
&& (pImageInfo->extent.height <= properties->maxExtent.height)
|
||||||
&& (pImageInfo->extent.depth <= properties->maxExtent.depth)
|
&& (pImageInfo->extent.depth <= properties->maxExtent.depth)
|
||||||
|
@ -640,10 +705,10 @@ namespace dxvk {
|
||||||
void D3D11CommonTexture::ExportImageInfo() {
|
void D3D11CommonTexture::ExportImageInfo() {
|
||||||
HANDLE hSharedHandle;
|
HANDLE hSharedHandle;
|
||||||
|
|
||||||
if (m_desc.MiscFlags & D3D11_RESOURCE_MISC_SHARED)
|
if (m_desc.MiscFlags & D3D11_RESOURCE_MISC_SHARED_NTHANDLE)
|
||||||
hSharedHandle = openKmtHandle( m_image->sharedHandle() );
|
|
||||||
else
|
|
||||||
hSharedHandle = m_image->sharedHandle();
|
hSharedHandle = m_image->sharedHandle();
|
||||||
|
else
|
||||||
|
hSharedHandle = openKmtHandle( m_image->sharedHandle() );
|
||||||
|
|
||||||
DxvkSharedTextureMetadata metadata;
|
DxvkSharedTextureMetadata metadata;
|
||||||
|
|
||||||
|
@ -663,7 +728,7 @@ namespace dxvk {
|
||||||
Logger::warn("D3D11: Failed to write shared resource info for a texture");
|
Logger::warn("D3D11: Failed to write shared resource info for a texture");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((m_desc.MiscFlags & D3D11_RESOURCE_MISC_SHARED) && hSharedHandle != INVALID_HANDLE_VALUE)
|
if (hSharedHandle != INVALID_HANDLE_VALUE)
|
||||||
CloseHandle(hSharedHandle);
|
CloseHandle(hSharedHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1028,12 +1093,13 @@ namespace dxvk {
|
||||||
// D 3 D 1 1 T E X T U R E 1 D
|
// D 3 D 1 1 T E X T U R E 1 D
|
||||||
D3D11Texture1D::D3D11Texture1D(
|
D3D11Texture1D::D3D11Texture1D(
|
||||||
D3D11Device* pDevice,
|
D3D11Device* pDevice,
|
||||||
const D3D11_COMMON_TEXTURE_DESC* pDesc)
|
const D3D11_COMMON_TEXTURE_DESC* pDesc,
|
||||||
|
const D3D11_ON_12_RESOURCE_INFO* p11on12Info)
|
||||||
: D3D11DeviceChild<ID3D11Texture1D>(pDevice),
|
: D3D11DeviceChild<ID3D11Texture1D>(pDevice),
|
||||||
m_texture (this, pDevice, pDesc, D3D11_RESOURCE_DIMENSION_TEXTURE1D, 0, VK_NULL_HANDLE, nullptr),
|
m_texture (this, pDevice, pDesc, p11on12Info, D3D11_RESOURCE_DIMENSION_TEXTURE1D, 0, VK_NULL_HANDLE, nullptr),
|
||||||
m_interop (this, &m_texture),
|
m_interop (this, &m_texture),
|
||||||
m_surface (this, &m_texture),
|
m_surface (this, &m_texture),
|
||||||
m_resource(this),
|
m_resource(this, pDevice),
|
||||||
m_d3d10 (this) {
|
m_d3d10 (this) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1080,14 +1146,20 @@ namespace dxvk {
|
||||||
*ppvObject = ref(&m_resource);
|
*ppvObject = ref(&m_resource);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (riid == __uuidof(IDXGIKeyedMutex))
|
||||||
|
return m_resource.GetKeyedMutex(ppvObject);
|
||||||
|
|
||||||
if (riid == __uuidof(IDXGIVkInteropSurface)) {
|
if (riid == __uuidof(IDXGIVkInteropSurface)) {
|
||||||
*ppvObject = ref(&m_interop);
|
*ppvObject = ref(&m_interop);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::warn("D3D11Texture1D::QueryInterface: Unknown interface query");
|
if (logQueryInterfaceError(__uuidof(ID3D10Texture1D), riid)) {
|
||||||
Logger::warn(str::format(riid));
|
Logger::warn("D3D11Texture1D::QueryInterface: Unknown interface query");
|
||||||
|
Logger::warn(str::format(riid));
|
||||||
|
}
|
||||||
|
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1127,12 +1199,13 @@ namespace dxvk {
|
||||||
D3D11Texture2D::D3D11Texture2D(
|
D3D11Texture2D::D3D11Texture2D(
|
||||||
D3D11Device* pDevice,
|
D3D11Device* pDevice,
|
||||||
const D3D11_COMMON_TEXTURE_DESC* pDesc,
|
const D3D11_COMMON_TEXTURE_DESC* pDesc,
|
||||||
|
const D3D11_ON_12_RESOURCE_INFO* p11on12Info,
|
||||||
HANDLE hSharedHandle)
|
HANDLE hSharedHandle)
|
||||||
: D3D11DeviceChild<ID3D11Texture2D1>(pDevice),
|
: D3D11DeviceChild<ID3D11Texture2D1>(pDevice),
|
||||||
m_texture (this, pDevice, pDesc, D3D11_RESOURCE_DIMENSION_TEXTURE2D, 0, VK_NULL_HANDLE, hSharedHandle),
|
m_texture (this, pDevice, pDesc, p11on12Info, D3D11_RESOURCE_DIMENSION_TEXTURE2D, 0, VK_NULL_HANDLE, hSharedHandle),
|
||||||
m_interop (this, &m_texture),
|
m_interop (this, &m_texture),
|
||||||
m_surface (this, &m_texture),
|
m_surface (this, &m_texture),
|
||||||
m_resource (this),
|
m_resource (this, pDevice),
|
||||||
m_d3d10 (this),
|
m_d3d10 (this),
|
||||||
m_swapChain (nullptr) {
|
m_swapChain (nullptr) {
|
||||||
}
|
}
|
||||||
|
@ -1144,10 +1217,10 @@ namespace dxvk {
|
||||||
DXGI_USAGE DxgiUsage,
|
DXGI_USAGE DxgiUsage,
|
||||||
VkImage vkImage)
|
VkImage vkImage)
|
||||||
: D3D11DeviceChild<ID3D11Texture2D1>(pDevice),
|
: D3D11DeviceChild<ID3D11Texture2D1>(pDevice),
|
||||||
m_texture (this, pDevice, pDesc, D3D11_RESOURCE_DIMENSION_TEXTURE2D, DxgiUsage, vkImage, nullptr),
|
m_texture (this, pDevice, pDesc, nullptr, D3D11_RESOURCE_DIMENSION_TEXTURE2D, DxgiUsage, vkImage, nullptr),
|
||||||
m_interop (this, &m_texture),
|
m_interop (this, &m_texture),
|
||||||
m_surface (this, &m_texture),
|
m_surface (this, &m_texture),
|
||||||
m_resource (this),
|
m_resource (this, pDevice),
|
||||||
m_d3d10 (this),
|
m_d3d10 (this),
|
||||||
m_swapChain (nullptr) {
|
m_swapChain (nullptr) {
|
||||||
|
|
||||||
|
@ -1160,10 +1233,10 @@ namespace dxvk {
|
||||||
const D3D11_COMMON_TEXTURE_DESC* pDesc,
|
const D3D11_COMMON_TEXTURE_DESC* pDesc,
|
||||||
DXGI_USAGE DxgiUsage)
|
DXGI_USAGE DxgiUsage)
|
||||||
: D3D11DeviceChild<ID3D11Texture2D1>(pDevice),
|
: D3D11DeviceChild<ID3D11Texture2D1>(pDevice),
|
||||||
m_texture (this, pDevice, pDesc, D3D11_RESOURCE_DIMENSION_TEXTURE2D, DxgiUsage, VK_NULL_HANDLE, nullptr),
|
m_texture (this, pDevice, pDesc, nullptr, D3D11_RESOURCE_DIMENSION_TEXTURE2D, DxgiUsage, VK_NULL_HANDLE, nullptr),
|
||||||
m_interop (this, &m_texture),
|
m_interop (this, &m_texture),
|
||||||
m_surface (this, &m_texture),
|
m_surface (this, &m_texture),
|
||||||
m_resource (this),
|
m_resource (this, pDevice),
|
||||||
m_d3d10 (this),
|
m_d3d10 (this),
|
||||||
m_swapChain (pSwapChain) {
|
m_swapChain (pSwapChain) {
|
||||||
|
|
||||||
|
@ -1237,14 +1310,20 @@ namespace dxvk {
|
||||||
*ppvObject = ref(&m_resource);
|
*ppvObject = ref(&m_resource);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (riid == __uuidof(IDXGIKeyedMutex))
|
||||||
|
return m_resource.GetKeyedMutex(ppvObject);
|
||||||
|
|
||||||
if (riid == __uuidof(IDXGIVkInteropSurface)) {
|
if (riid == __uuidof(IDXGIVkInteropSurface)) {
|
||||||
*ppvObject = ref(&m_interop);
|
*ppvObject = ref(&m_interop);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::warn("D3D11Texture2D::QueryInterface: Unknown interface query");
|
if (logQueryInterfaceError(__uuidof(ID3D10Texture2D), riid)) {
|
||||||
Logger::warn(str::format(riid));
|
Logger::warn("D3D11Texture2D::QueryInterface: Unknown interface query");
|
||||||
|
Logger::warn(str::format(riid));
|
||||||
|
}
|
||||||
|
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1300,11 +1379,12 @@ namespace dxvk {
|
||||||
// D 3 D 1 1 T E X T U R E 3 D
|
// D 3 D 1 1 T E X T U R E 3 D
|
||||||
D3D11Texture3D::D3D11Texture3D(
|
D3D11Texture3D::D3D11Texture3D(
|
||||||
D3D11Device* pDevice,
|
D3D11Device* pDevice,
|
||||||
const D3D11_COMMON_TEXTURE_DESC* pDesc)
|
const D3D11_COMMON_TEXTURE_DESC* pDesc,
|
||||||
|
const D3D11_ON_12_RESOURCE_INFO* p11on12Info)
|
||||||
: D3D11DeviceChild<ID3D11Texture3D1>(pDevice),
|
: D3D11DeviceChild<ID3D11Texture3D1>(pDevice),
|
||||||
m_texture (this, pDevice, pDesc, D3D11_RESOURCE_DIMENSION_TEXTURE3D, 0, VK_NULL_HANDLE, nullptr),
|
m_texture (this, pDevice, pDesc, p11on12Info, D3D11_RESOURCE_DIMENSION_TEXTURE3D, 0, VK_NULL_HANDLE, nullptr),
|
||||||
m_interop (this, &m_texture),
|
m_interop (this, &m_texture),
|
||||||
m_resource(this),
|
m_resource(this, pDevice),
|
||||||
m_d3d10 (this) {
|
m_d3d10 (this) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1344,14 +1424,20 @@ namespace dxvk {
|
||||||
*ppvObject = ref(&m_resource);
|
*ppvObject = ref(&m_resource);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (riid == __uuidof(IDXGIKeyedMutex))
|
||||||
|
return m_resource.GetKeyedMutex(ppvObject);
|
||||||
|
|
||||||
if (riid == __uuidof(IDXGIVkInteropSurface)) {
|
if (riid == __uuidof(IDXGIVkInteropSurface)) {
|
||||||
*ppvObject = ref(&m_interop);
|
*ppvObject = ref(&m_interop);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::warn("D3D11Texture3D::QueryInterface: Unknown interface query");
|
if (logQueryInterfaceError(__uuidof(ID3D10Texture3D), riid)) {
|
||||||
Logger::warn(str::format(riid));
|
Logger::warn("D3D11Texture3D::QueryInterface: Unknown interface query");
|
||||||
|
Logger::warn(str::format(riid));
|
||||||
|
}
|
||||||
|
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
#include "d3d11_device_child.h"
|
#include "d3d11_device_child.h"
|
||||||
#include "d3d11_interfaces.h"
|
#include "d3d11_interfaces.h"
|
||||||
|
#include "d3d11_on_12.h"
|
||||||
#include "d3d11_resource.h"
|
#include "d3d11_resource.h"
|
||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
@ -85,6 +86,7 @@ namespace dxvk {
|
||||||
ID3D11Resource* pInterface,
|
ID3D11Resource* pInterface,
|
||||||
D3D11Device* pDevice,
|
D3D11Device* pDevice,
|
||||||
const D3D11_COMMON_TEXTURE_DESC* pDesc,
|
const D3D11_COMMON_TEXTURE_DESC* pDesc,
|
||||||
|
const D3D11_ON_12_RESOURCE_INFO* p11on12Info,
|
||||||
D3D11_RESOURCE_DIMENSION Dimension,
|
D3D11_RESOURCE_DIMENSION Dimension,
|
||||||
DXGI_USAGE DxgiUsage,
|
DXGI_USAGE DxgiUsage,
|
||||||
VkImage vkImage,
|
VkImage vkImage,
|
||||||
|
@ -435,6 +437,14 @@ namespace dxvk {
|
||||||
DXGI_FORMAT Format,
|
DXGI_FORMAT Format,
|
||||||
UINT Plane) const;
|
UINT Plane) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Retrieves D3D11on12 resource info
|
||||||
|
* \returns 11on12 resource info
|
||||||
|
*/
|
||||||
|
D3D11_ON_12_RESOURCE_INFO Get11on12Info() const {
|
||||||
|
return m_11on12;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Normalizes and validates texture description
|
* \brief Normalizes and validates texture description
|
||||||
*
|
*
|
||||||
|
@ -447,6 +457,19 @@ namespace dxvk {
|
||||||
static HRESULT NormalizeTextureProperties(
|
static HRESULT NormalizeTextureProperties(
|
||||||
D3D11_COMMON_TEXTURE_DESC* pDesc);
|
D3D11_COMMON_TEXTURE_DESC* pDesc);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Initializes D3D11 texture description from D3D12
|
||||||
|
*
|
||||||
|
* \param [in] pResource D3D12 resource
|
||||||
|
* \param [in] pResourceFlags D3D11 flag overrides
|
||||||
|
* \param [out] pTextureDesc D3D11 buffer description
|
||||||
|
* \returns \c S_OK if the parameters are valid
|
||||||
|
*/
|
||||||
|
static HRESULT GetDescFromD3D12(
|
||||||
|
ID3D12Resource* pResource,
|
||||||
|
const D3D11_RESOURCE_FLAGS* pResourceFlags,
|
||||||
|
D3D11_COMMON_TEXTURE_DESC* pTextureDesc);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
struct MappedBuffer {
|
struct MappedBuffer {
|
||||||
|
@ -465,6 +488,7 @@ namespace dxvk {
|
||||||
D3D11Device* m_device;
|
D3D11Device* m_device;
|
||||||
D3D11_RESOURCE_DIMENSION m_dimension;
|
D3D11_RESOURCE_DIMENSION m_dimension;
|
||||||
D3D11_COMMON_TEXTURE_DESC m_desc;
|
D3D11_COMMON_TEXTURE_DESC m_desc;
|
||||||
|
D3D11_ON_12_RESOURCE_INFO m_11on12;
|
||||||
D3D11_COMMON_TEXTURE_MAP_MODE m_mapMode;
|
D3D11_COMMON_TEXTURE_MAP_MODE m_mapMode;
|
||||||
DXGI_USAGE m_dxgiUsage;
|
DXGI_USAGE m_dxgiUsage;
|
||||||
VkFormat m_packedFormat;
|
VkFormat m_packedFormat;
|
||||||
|
@ -636,7 +660,8 @@ namespace dxvk {
|
||||||
|
|
||||||
D3D11Texture1D(
|
D3D11Texture1D(
|
||||||
D3D11Device* pDevice,
|
D3D11Device* pDevice,
|
||||||
const D3D11_COMMON_TEXTURE_DESC* pDesc);
|
const D3D11_COMMON_TEXTURE_DESC* pDesc,
|
||||||
|
const D3D11_ON_12_RESOURCE_INFO* p11on12Info);
|
||||||
|
|
||||||
~D3D11Texture1D();
|
~D3D11Texture1D();
|
||||||
|
|
||||||
|
@ -682,6 +707,7 @@ namespace dxvk {
|
||||||
D3D11Texture2D(
|
D3D11Texture2D(
|
||||||
D3D11Device* pDevice,
|
D3D11Device* pDevice,
|
||||||
const D3D11_COMMON_TEXTURE_DESC* pDesc,
|
const D3D11_COMMON_TEXTURE_DESC* pDesc,
|
||||||
|
const D3D11_ON_12_RESOURCE_INFO* p11on12Info,
|
||||||
HANDLE hSharedHandle);
|
HANDLE hSharedHandle);
|
||||||
|
|
||||||
D3D11Texture2D(
|
D3D11Texture2D(
|
||||||
|
@ -747,7 +773,8 @@ namespace dxvk {
|
||||||
|
|
||||||
D3D11Texture3D(
|
D3D11Texture3D(
|
||||||
D3D11Device* pDevice,
|
D3D11Device* pDevice,
|
||||||
const D3D11_COMMON_TEXTURE_DESC* pDesc);
|
const D3D11_COMMON_TEXTURE_DESC* pDesc,
|
||||||
|
const D3D11_ON_12_RESOURCE_INFO* p11on12Info);
|
||||||
|
|
||||||
~D3D11Texture3D();
|
~D3D11Texture3D();
|
||||||
|
|
||||||
|
|
|
@ -32,8 +32,11 @@ namespace dxvk {
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::warn("D3D11VideoProcessorEnumerator::QueryInterface: Unknown interface query");
|
if (logQueryInterfaceError(__uuidof(ID3D11VideoProcessorEnumerator), riid)) {
|
||||||
Logger::warn(str::format(riid));
|
Logger::warn("D3D11VideoProcessorEnumerator::QueryInterface: Unknown interface query");
|
||||||
|
Logger::warn(str::format(riid));
|
||||||
|
}
|
||||||
|
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,23 +51,47 @@ namespace dxvk {
|
||||||
HRESULT STDMETHODCALLTYPE D3D11VideoProcessorEnumerator::CheckVideoProcessorFormat(
|
HRESULT STDMETHODCALLTYPE D3D11VideoProcessorEnumerator::CheckVideoProcessorFormat(
|
||||||
DXGI_FORMAT Format,
|
DXGI_FORMAT Format,
|
||||||
UINT* pFlags) {
|
UINT* pFlags) {
|
||||||
Logger::err("D3D11VideoProcessorEnumerator::CheckVideoProcessorFormat: Stub");
|
Logger::err(str::format("D3D11VideoProcessorEnumerator::CheckVideoProcessorFormat: stub, format ", Format));
|
||||||
return E_NOTIMPL;
|
|
||||||
|
if (!pFlags)
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
*pFlags = D3D11_VIDEO_PROCESSOR_FORMAT_SUPPORT_INPUT | D3D11_VIDEO_PROCESSOR_FORMAT_SUPPORT_OUTPUT;
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE D3D11VideoProcessorEnumerator::GetVideoProcessorCaps(
|
HRESULT STDMETHODCALLTYPE D3D11VideoProcessorEnumerator::GetVideoProcessorCaps(
|
||||||
D3D11_VIDEO_PROCESSOR_CAPS* pCaps) {
|
D3D11_VIDEO_PROCESSOR_CAPS* pCaps) {
|
||||||
Logger::err("D3D11VideoProcessorEnumerator::GetVideoProcessorCaps: Stub");
|
Logger::err("D3D11VideoProcessorEnumerator::GetVideoProcessorCaps: semi-stub");
|
||||||
return E_NOTIMPL;
|
|
||||||
|
if (!pCaps)
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
*pCaps = {};
|
||||||
|
pCaps->RateConversionCapsCount = 1;
|
||||||
|
pCaps->MaxInputStreams = 52;
|
||||||
|
pCaps->MaxStreamStates = 52;
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE D3D11VideoProcessorEnumerator::GetVideoProcessorRateConversionCaps(
|
HRESULT STDMETHODCALLTYPE D3D11VideoProcessorEnumerator::GetVideoProcessorRateConversionCaps(
|
||||||
UINT TypeIndex,
|
UINT TypeIndex,
|
||||||
D3D11_VIDEO_PROCESSOR_RATE_CONVERSION_CAPS* pCaps) {
|
D3D11_VIDEO_PROCESSOR_RATE_CONVERSION_CAPS* pCaps) {
|
||||||
Logger::err("D3D11VideoProcessorEnumerator::GetVideoProcessorRateConversionCaps: Stub");
|
Logger::err("D3D11VideoProcessorEnumerator::GetVideoProcessorRateConversionCaps: semi-stub");
|
||||||
return E_NOTIMPL;
|
if (!pCaps || TypeIndex)
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
*pCaps = {};
|
||||||
|
if (m_desc.InputFrameFormat == D3D11_VIDEO_FRAME_FORMAT_PROGRESSIVE) {
|
||||||
|
pCaps->ProcessorCaps = D3D11_VIDEO_PROCESSOR_PROCESSOR_CAPS_FRAME_RATE_CONVERSION;
|
||||||
|
} else {
|
||||||
|
pCaps->ProcessorCaps = D3D11_VIDEO_PROCESSOR_PROCESSOR_CAPS_DEINTERLACE_BOB;
|
||||||
|
pCaps->PastFrames = 1;
|
||||||
|
pCaps->FutureFrames = 1;
|
||||||
|
}
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -112,8 +139,11 @@ namespace dxvk {
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::warn("D3D11VideoProcessor::QueryInterface: Unknown interface query");
|
if (logQueryInterfaceError(__uuidof(ID3D11VideoProcessor), riid)) {
|
||||||
Logger::warn(str::format(riid));
|
Logger::warn("D3D11VideoProcessor::QueryInterface: Unknown interface query");
|
||||||
|
Logger::warn(str::format(riid));
|
||||||
|
}
|
||||||
|
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,8 +253,11 @@ namespace dxvk {
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::warn("D3D11VideoProcessorInputView::QueryInterface: Unknown interface query");
|
if (logQueryInterfaceError(__uuidof(ID3D11VideoProcessorInputView), riid)) {
|
||||||
Logger::warn(str::format(riid));
|
Logger::warn("D3D11VideoProcessorInputView::QueryInterface: Unknown interface query");
|
||||||
|
Logger::warn(str::format(riid));
|
||||||
|
}
|
||||||
|
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,8 +335,11 @@ namespace dxvk {
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::warn("D3D11VideoProcessorOutputView::QueryInterface: Unknown interface query");
|
if (logQueryInterfaceError(__uuidof(ID3D11VideoProcessorOutputView), riid)) {
|
||||||
Logger::warn(str::format(riid));
|
Logger::warn("D3D11VideoProcessorOutputView::QueryInterface: Unknown interface query");
|
||||||
|
Logger::warn(str::format(riid));
|
||||||
|
}
|
||||||
|
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -324,56 +360,8 @@ namespace dxvk {
|
||||||
D3D11VideoContext::D3D11VideoContext(
|
D3D11VideoContext::D3D11VideoContext(
|
||||||
D3D11ImmediateContext* pContext,
|
D3D11ImmediateContext* pContext,
|
||||||
const Rc<DxvkDevice>& Device)
|
const Rc<DxvkDevice>& Device)
|
||||||
: m_ctx(pContext) {
|
: m_ctx(pContext), m_device(Device) {
|
||||||
SpirvCodeBuffer vsCode(d3d11_video_blit_vert);
|
|
||||||
SpirvCodeBuffer fsCode(d3d11_video_blit_frag);
|
|
||||||
|
|
||||||
const std::array<DxvkBindingInfo, 4> fsBindings = {{
|
|
||||||
{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, VK_IMAGE_VIEW_TYPE_MAX_ENUM, VK_SHADER_STAGE_FRAGMENT_BIT, VK_ACCESS_UNIFORM_READ_BIT, VK_TRUE },
|
|
||||||
{ VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_IMAGE_VIEW_TYPE_MAX_ENUM, VK_SHADER_STAGE_FRAGMENT_BIT, 0 },
|
|
||||||
{ VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 2, VK_IMAGE_VIEW_TYPE_2D, VK_SHADER_STAGE_FRAGMENT_BIT, VK_ACCESS_SHADER_READ_BIT },
|
|
||||||
{ VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 3, VK_IMAGE_VIEW_TYPE_2D, VK_SHADER_STAGE_FRAGMENT_BIT, VK_ACCESS_SHADER_READ_BIT },
|
|
||||||
}};
|
|
||||||
|
|
||||||
DxvkShaderCreateInfo vsInfo;
|
|
||||||
vsInfo.stage = VK_SHADER_STAGE_VERTEX_BIT;
|
|
||||||
vsInfo.outputMask = 0x1;
|
|
||||||
m_vs = new DxvkShader(vsInfo, std::move(vsCode));
|
|
||||||
|
|
||||||
DxvkShaderCreateInfo fsInfo;
|
|
||||||
fsInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
|
|
||||||
fsInfo.bindingCount = fsBindings.size();
|
|
||||||
fsInfo.bindings = fsBindings.data();
|
|
||||||
fsInfo.inputMask = 0x1;
|
|
||||||
fsInfo.outputMask = 0x1;
|
|
||||||
m_fs = new DxvkShader(fsInfo, std::move(fsCode));
|
|
||||||
|
|
||||||
DxvkSamplerCreateInfo samplerInfo;
|
|
||||||
samplerInfo.magFilter = VK_FILTER_LINEAR;
|
|
||||||
samplerInfo.minFilter = VK_FILTER_LINEAR;
|
|
||||||
samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
|
|
||||||
samplerInfo.mipmapLodBias = 0.0f;
|
|
||||||
samplerInfo.mipmapLodMin = 0.0f;
|
|
||||||
samplerInfo.mipmapLodMax = 0.0f;
|
|
||||||
samplerInfo.useAnisotropy = VK_FALSE;
|
|
||||||
samplerInfo.maxAnisotropy = 1.0f;
|
|
||||||
samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
|
||||||
samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
|
||||||
samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
|
||||||
samplerInfo.compareToDepth = VK_FALSE;
|
|
||||||
samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS;
|
|
||||||
samplerInfo.reductionMode = VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE;
|
|
||||||
samplerInfo.borderColor = VkClearColorValue();
|
|
||||||
samplerInfo.usePixelCoord = VK_FALSE;
|
|
||||||
samplerInfo.nonSeamless = VK_FALSE;
|
|
||||||
m_sampler = Device->createSampler(samplerInfo);
|
|
||||||
|
|
||||||
DxvkBufferCreateInfo bufferInfo;
|
|
||||||
bufferInfo.size = sizeof(UboData);
|
|
||||||
bufferInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
|
|
||||||
bufferInfo.stages = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
|
|
||||||
bufferInfo.access = VK_ACCESS_UNIFORM_READ_BIT;
|
|
||||||
m_ubo = Device->createBuffer(bufferInfo, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -603,7 +591,9 @@ namespace dxvk {
|
||||||
D3D11_VIDEO_PROCESSOR_OUTPUT_RATE Rate,
|
D3D11_VIDEO_PROCESSOR_OUTPUT_RATE Rate,
|
||||||
BOOL Repeat,
|
BOOL Repeat,
|
||||||
const DXGI_RATIONAL* CustomRate) {
|
const DXGI_RATIONAL* CustomRate) {
|
||||||
Logger::err("D3D11VideoContext::VideoProcessorSetStreamOutputRate: Stub");
|
Logger::err(str::format("D3D11VideoContext::VideoProcessorSetStreamOutputRate: Stub, Rate ", Rate));
|
||||||
|
if (CustomRate)
|
||||||
|
Logger::err(str::format("CustomRate ", CustomRate->Numerator, "/", CustomRate->Denominator));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1200,9 +1190,6 @@ namespace dxvk {
|
||||||
rt.color[0].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
rt.color[0].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||||
|
|
||||||
ctx->bindRenderTargets(std::move(rt), 0u);
|
ctx->bindRenderTargets(std::move(rt), 0u);
|
||||||
ctx->bindShader<VK_SHADER_STAGE_VERTEX_BIT>(Rc<DxvkShader>(m_vs));
|
|
||||||
ctx->bindShader<VK_SHADER_STAGE_FRAGMENT_BIT>(Rc<DxvkShader>(m_fs));
|
|
||||||
ctx->bindUniformBuffer(VK_SHADER_STAGE_FRAGMENT_BIT, 0, DxvkBufferSlice(m_ubo));
|
|
||||||
|
|
||||||
DxvkInputAssemblyState iaState;
|
DxvkInputAssemblyState iaState;
|
||||||
iaState.primitiveTopology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
iaState.primitiveTopology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
||||||
|
@ -1219,6 +1206,8 @@ namespace dxvk {
|
||||||
void D3D11VideoContext::BlitStream(
|
void D3D11VideoContext::BlitStream(
|
||||||
const D3D11VideoProcessorStreamState* pStreamState,
|
const D3D11VideoProcessorStreamState* pStreamState,
|
||||||
const D3D11_VIDEO_PROCESSOR_STREAM* pStream) {
|
const D3D11_VIDEO_PROCESSOR_STREAM* pStream) {
|
||||||
|
CreateResources();
|
||||||
|
|
||||||
if (pStream->PastFrames || pStream->FutureFrames)
|
if (pStream->PastFrames || pStream->FutureFrames)
|
||||||
Logger::err("D3D11VideoContext: Ignoring non-zero PastFrames and FutureFrames");
|
Logger::err("D3D11VideoContext: Ignoring non-zero PastFrames and FutureFrames");
|
||||||
|
|
||||||
|
@ -1273,12 +1262,28 @@ namespace dxvk {
|
||||||
viewport.height = float(cStreamState.dstRect.bottom) - viewport.y;
|
viewport.height = float(cStreamState.dstRect.bottom) - viewport.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VkExtent3D viewExtent = cViews[0]->mipLevelExtent(0);
|
||||||
|
|
||||||
|
VkRect2D srcRect;
|
||||||
|
srcRect.offset = { 0, 0 };
|
||||||
|
srcRect.extent = { viewExtent.width, viewExtent.height };
|
||||||
|
|
||||||
|
if (cStreamState.srcRectEnabled) {
|
||||||
|
srcRect.offset.x = cStreamState.srcRect.left;
|
||||||
|
srcRect.offset.y = cStreamState.srcRect.top;
|
||||||
|
srcRect.extent.width = cStreamState.srcRect.right - srcRect.offset.x;
|
||||||
|
srcRect.extent.height = cStreamState.srcRect.bottom - srcRect.offset.y;
|
||||||
|
}
|
||||||
|
|
||||||
UboData uboData = { };
|
UboData uboData = { };
|
||||||
uboData.colorMatrix[0][0] = 1.0f;
|
uboData.colorMatrix[0][0] = 1.0f;
|
||||||
uboData.colorMatrix[1][1] = 1.0f;
|
uboData.colorMatrix[1][1] = 1.0f;
|
||||||
uboData.colorMatrix[2][2] = 1.0f;
|
uboData.colorMatrix[2][2] = 1.0f;
|
||||||
uboData.coordMatrix[0][0] = 1.0f;
|
uboData.coordMatrix[0][0] = float(srcRect.extent.width) / float(viewExtent.width);
|
||||||
uboData.coordMatrix[1][1] = 1.0f;
|
uboData.coordMatrix[1][1] = float(srcRect.extent.height) / float(viewExtent.height);
|
||||||
|
uboData.coordMatrix[2][0] = float(srcRect.offset.x) / float(viewExtent.width);
|
||||||
|
uboData.coordMatrix[2][1] = float(srcRect.offset.y) / float(viewExtent.height);
|
||||||
|
uboData.srcRect = srcRect;
|
||||||
uboData.yMin = 0.0f;
|
uboData.yMin = 0.0f;
|
||||||
uboData.yMax = 1.0f;
|
uboData.yMax = 1.0f;
|
||||||
uboData.isPlanar = cViews[1] != nullptr;
|
uboData.isPlanar = cViews[1] != nullptr;
|
||||||
|
@ -1296,21 +1301,67 @@ namespace dxvk {
|
||||||
|
|
||||||
ctx->invalidateBuffer(m_ubo, uboSlice);
|
ctx->invalidateBuffer(m_ubo, uboSlice);
|
||||||
ctx->setViewports(1, &viewport, &scissor);
|
ctx->setViewports(1, &viewport, &scissor);
|
||||||
ctx->bindResourceSampler(VK_SHADER_STAGE_FRAGMENT_BIT, 1, Rc<DxvkSampler>(m_sampler));
|
|
||||||
|
ctx->bindShader<VK_SHADER_STAGE_VERTEX_BIT>(Rc<DxvkShader>(m_vs));
|
||||||
|
ctx->bindShader<VK_SHADER_STAGE_FRAGMENT_BIT>(Rc<DxvkShader>(m_fs));
|
||||||
|
|
||||||
|
ctx->bindUniformBuffer(VK_SHADER_STAGE_FRAGMENT_BIT, 0, DxvkBufferSlice(m_ubo));
|
||||||
|
|
||||||
for (uint32_t i = 0; i < cViews.size(); i++)
|
for (uint32_t i = 0; i < cViews.size(); i++)
|
||||||
ctx->bindResourceImageView(VK_SHADER_STAGE_FRAGMENT_BIT, 2 + i, Rc<DxvkImageView>(cViews[i]));
|
ctx->bindResourceImageView(VK_SHADER_STAGE_FRAGMENT_BIT, 1 + i, Rc<DxvkImageView>(cViews[i]));
|
||||||
|
|
||||||
ctx->draw(3, 1, 0, 0);
|
ctx->draw(3, 1, 0, 0);
|
||||||
|
|
||||||
ctx->bindResourceSampler(VK_SHADER_STAGE_FRAGMENT_BIT, 1, nullptr);
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < cViews.size(); i++)
|
for (uint32_t i = 0; i < cViews.size(); i++)
|
||||||
ctx->bindResourceImageView(VK_SHADER_STAGE_FRAGMENT_BIT, 2 + i, nullptr);
|
ctx->bindResourceImageView(VK_SHADER_STAGE_FRAGMENT_BIT, 1 + i, nullptr);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void D3D11VideoContext::CreateUniformBuffer() {
|
||||||
|
DxvkBufferCreateInfo bufferInfo;
|
||||||
|
bufferInfo.size = sizeof(UboData);
|
||||||
|
bufferInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
|
||||||
|
bufferInfo.stages = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
|
||||||
|
bufferInfo.access = VK_ACCESS_UNIFORM_READ_BIT;
|
||||||
|
m_ubo = m_device->createBuffer(bufferInfo, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void D3D11VideoContext::CreateShaders() {
|
||||||
|
SpirvCodeBuffer vsCode(d3d11_video_blit_vert);
|
||||||
|
SpirvCodeBuffer fsCode(d3d11_video_blit_frag);
|
||||||
|
|
||||||
|
const std::array<DxvkBindingInfo, 3> fsBindings = {{
|
||||||
|
{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, VK_IMAGE_VIEW_TYPE_MAX_ENUM, VK_SHADER_STAGE_FRAGMENT_BIT, VK_ACCESS_UNIFORM_READ_BIT, VK_TRUE },
|
||||||
|
{ VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_IMAGE_VIEW_TYPE_2D, VK_SHADER_STAGE_FRAGMENT_BIT, VK_ACCESS_SHADER_READ_BIT },
|
||||||
|
{ VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 2, VK_IMAGE_VIEW_TYPE_2D, VK_SHADER_STAGE_FRAGMENT_BIT, VK_ACCESS_SHADER_READ_BIT },
|
||||||
|
}};
|
||||||
|
|
||||||
|
DxvkShaderCreateInfo vsInfo;
|
||||||
|
vsInfo.stage = VK_SHADER_STAGE_VERTEX_BIT;
|
||||||
|
vsInfo.outputMask = 0x1;
|
||||||
|
m_vs = new DxvkShader(vsInfo, std::move(vsCode));
|
||||||
|
|
||||||
|
DxvkShaderCreateInfo fsInfo;
|
||||||
|
fsInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||||
|
fsInfo.bindingCount = fsBindings.size();
|
||||||
|
fsInfo.bindings = fsBindings.data();
|
||||||
|
fsInfo.inputMask = 0x1;
|
||||||
|
fsInfo.outputMask = 0x1;
|
||||||
|
m_fs = new DxvkShader(fsInfo, std::move(fsCode));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void D3D11VideoContext::CreateResources() {
|
||||||
|
if (std::exchange(m_resourcesCreated, true))
|
||||||
|
return;
|
||||||
|
|
||||||
|
CreateUniformBuffer();
|
||||||
|
CreateShaders();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void D3D11VideoContext::UnbindResources() {
|
void D3D11VideoContext::UnbindResources() {
|
||||||
m_ctx->EmitCs([] (DxvkContext* ctx) {
|
m_ctx->EmitCs([] (DxvkContext* ctx) {
|
||||||
ctx->bindRenderTargets(DxvkRenderTargets(), 0u);
|
ctx->bindRenderTargets(DxvkRenderTargets(), 0u);
|
||||||
|
|
|
@ -584,19 +584,22 @@ namespace dxvk {
|
||||||
struct alignas(16) UboData {
|
struct alignas(16) UboData {
|
||||||
float colorMatrix[3][4];
|
float colorMatrix[3][4];
|
||||||
float coordMatrix[3][2];
|
float coordMatrix[3][2];
|
||||||
|
VkRect2D srcRect;
|
||||||
float yMin, yMax;
|
float yMin, yMax;
|
||||||
VkBool32 isPlanar;
|
VkBool32 isPlanar;
|
||||||
};
|
};
|
||||||
|
|
||||||
D3D11ImmediateContext* m_ctx;
|
D3D11ImmediateContext* m_ctx;
|
||||||
|
|
||||||
Rc<DxvkSampler> m_sampler;
|
Rc<DxvkDevice> m_device;
|
||||||
Rc<DxvkShader> m_vs;
|
Rc<DxvkShader> m_vs;
|
||||||
Rc<DxvkShader> m_fs;
|
Rc<DxvkShader> m_fs;
|
||||||
Rc<DxvkBuffer> m_ubo;
|
Rc<DxvkBuffer> m_ubo;
|
||||||
|
|
||||||
VkExtent2D m_dstExtent = { 0u, 0u };
|
VkExtent2D m_dstExtent = { 0u, 0u };
|
||||||
|
|
||||||
|
bool m_resourcesCreated = false;
|
||||||
|
|
||||||
void ApplyColorMatrix(float pDst[3][4], const float pSrc[3][4]);
|
void ApplyColorMatrix(float pDst[3][4], const float pSrc[3][4]);
|
||||||
|
|
||||||
void ApplyYCbCrMatrix(float pColorMatrix[3][4], bool UseBt709);
|
void ApplyYCbCrMatrix(float pColorMatrix[3][4], bool UseBt709);
|
||||||
|
@ -608,6 +611,12 @@ namespace dxvk {
|
||||||
const D3D11VideoProcessorStreamState* pStreamState,
|
const D3D11VideoProcessorStreamState* pStreamState,
|
||||||
const D3D11_VIDEO_PROCESSOR_STREAM* pStream);
|
const D3D11_VIDEO_PROCESSOR_STREAM* pStream);
|
||||||
|
|
||||||
|
void CreateUniformBuffer();
|
||||||
|
|
||||||
|
void CreateShaders();
|
||||||
|
|
||||||
|
void CreateResources();
|
||||||
|
|
||||||
void UnbindResources();
|
void UnbindResources();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -126,12 +126,15 @@ namespace dxvk {
|
||||||
if (riid == __uuidof(ID3D10DeviceChild)
|
if (riid == __uuidof(ID3D10DeviceChild)
|
||||||
|| riid == __uuidof(ID3D10View)
|
|| riid == __uuidof(ID3D10View)
|
||||||
|| riid == __uuidof(ID3D10DepthStencilView)) {
|
|| riid == __uuidof(ID3D10DepthStencilView)) {
|
||||||
*ppvObject = ref(this);
|
*ppvObject = ref(&m_d3d10);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::warn("D3D11DepthStencilView::QueryInterface: Unknown interface query");
|
if (logQueryInterfaceError(__uuidof(ID3D11DepthStencilView), riid)) {
|
||||||
Logger::warn(str::format(riid));
|
Logger::warn("D3D11DepthStencilView::QueryInterface: Unknown interface query");
|
||||||
|
Logger::warn(str::format(riid));
|
||||||
|
}
|
||||||
|
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,6 +77,10 @@ namespace dxvk {
|
||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DXGI_FORMAT GetViewFormat() const {
|
||||||
|
return m_desc.Format;
|
||||||
|
}
|
||||||
|
|
||||||
D3D10DepthStencilView* GetD3D10Iface() {
|
D3D10DepthStencilView* GetD3D10Iface() {
|
||||||
return &m_d3d10;
|
return &m_d3d10;
|
||||||
}
|
}
|
||||||
|
|
|
@ -137,12 +137,15 @@ namespace dxvk {
|
||||||
if (riid == __uuidof(ID3D10DeviceChild)
|
if (riid == __uuidof(ID3D10DeviceChild)
|
||||||
|| riid == __uuidof(ID3D10View)
|
|| riid == __uuidof(ID3D10View)
|
||||||
|| riid == __uuidof(ID3D10RenderTargetView)) {
|
|| riid == __uuidof(ID3D10RenderTargetView)) {
|
||||||
*ppvObject = ref(this);
|
*ppvObject = ref(&m_d3d10);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::warn("D3D11RenderTargetView::QueryInterface: Unknown interface query");
|
if (logQueryInterfaceError(__uuidof(ID3D11RenderTargetView), riid)) {
|
||||||
Logger::warn(str::format(riid));
|
Logger::warn("D3D11RenderTargetView::QueryInterface: Unknown interface query");
|
||||||
|
Logger::warn(str::format(riid));
|
||||||
|
}
|
||||||
|
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -205,12 +205,15 @@ namespace dxvk {
|
||||||
|| riid == __uuidof(ID3D10View)
|
|| riid == __uuidof(ID3D10View)
|
||||||
|| riid == __uuidof(ID3D10ShaderResourceView)
|
|| riid == __uuidof(ID3D10ShaderResourceView)
|
||||||
|| riid == __uuidof(ID3D10ShaderResourceView1)) {
|
|| riid == __uuidof(ID3D10ShaderResourceView1)) {
|
||||||
*ppvObject = ref(this);
|
*ppvObject = ref(&m_d3d10);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::warn("D3D11ShaderResourceView::QueryInterface: Unknown interface query");
|
if (logQueryInterfaceError(__uuidof(ID3D11ShaderResourceView), riid)) {
|
||||||
Logger::warn(str::format(riid));
|
Logger::warn("D3D11ShaderResourceView::QueryInterface: Unknown interface query");
|
||||||
|
Logger::warn(str::format(riid));
|
||||||
|
}
|
||||||
|
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,7 +298,7 @@ namespace dxvk {
|
||||||
D3D11_BUFFER_DESC bufferDesc;
|
D3D11_BUFFER_DESC bufferDesc;
|
||||||
static_cast<D3D11Buffer*>(pResource)->GetDesc(&bufferDesc);
|
static_cast<D3D11Buffer*>(pResource)->GetDesc(&bufferDesc);
|
||||||
|
|
||||||
if (bufferDesc.MiscFlags == D3D11_RESOURCE_MISC_BUFFER_STRUCTURED) {
|
if (bufferDesc.MiscFlags & D3D11_RESOURCE_MISC_BUFFER_STRUCTURED) {
|
||||||
pDesc->Format = DXGI_FORMAT_UNKNOWN;
|
pDesc->Format = DXGI_FORMAT_UNKNOWN;
|
||||||
pDesc->ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
|
pDesc->ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
|
||||||
pDesc->Buffer.FirstElement = 0;
|
pDesc->Buffer.FirstElement = 0;
|
||||||
|
|
|
@ -147,8 +147,11 @@ namespace dxvk {
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::warn("D3D11UnorderedAccessView::QueryInterface: Unknown interface query");
|
if (logQueryInterfaceError(__uuidof(ID3D11UnorderedAccessView), riid)) {
|
||||||
Logger::warn(str::format(riid));
|
Logger::warn("D3D11UnorderedAccessView::QueryInterface: Unknown interface query");
|
||||||
|
Logger::warn(str::format(riid));
|
||||||
|
}
|
||||||
|
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,7 +214,7 @@ namespace dxvk {
|
||||||
D3D11_BUFFER_DESC bufferDesc;
|
D3D11_BUFFER_DESC bufferDesc;
|
||||||
static_cast<D3D11Buffer*>(pResource)->GetDesc(&bufferDesc);
|
static_cast<D3D11Buffer*>(pResource)->GetDesc(&bufferDesc);
|
||||||
|
|
||||||
if (bufferDesc.MiscFlags == D3D11_RESOURCE_MISC_BUFFER_STRUCTURED) {
|
if (bufferDesc.MiscFlags & D3D11_RESOURCE_MISC_BUFFER_STRUCTURED) {
|
||||||
pDesc->Format = DXGI_FORMAT_UNKNOWN;
|
pDesc->Format = DXGI_FORMAT_UNKNOWN;
|
||||||
pDesc->ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
|
pDesc->ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
|
||||||
pDesc->Buffer.FirstElement = 0;
|
pDesc->Buffer.FirstElement = 0;
|
||||||
|
|
|
@ -42,6 +42,7 @@ d3d11_src = [
|
||||||
'd3d11_input_layout.cpp',
|
'd3d11_input_layout.cpp',
|
||||||
'd3d11_interop.cpp',
|
'd3d11_interop.cpp',
|
||||||
'd3d11_main.cpp',
|
'd3d11_main.cpp',
|
||||||
|
'd3d11_on_12.cpp',
|
||||||
'd3d11_options.cpp',
|
'd3d11_options.cpp',
|
||||||
'd3d11_query.cpp',
|
'd3d11_query.cpp',
|
||||||
'd3d11_rasterizer.cpp',
|
'd3d11_rasterizer.cpp',
|
||||||
|
@ -68,23 +69,33 @@ d3d11_shaders = files([
|
||||||
d3d11_ld_args = []
|
d3d11_ld_args = []
|
||||||
d3d11_link_depends = []
|
d3d11_link_depends = []
|
||||||
|
|
||||||
if platform != 'windows'
|
if platform == 'windows'
|
||||||
|
d3d11_dxgi_dep = lib_dxgi
|
||||||
|
else
|
||||||
d3d11_ld_args += [ '-Wl,--version-script', join_paths(meson.current_source_dir(), 'd3d11.sym') ]
|
d3d11_ld_args += [ '-Wl,--version-script', join_paths(meson.current_source_dir(), 'd3d11.sym') ]
|
||||||
d3d11_link_depends += files('d3d11.sym')
|
d3d11_link_depends += files('d3d11.sym')
|
||||||
|
d3d11_dxgi_dep = dxgi_dep
|
||||||
endif
|
endif
|
||||||
|
|
||||||
d3d11_dll = shared_library('d3d11'+dll_ext, dxgi_common_src + d3d11_src + d3d10_src,
|
d3d11_dll = shared_library(dxvk_name_prefix+'d3d11', dxgi_common_src + d3d11_src + d3d10_src,
|
||||||
glsl_generator.process(d3d11_shaders), d3d11_res,
|
glsl_generator.process(d3d11_shaders), d3d11_res,
|
||||||
name_prefix : dxvk_name_prefix,
|
dependencies : [ d3d11_dxgi_dep, dxbc_dep, dxvk_dep ],
|
||||||
dependencies : [ dxgi_dep, dxbc_dep, dxvk_dep ],
|
|
||||||
include_directories : dxvk_include_path,
|
include_directories : dxvk_include_path,
|
||||||
install : true,
|
install : true,
|
||||||
vs_module_defs : 'd3d11'+def_spec_ext,
|
vs_module_defs : 'd3d11'+def_spec_ext,
|
||||||
link_args : d3d11_ld_args,
|
link_args : d3d11_ld_args,
|
||||||
link_depends : [ d3d11_link_depends ],
|
link_depends : [ d3d11_link_depends ],
|
||||||
|
kwargs : dxvk_so_version,
|
||||||
)
|
)
|
||||||
|
|
||||||
d3d11_dep = declare_dependency(
|
d3d11_dep = declare_dependency(
|
||||||
link_with : [ d3d11_dll ],
|
link_with : [ d3d11_dll ],
|
||||||
include_directories : [ dxvk_include_path ],
|
include_directories : [ dxvk_include_path ],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if platform != 'windows'
|
||||||
|
pkg.generate(d3d11_dll,
|
||||||
|
filebase: dxvk_pkg_prefix + 'd3d11',
|
||||||
|
subdirs: 'dxvk',
|
||||||
|
)
|
||||||
|
endif
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#version 450
|
#version 450
|
||||||
|
|
||||||
|
#extension GL_EXT_samplerless_texture_functions : require
|
||||||
|
|
||||||
// Can't use matrix types here since even a two-row
|
// Can't use matrix types here since even a two-row
|
||||||
// matrix will be padded to 16 bytes per column for
|
// matrix will be padded to 16 bytes per column for
|
||||||
// absolutely no reason
|
// absolutely no reason
|
||||||
|
@ -11,6 +13,8 @@ uniform ubo_t {
|
||||||
vec2 coord_matrix_c1;
|
vec2 coord_matrix_c1;
|
||||||
vec2 coord_matrix_c2;
|
vec2 coord_matrix_c2;
|
||||||
vec2 coord_matrix_c3;
|
vec2 coord_matrix_c3;
|
||||||
|
uvec2 src_offset;
|
||||||
|
uvec2 src_extent;
|
||||||
float y_min;
|
float y_min;
|
||||||
float y_max;
|
float y_max;
|
||||||
bool is_planar;
|
bool is_planar;
|
||||||
|
@ -19,9 +23,8 @@ uniform ubo_t {
|
||||||
layout(location = 0) in vec2 i_texcoord;
|
layout(location = 0) in vec2 i_texcoord;
|
||||||
layout(location = 0) out vec4 o_color;
|
layout(location = 0) out vec4 o_color;
|
||||||
|
|
||||||
layout(set = 0, binding = 1) uniform sampler s_sampler;
|
layout(set = 0, binding = 1) uniform texture2D s_inputY;
|
||||||
layout(set = 0, binding = 2) uniform texture2D s_inputY;
|
layout(set = 0, binding = 2) uniform texture2D s_inputCbCr;
|
||||||
layout(set = 0, binding = 3) uniform texture2D s_inputCbCr;
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
// Transform input texture coordinates to
|
// Transform input texture coordinates to
|
||||||
|
@ -31,25 +34,61 @@ void main() {
|
||||||
coord_matrix_c2,
|
coord_matrix_c2,
|
||||||
coord_matrix_c3);
|
coord_matrix_c3);
|
||||||
|
|
||||||
vec2 coord = coord_matrix * vec3(i_texcoord, 1.0f);
|
// Load color space transform
|
||||||
|
|
||||||
// Fetch source image color
|
|
||||||
vec4 color = vec4(0.0f, 0.0f, 0.0f, 1.0f);
|
|
||||||
|
|
||||||
if (is_planar) {
|
|
||||||
color.g = texture(sampler2D(s_inputY, s_sampler), coord).r;
|
|
||||||
color.rb = texture(sampler2D(s_inputCbCr, s_sampler), coord).gr;
|
|
||||||
color.g = clamp((color.g - y_min) / (y_max - y_min), 0.0f, 1.0f);
|
|
||||||
} else {
|
|
||||||
color = texture(sampler2D(s_inputY, s_sampler), coord);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Color space transformation
|
|
||||||
mat3x4 color_matrix = mat3x4(
|
mat3x4 color_matrix = mat3x4(
|
||||||
color_matrix_r1,
|
color_matrix_r1,
|
||||||
color_matrix_r2,
|
color_matrix_r2,
|
||||||
color_matrix_r3);
|
color_matrix_r3);
|
||||||
|
|
||||||
o_color.rgb = vec4(color.rgb, 1.0f) * color_matrix;
|
// Compute actual pixel coordinates to sample. We filter
|
||||||
o_color.a = color.a;
|
// manually in order to avoid bleeding from pixels outside
|
||||||
|
// the source rectangle.
|
||||||
|
vec2 abs_size_y = vec2(textureSize(s_inputY, 0));
|
||||||
|
vec2 abs_size_c = vec2(textureSize(s_inputCbCr, 0));
|
||||||
|
|
||||||
|
vec2 coord = coord_matrix * vec3(i_texcoord, 1.0f);
|
||||||
|
coord -= 0.5f / abs_size_y;
|
||||||
|
|
||||||
|
vec2 size_factor = abs_size_c / abs_size_y;
|
||||||
|
|
||||||
|
vec2 src_lo = vec2(src_offset);
|
||||||
|
vec2 src_hi = vec2(src_offset + src_extent - 1u);
|
||||||
|
|
||||||
|
vec2 abs_coord = coord * abs_size_y;
|
||||||
|
vec2 fract_coord = fract(clamp(abs_coord, src_lo, src_hi));
|
||||||
|
|
||||||
|
vec4 accum = vec4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
ivec2 offset = ivec2(i & 1, i >> 1);
|
||||||
|
|
||||||
|
// Compute exact pixel coordinates for the current
|
||||||
|
// iteration and clamp it to the source rectangle.
|
||||||
|
vec2 fetch_coord = clamp(abs_coord + vec2(offset), src_lo, src_hi);
|
||||||
|
|
||||||
|
// Fetch actual pixel color in source color space
|
||||||
|
vec4 color;
|
||||||
|
|
||||||
|
if (is_planar) {
|
||||||
|
color.g = texelFetch(s_inputY, ivec2(fetch_coord), 0).r;
|
||||||
|
color.rb = texelFetch(s_inputCbCr, ivec2(fetch_coord * size_factor), 0).gr;
|
||||||
|
color.g = clamp((color.g - y_min) / (y_max - y_min), 0.0f, 1.0f);
|
||||||
|
color.a = 1.0f;
|
||||||
|
} else {
|
||||||
|
color = texelFetch(s_inputY, ivec2(fetch_coord), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transform color space before accumulation
|
||||||
|
color.rgb = vec4(color.rgb, 1.0f) * color_matrix;
|
||||||
|
|
||||||
|
// Filter and accumulate final pixel color
|
||||||
|
vec2 factor = fract_coord;
|
||||||
|
|
||||||
|
if (offset.x == 0) factor.x = 1.0f - factor.x;
|
||||||
|
if (offset.y == 0) factor.y = 1.0f - factor.y;
|
||||||
|
|
||||||
|
accum += factor.x * factor.y * color;
|
||||||
|
}
|
||||||
|
|
||||||
|
o_color = accum;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,3 +25,6 @@ EXPORTS
|
||||||
DXVK_UnRegisterAnnotation @28258 NONAME
|
DXVK_UnRegisterAnnotation @28258 NONAME
|
||||||
|
|
||||||
Direct3D9ForceHybridEnumeration @16 NONAME PRIVATE
|
Direct3D9ForceHybridEnumeration @16 NONAME PRIVATE
|
||||||
|
|
||||||
|
Direct3DCreate9On12 @20
|
||||||
|
Direct3DCreate9On12Ex @21
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
DXVK_RegisterAnnotation;
|
DXVK_RegisterAnnotation;
|
||||||
DXVK_UnRegisterAnnotation;
|
DXVK_UnRegisterAnnotation;
|
||||||
Direct3D9ForceHybridEnumeration;
|
Direct3D9ForceHybridEnumeration;
|
||||||
|
Direct3DCreate9On12;
|
||||||
|
Direct3DCreate9On12Ex;
|
||||||
|
|
||||||
local:
|
local:
|
||||||
*;
|
*;
|
||||||
|
|
|
@ -162,6 +162,9 @@ namespace dxvk {
|
||||||
if (mapping.FormatSrgb == VK_FORMAT_UNDEFINED && srgb)
|
if (mapping.FormatSrgb == VK_FORMAT_UNDEFINED && srgb)
|
||||||
return D3DERR_NOTAVAILABLE;
|
return D3DERR_NOTAVAILABLE;
|
||||||
|
|
||||||
|
if (RType == D3DRTYPE_CUBETEXTURE && mapping.Aspect != VK_IMAGE_ASPECT_COLOR_BIT)
|
||||||
|
return D3DERR_NOTAVAILABLE;
|
||||||
|
|
||||||
if (RType == D3DRTYPE_VERTEXBUFFER || RType == D3DRTYPE_INDEXBUFFER)
|
if (RType == D3DRTYPE_VERTEXBUFFER || RType == D3DRTYPE_INDEXBUFFER)
|
||||||
return D3D_OK;
|
return D3D_OK;
|
||||||
|
|
||||||
|
@ -224,11 +227,15 @@ namespace dxvk {
|
||||||
if (!IsDepthFormat(DepthStencilFormat))
|
if (!IsDepthFormat(DepthStencilFormat))
|
||||||
return D3DERR_NOTAVAILABLE;
|
return D3DERR_NOTAVAILABLE;
|
||||||
|
|
||||||
|
auto dsfMapping = ConvertFormatUnfixed(DepthStencilFormat);
|
||||||
|
if (dsfMapping.FormatColor == VK_FORMAT_UNDEFINED)
|
||||||
|
return D3DERR_NOTAVAILABLE;
|
||||||
|
|
||||||
if (RenderTargetFormat == dxvk::D3D9Format::NULL_FORMAT)
|
if (RenderTargetFormat == dxvk::D3D9Format::NULL_FORMAT)
|
||||||
return D3D_OK;
|
return D3D_OK;
|
||||||
|
|
||||||
auto mapping = ConvertFormatUnfixed(RenderTargetFormat);
|
auto rtfMapping = ConvertFormatUnfixed(RenderTargetFormat);
|
||||||
if (mapping.FormatColor == VK_FORMAT_UNDEFINED)
|
if (rtfMapping.FormatColor == VK_FORMAT_UNDEFINED)
|
||||||
return D3DERR_NOTAVAILABLE;
|
return D3DERR_NOTAVAILABLE;
|
||||||
|
|
||||||
return D3D_OK;
|
return D3D_OK;
|
||||||
|
@ -529,7 +536,7 @@ namespace dxvk {
|
||||||
// Max Vertex Blend Matrices
|
// Max Vertex Blend Matrices
|
||||||
pCaps->MaxVertexBlendMatrices = 4;
|
pCaps->MaxVertexBlendMatrices = 4;
|
||||||
// Max Vertex Blend Matrix Index
|
// Max Vertex Blend Matrix Index
|
||||||
pCaps->MaxVertexBlendMatrixIndex = 8;
|
pCaps->MaxVertexBlendMatrixIndex = 0;
|
||||||
// Max Point Size
|
// Max Point Size
|
||||||
pCaps->MaxPointSize = 256.0f;
|
pCaps->MaxPointSize = 256.0f;
|
||||||
// Max Primitive Count
|
// Max Primitive Count
|
||||||
|
@ -788,7 +795,8 @@ namespace dxvk {
|
||||||
// Fix up the D3DFORMAT to match what we are enumerating
|
// Fix up the D3DFORMAT to match what we are enumerating
|
||||||
mode.Format = static_cast<D3DFORMAT>(Format);
|
mode.Format = static_cast<D3DFORMAT>(Format);
|
||||||
|
|
||||||
m_modes.push_back(mode);
|
if (std::count(m_modes.begin(), m_modes.end(), mode) == 0)
|
||||||
|
m_modes.push_back(mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort display modes by width, height and refresh rate,
|
// Sort display modes by width, height and refresh rate,
|
||||||
|
|
|
@ -2,8 +2,11 @@
|
||||||
|
|
||||||
#include "d3d9_device.h"
|
#include "d3d9_device.h"
|
||||||
#include "d3d9_include.h"
|
#include "d3d9_include.h"
|
||||||
|
|
||||||
#include "../dxvk/dxvk_annotation.h"
|
#include "../dxvk/dxvk_annotation.h"
|
||||||
|
|
||||||
|
#include "../util/thread.h"
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -43,7 +46,7 @@ namespace dxvk {
|
||||||
|
|
||||||
std::atomic<bool> m_shouldAnnotate;
|
std::atomic<bool> m_shouldAnnotate;
|
||||||
|
|
||||||
std::mutex m_mutex;
|
dxvk::mutex m_mutex;
|
||||||
std::vector<IDXVKUserDefinedAnnotation*> m_annotations;
|
std::vector<IDXVKUserDefinedAnnotation*> m_annotations;
|
||||||
|
|
||||||
// Provide our own event depth as we
|
// Provide our own event depth as we
|
||||||
|
|
|
@ -0,0 +1,111 @@
|
||||||
|
|
||||||
|
#include "d3d9_device.h"
|
||||||
|
#include "d3d9_interface.h"
|
||||||
|
#include "d3d9_bridge.h"
|
||||||
|
#include "d3d9_swapchain.h"
|
||||||
|
#include "d3d9_surface.h"
|
||||||
|
|
||||||
|
namespace dxvk {
|
||||||
|
|
||||||
|
DxvkD3D8Bridge::DxvkD3D8Bridge(D3D9DeviceEx* pDevice)
|
||||||
|
: m_device(pDevice) {
|
||||||
|
}
|
||||||
|
|
||||||
|
DxvkD3D8Bridge::~DxvkD3D8Bridge() {
|
||||||
|
}
|
||||||
|
|
||||||
|
ULONG STDMETHODCALLTYPE DxvkD3D8Bridge::AddRef() {
|
||||||
|
return m_device->AddRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
ULONG STDMETHODCALLTYPE DxvkD3D8Bridge::Release() {
|
||||||
|
return m_device->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT STDMETHODCALLTYPE DxvkD3D8Bridge::QueryInterface(
|
||||||
|
REFIID riid,
|
||||||
|
void** ppvObject) {
|
||||||
|
return m_device->QueryInterface(riid, ppvObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DxvkD3D8Bridge::SetAPIName(const char* name) {
|
||||||
|
m_device->m_implicitSwapchain->SetApiName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DxvkD3D8Bridge::SetD3D8CompatibilityMode(const bool compatMode) {
|
||||||
|
m_device->SetD3D8CompatibilityMode(compatMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT DxvkD3D8Bridge::UpdateTextureFromBuffer(
|
||||||
|
IDirect3DSurface9* pDestSurface,
|
||||||
|
IDirect3DSurface9* pSrcSurface,
|
||||||
|
const RECT* pSrcRect,
|
||||||
|
const POINT* pDestPoint) {
|
||||||
|
auto lock = m_device->LockDevice();
|
||||||
|
|
||||||
|
D3D9Surface* dst = static_cast<D3D9Surface*>(pDestSurface);
|
||||||
|
D3D9Surface* src = static_cast<D3D9Surface*>(pSrcSurface);
|
||||||
|
|
||||||
|
if (unlikely(dst == nullptr || src == nullptr))
|
||||||
|
return D3DERR_INVALIDCALL;
|
||||||
|
|
||||||
|
D3D9CommonTexture* srcTextureInfo = src->GetCommonTexture();
|
||||||
|
D3D9CommonTexture* dstTextureInfo = dst->GetCommonTexture();
|
||||||
|
|
||||||
|
VkOffset3D srcOffset = { 0u, 0u, 0u };
|
||||||
|
VkOffset3D dstOffset = { 0u, 0u, 0u };
|
||||||
|
VkExtent3D texLevelExtent = srcTextureInfo->GetExtentMip(src->GetSubresource());
|
||||||
|
VkExtent3D extent = texLevelExtent;
|
||||||
|
|
||||||
|
srcOffset = { pSrcRect->left,
|
||||||
|
pSrcRect->top,
|
||||||
|
0u };
|
||||||
|
|
||||||
|
extent = { uint32_t(pSrcRect->right - pSrcRect->left), uint32_t(pSrcRect->bottom - pSrcRect->top), 1 };
|
||||||
|
|
||||||
|
// TODO: Validate extents like in D3D9DeviceEx::UpdateSurface
|
||||||
|
|
||||||
|
dstOffset = { pDestPoint->x,
|
||||||
|
pDestPoint->y,
|
||||||
|
0u };
|
||||||
|
|
||||||
|
|
||||||
|
m_device->UpdateTextureFromBuffer(
|
||||||
|
srcTextureInfo, dstTextureInfo,
|
||||||
|
src->GetSubresource(), dst->GetSubresource(),
|
||||||
|
srcOffset, extent, dstOffset
|
||||||
|
);
|
||||||
|
|
||||||
|
dstTextureInfo->SetNeedsReadback(dst->GetSubresource(), true);
|
||||||
|
|
||||||
|
if (dstTextureInfo->IsAutomaticMip())
|
||||||
|
m_device->MarkTextureMipsDirty(dstTextureInfo);
|
||||||
|
|
||||||
|
return D3D_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
DxvkD3D8InterfaceBridge::DxvkD3D8InterfaceBridge(D3D9InterfaceEx* pObject)
|
||||||
|
: m_interface(pObject) {
|
||||||
|
}
|
||||||
|
|
||||||
|
DxvkD3D8InterfaceBridge::~DxvkD3D8InterfaceBridge() {
|
||||||
|
}
|
||||||
|
|
||||||
|
ULONG STDMETHODCALLTYPE DxvkD3D8InterfaceBridge::AddRef() {
|
||||||
|
return m_interface->AddRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
ULONG STDMETHODCALLTYPE DxvkD3D8InterfaceBridge::Release() {
|
||||||
|
return m_interface->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT STDMETHODCALLTYPE DxvkD3D8InterfaceBridge::QueryInterface(
|
||||||
|
REFIID riid,
|
||||||
|
void** ppvObject) {
|
||||||
|
return m_interface->QueryInterface(riid, ppvObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Config* DxvkD3D8InterfaceBridge::GetConfig() const {
|
||||||
|
return &m_interface->GetInstance()->config();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,118 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include "../util/config/config.h"
|
||||||
|
|
||||||
|
#include "../vulkan/vulkan_loader.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The D3D9 bridge allows D3D8 to access DXVK internals.
|
||||||
|
* For Vulkan interop without needing DXVK internals, see d3d9_interop.h.
|
||||||
|
*
|
||||||
|
* NOTE: You must include "d3d9_include.h" or "d3d8_include.h" before this header.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief D3D9 device interface for D3D8 interop
|
||||||
|
*/
|
||||||
|
MIDL_INTERFACE("D3D9D3D8-42A9-4C1E-AA97-BEEFCAFE2000")
|
||||||
|
IDxvkD3D8Bridge : public IUnknown {
|
||||||
|
|
||||||
|
// D3D8 keeps D3D9 objects contained in a namespace.
|
||||||
|
#ifdef DXVK_D3D9_NAMESPACE
|
||||||
|
using IDirect3DSurface9 = d3d9::IDirect3DSurface9;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Changes the API name displayed on the HUD
|
||||||
|
*
|
||||||
|
* \param [in] name The new API name
|
||||||
|
*/
|
||||||
|
virtual void SetAPIName(const char* name) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Enables or disables D3D9-specific device features and validations
|
||||||
|
*
|
||||||
|
* \param [in] compatibility state
|
||||||
|
*/
|
||||||
|
virtual void SetD3D8CompatibilityMode(const bool compatMode) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Updates a D3D9 surface from a D3D9 buffer
|
||||||
|
*
|
||||||
|
* \param [in] pDestSurface Destination surface (typically in VRAM)
|
||||||
|
* \param [in] pSrcSurface Source surface (typically in system memory)
|
||||||
|
* \param [in] pSrcRect Source rectangle
|
||||||
|
* \param [in] pDestPoint Destination (top-left) point
|
||||||
|
*/
|
||||||
|
virtual HRESULT UpdateTextureFromBuffer(
|
||||||
|
IDirect3DSurface9* pDestSurface,
|
||||||
|
IDirect3DSurface9* pSrcSurface,
|
||||||
|
const RECT* pSrcRect,
|
||||||
|
const POINT* pDestPoint) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief D3D9 instance interface for D3D8 interop
|
||||||
|
*/
|
||||||
|
MIDL_INTERFACE("D3D9D3D8-A407-773E-18E9-CAFEBEEF3000")
|
||||||
|
IDxvkD3D8InterfaceBridge : public IUnknown {
|
||||||
|
/**
|
||||||
|
* \brief Retrieves the DXVK configuration
|
||||||
|
*
|
||||||
|
* \returns The DXVK Config object
|
||||||
|
*/
|
||||||
|
virtual const dxvk::Config* GetConfig() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef _MSC_VER
|
||||||
|
__CRT_UUID_DECL(IDxvkD3D8Bridge, 0xD3D9D3D8, 0x42A9, 0x4C1E, 0xAA, 0x97, 0xBE, 0xEF, 0xCA, 0xFE, 0x20, 0x00);
|
||||||
|
__CRT_UUID_DECL(IDxvkD3D8InterfaceBridge, 0xD3D9D3D8, 0xA407, 0x773E, 0x18, 0xE9, 0xCA, 0xFE, 0xBE, 0xEF, 0x30, 0x00);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace dxvk {
|
||||||
|
|
||||||
|
class D3D9DeviceEx;
|
||||||
|
class D3D9InterfaceEx;
|
||||||
|
|
||||||
|
class DxvkD3D8Bridge : public IDxvkD3D8Bridge {
|
||||||
|
public:
|
||||||
|
DxvkD3D8Bridge(D3D9DeviceEx* pDevice);
|
||||||
|
~DxvkD3D8Bridge();
|
||||||
|
|
||||||
|
ULONG STDMETHODCALLTYPE AddRef();
|
||||||
|
ULONG STDMETHODCALLTYPE Release();
|
||||||
|
HRESULT STDMETHODCALLTYPE QueryInterface(
|
||||||
|
REFIID riid,
|
||||||
|
void** ppvObject);
|
||||||
|
|
||||||
|
void SetAPIName(const char* name);
|
||||||
|
void SetD3D8CompatibilityMode(const bool compatMode);
|
||||||
|
|
||||||
|
HRESULT UpdateTextureFromBuffer(
|
||||||
|
IDirect3DSurface9* pDestSurface,
|
||||||
|
IDirect3DSurface9* pSrcSurface,
|
||||||
|
const RECT* pSrcRect,
|
||||||
|
const POINT* pDestPoint);
|
||||||
|
|
||||||
|
private:
|
||||||
|
D3D9DeviceEx* m_device;
|
||||||
|
};
|
||||||
|
|
||||||
|
class DxvkD3D8InterfaceBridge : public IDxvkD3D8InterfaceBridge {
|
||||||
|
public:
|
||||||
|
DxvkD3D8InterfaceBridge(D3D9InterfaceEx* pObject);
|
||||||
|
~DxvkD3D8InterfaceBridge();
|
||||||
|
|
||||||
|
ULONG STDMETHODCALLTYPE AddRef();
|
||||||
|
ULONG STDMETHODCALLTYPE Release();
|
||||||
|
HRESULT STDMETHODCALLTYPE QueryInterface(
|
||||||
|
REFIID riid,
|
||||||
|
void** ppvObject);
|
||||||
|
|
||||||
|
const Config* GetConfig() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
D3D9InterfaceEx* m_interface;
|
||||||
|
};
|
||||||
|
}
|
|
@ -29,8 +29,11 @@ namespace dxvk {
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::warn("D3D9VertexBuffer::QueryInterface: Unknown interface query");
|
if (logQueryInterfaceError(__uuidof(IDirect3DVertexBuffer9), riid)) {
|
||||||
Logger::warn(str::format(riid));
|
Logger::warn("D3D9VertexBuffer::QueryInterface: Unknown interface query");
|
||||||
|
Logger::warn(str::format(riid));
|
||||||
|
}
|
||||||
|
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,8 +89,11 @@ namespace dxvk {
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::warn("D3D9IndexBuffer::QueryInterface: Unknown interface query");
|
if (logQueryInterfaceError(__uuidof(IDirect3DIndexBuffer9), riid)) {
|
||||||
Logger::warn(str::format(riid));
|
Logger::warn("D3D9IndexBuffer::QueryInterface: Unknown interface query");
|
||||||
|
Logger::warn(str::format(riid));
|
||||||
|
}
|
||||||
|
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,11 @@ namespace dxvk {
|
||||||
m_dirtyRange = D3D9Range(0, m_desc.Size);
|
m_dirtyRange = D3D9Range(0, m_desc.Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
D3D9CommonBuffer::~D3D9CommonBuffer() {
|
||||||
|
if (m_desc.Pool == D3DPOOL_DEFAULT)
|
||||||
|
m_parent->DecrementLosableCounter();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
HRESULT D3D9CommonBuffer::Lock(
|
HRESULT D3D9CommonBuffer::Lock(
|
||||||
UINT OffsetToLock,
|
UINT OffsetToLock,
|
||||||
|
@ -57,6 +62,32 @@ namespace dxvk {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
D3D9_COMMON_BUFFER_MAP_MODE D3D9CommonBuffer::DetermineMapMode(const D3D9Options* options) const {
|
||||||
|
if (m_desc.Pool != D3DPOOL_DEFAULT)
|
||||||
|
return D3D9_COMMON_BUFFER_MAP_MODE_BUFFER;
|
||||||
|
|
||||||
|
// CSGO keeps vertex buffers locked across multiple frames and writes to it. It uses them for drawing without unlocking first.
|
||||||
|
// Tests show that D3D9 DEFAULT + USAGE_DYNAMIC behaves like a directly mapped buffer even when unlocked.
|
||||||
|
// DEFAULT + WRITEONLY does not behave like a directly mapped buffer EXCEPT if its locked at the moment.
|
||||||
|
// That's annoying to implement so we just always directly map DEFAULT + WRITEONLY.
|
||||||
|
if (!(m_desc.Usage & (D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY)))
|
||||||
|
return D3D9_COMMON_BUFFER_MAP_MODE_BUFFER;
|
||||||
|
|
||||||
|
// Tests show that DISCARD does not work for pure SWVP devices.
|
||||||
|
// So force staging buffer path to avoid stalls.
|
||||||
|
// Dark Romance: Vampire in Love also expects draws to be synchronous
|
||||||
|
// and breaks if we respect NOOVERWRITE.
|
||||||
|
// D&D Temple of Elemental Evil breaks if we respect DISCARD.
|
||||||
|
if (m_parent->CanOnlySWVP())
|
||||||
|
return D3D9_COMMON_BUFFER_MAP_MODE_BUFFER;
|
||||||
|
|
||||||
|
if (!options->allowDirectBufferMapping)
|
||||||
|
return D3D9_COMMON_BUFFER_MAP_MODE_BUFFER;
|
||||||
|
|
||||||
|
return D3D9_COMMON_BUFFER_MAP_MODE_DIRECT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Rc<DxvkBuffer> D3D9CommonBuffer::CreateBuffer() const {
|
Rc<DxvkBuffer> D3D9CommonBuffer::CreateBuffer() const {
|
||||||
DxvkBufferCreateInfo info;
|
DxvkBufferCreateInfo info;
|
||||||
|
@ -103,7 +134,8 @@ namespace dxvk {
|
||||||
memoryFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
|
memoryFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (memoryFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT && m_parent->GetOptions()->apitraceMode) {
|
if ((memoryFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) && m_parent->GetOptions()->cachedDynamicBuffers) {
|
||||||
|
memoryFlags &= ~VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
|
||||||
memoryFlags |= VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
|
memoryFlags |= VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
|
||||||
| VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
|
| VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,6 +78,8 @@ namespace dxvk {
|
||||||
D3D9DeviceEx* pDevice,
|
D3D9DeviceEx* pDevice,
|
||||||
const D3D9_BUFFER_DESC* pDesc);
|
const D3D9_BUFFER_DESC* pDesc);
|
||||||
|
|
||||||
|
~D3D9CommonBuffer();
|
||||||
|
|
||||||
HRESULT Lock(
|
HRESULT Lock(
|
||||||
UINT OffsetToLock,
|
UINT OffsetToLock,
|
||||||
UINT SizeToLock,
|
UINT SizeToLock,
|
||||||
|
@ -89,11 +91,7 @@ namespace dxvk {
|
||||||
/**
|
/**
|
||||||
* \brief Determine the mapping mode of the buffer, (ie. direct mapping or backed)
|
* \brief Determine the mapping mode of the buffer, (ie. direct mapping or backed)
|
||||||
*/
|
*/
|
||||||
inline D3D9_COMMON_BUFFER_MAP_MODE DetermineMapMode(const D3D9Options* options) const {
|
D3D9_COMMON_BUFFER_MAP_MODE DetermineMapMode(const D3D9Options* options) const;
|
||||||
return (m_desc.Pool == D3DPOOL_DEFAULT && (m_desc.Usage & (D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY)) && options->allowDirectBufferMapping)
|
|
||||||
? D3D9_COMMON_BUFFER_MAP_MODE_DIRECT
|
|
||||||
: D3D9_COMMON_BUFFER_MAP_MODE_BUFFER;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Get the mapping mode of the buffer, (ie. direct mapping or backed)
|
* \brief Get the mapping mode of the buffer, (ie. direct mapping or backed)
|
||||||
|
@ -127,7 +125,12 @@ namespace dxvk {
|
||||||
|
|
||||||
template <D3D9_COMMON_BUFFER_TYPE Type>
|
template <D3D9_COMMON_BUFFER_TYPE Type>
|
||||||
inline DxvkBufferSlice GetBufferSlice(VkDeviceSize offset, VkDeviceSize length) const {
|
inline DxvkBufferSlice GetBufferSlice(VkDeviceSize offset, VkDeviceSize length) const {
|
||||||
return DxvkBufferSlice(GetBuffer<Type>(), offset, length);
|
if (likely(length && offset < m_desc.Size)) {
|
||||||
|
return DxvkBufferSlice(GetBuffer<Type>(), offset,
|
||||||
|
std::min<VkDeviceSize>(m_desc.Size - offset, length));
|
||||||
|
}
|
||||||
|
|
||||||
|
return DxvkBufferSlice();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline DxvkBufferSliceHandle AllocMapSlice() {
|
inline DxvkBufferSliceHandle AllocMapSlice() {
|
||||||
|
@ -208,6 +211,10 @@ namespace dxvk {
|
||||||
: DxvkCsThread::SynchronizeAll;
|
: DxvkCsThread::SynchronizeAll;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsSysmemDynamic() const {
|
||||||
|
return m_desc.Pool == D3DPOOL_SYSTEMMEM && (m_desc.Usage & D3DUSAGE_DYNAMIC) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Rc<DxvkBuffer> CreateBuffer() const;
|
Rc<DxvkBuffer> CreateBuffer() const;
|
||||||
|
@ -227,7 +234,7 @@ namespace dxvk {
|
||||||
|
|
||||||
D3D9DeviceEx* m_parent;
|
D3D9DeviceEx* m_parent;
|
||||||
const D3D9_BUFFER_DESC m_desc;
|
const D3D9_BUFFER_DESC m_desc;
|
||||||
DWORD m_mapFlags;
|
DWORD m_mapFlags = 0;
|
||||||
bool m_needsReadback = false;
|
bool m_needsReadback = false;
|
||||||
D3D9_COMMON_BUFFER_MAP_MODE m_mapMode;
|
D3D9_COMMON_BUFFER_MAP_MODE m_mapMode;
|
||||||
|
|
||||||
|
|
|
@ -31,11 +31,12 @@ namespace dxvk {
|
||||||
AddDirtyBox(nullptr, i);
|
AddDirtyBox(nullptr, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_desc.Pool != D3DPOOL_DEFAULT) {
|
if (m_desc.Pool != D3DPOOL_DEFAULT && pSharedHandle) {
|
||||||
|
throw DxvkError("D3D9: Incompatible pool type for texture sharing.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsPoolManaged(m_desc.Pool)) {
|
||||||
SetAllNeedUpload();
|
SetAllNeedUpload();
|
||||||
if (pSharedHandle) {
|
|
||||||
throw DxvkError("D3D9: Incompatible pool type for texture sharing.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_mapping = pDevice->LookupFormat(m_desc.Format);
|
m_mapping = pDevice->LookupFormat(m_desc.Format);
|
||||||
|
@ -98,6 +99,9 @@ namespace dxvk {
|
||||||
m_device->ChangeReportedMemory(m_size);
|
m_device->ChangeReportedMemory(m_size);
|
||||||
|
|
||||||
m_device->RemoveMappedTexture(this);
|
m_device->RemoveMappedTexture(this);
|
||||||
|
|
||||||
|
if (m_desc.Pool == D3DPOOL_DEFAULT)
|
||||||
|
m_device->DecrementLosableCounter();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -114,6 +118,7 @@ namespace dxvk {
|
||||||
|
|
||||||
HRESULT D3D9CommonTexture::NormalizeTextureProperties(
|
HRESULT D3D9CommonTexture::NormalizeTextureProperties(
|
||||||
D3D9DeviceEx* pDevice,
|
D3D9DeviceEx* pDevice,
|
||||||
|
D3DRESOURCETYPE ResourceType,
|
||||||
D3D9_COMMON_TEXTURE_DESC* pDesc) {
|
D3D9_COMMON_TEXTURE_DESC* pDesc) {
|
||||||
auto* options = pDevice->GetOptions();
|
auto* options = pDevice->GetOptions();
|
||||||
|
|
||||||
|
@ -127,6 +132,11 @@ namespace dxvk {
|
||||||
options->disableA8RT)
|
options->disableA8RT)
|
||||||
return D3DERR_INVALIDCALL;
|
return D3DERR_INVALIDCALL;
|
||||||
|
|
||||||
|
// Cube textures with depth formats are not supported on any native
|
||||||
|
// driver, and allowing them triggers a broken code path in Gothic 3.
|
||||||
|
if (ResourceType == D3DRTYPE_CUBETEXTURE && mapping.Aspect != VK_IMAGE_ASPECT_COLOR_BIT)
|
||||||
|
return D3DERR_INVALIDCALL;
|
||||||
|
|
||||||
// If the mapping is invalid then lets return invalid
|
// If the mapping is invalid then lets return invalid
|
||||||
// Some edge cases:
|
// Some edge cases:
|
||||||
// NULL format does not map to anything, but should succeed
|
// NULL format does not map to anything, but should succeed
|
||||||
|
@ -238,13 +248,21 @@ namespace dxvk {
|
||||||
const VkExtent3D mipExtent = util::computeMipLevelExtent(
|
const VkExtent3D mipExtent = util::computeMipLevelExtent(
|
||||||
GetExtent(), MipLevel);
|
GetExtent(), MipLevel);
|
||||||
|
|
||||||
|
VkExtent3D blockSize = formatInfo->blockSize;
|
||||||
|
uint32_t elementSize = formatInfo->elementSize;
|
||||||
|
if (unlikely(formatInfo->flags.test(DxvkFormatFlag::MultiPlane))) {
|
||||||
|
// D3D9 doesn't allow specifying the plane when locking a texture.
|
||||||
|
// So the subsampled planes inherit the pitch of the first plane.
|
||||||
|
// That means the size is the size of plane 0 * plane count
|
||||||
|
elementSize = formatInfo->planes[0].elementSize;
|
||||||
|
blockSize = { formatInfo->planes[0].blockSize.width, formatInfo->planes[0].blockSize.height, 1u };
|
||||||
|
}
|
||||||
|
|
||||||
const VkExtent3D blockCount = util::computeBlockCount(
|
const VkExtent3D blockCount = util::computeBlockCount(
|
||||||
mipExtent, formatInfo->blockSize);
|
mipExtent, blockSize);
|
||||||
|
|
||||||
const uint32_t planeCount = m_mapping.ConversionFormatInfo.PlaneCount;
|
return std::min(GetPlaneCount(), 2u)
|
||||||
|
* align(elementSize * blockCount.width, 4)
|
||||||
return std::min(planeCount, 2u)
|
|
||||||
* align(formatInfo->elementSize * blockCount.width, 4)
|
|
||||||
* blockCount.height
|
* blockCount.height
|
||||||
* blockCount.depth;
|
* blockCount.depth;
|
||||||
}
|
}
|
||||||
|
@ -356,7 +374,7 @@ namespace dxvk {
|
||||||
if (!CheckImageSupport(&imageInfo, imageInfo.tiling)) {
|
if (!CheckImageSupport(&imageInfo, imageInfo.tiling)) {
|
||||||
throw DxvkError(str::format(
|
throw DxvkError(str::format(
|
||||||
"D3D9: Cannot create texture:",
|
"D3D9: Cannot create texture:",
|
||||||
"\n Type: ", std::hex, ResourceType,
|
"\n Type: 0x", std::hex, ResourceType, std::dec,
|
||||||
"\n Format: ", m_desc.Format,
|
"\n Format: ", m_desc.Format,
|
||||||
"\n Extent: ", m_desc.Width,
|
"\n Extent: ", m_desc.Width,
|
||||||
"x", m_desc.Height,
|
"x", m_desc.Height,
|
||||||
|
@ -364,8 +382,8 @@ namespace dxvk {
|
||||||
"\n Samples: ", m_desc.MultiSample,
|
"\n Samples: ", m_desc.MultiSample,
|
||||||
"\n Layers: ", m_desc.ArraySize,
|
"\n Layers: ", m_desc.ArraySize,
|
||||||
"\n Levels: ", m_desc.MipLevels,
|
"\n Levels: ", m_desc.MipLevels,
|
||||||
"\n Usage: ", std::hex, m_desc.Usage,
|
"\n Usage: 0x", std::hex, m_desc.Usage, std::dec,
|
||||||
"\n Pool: ", std::hex, m_desc.Pool));
|
"\n Pool: 0x", std::hex, m_desc.Pool, std::dec));
|
||||||
}
|
}
|
||||||
|
|
||||||
return m_device->GetDXVKDevice()->createImage(imageInfo, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
return m_device->GetDXVKDevice()->createImage(imageInfo, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
||||||
|
@ -675,4 +693,13 @@ namespace dxvk {
|
||||||
return DxvkBufferSlice(GetBuffer(), m_memoryOffset[Subresource], GetMipSize(Subresource));
|
return DxvkBufferSlice(GetBuffer(), m_memoryOffset[Subresource], GetMipSize(Subresource));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t D3D9CommonTexture::GetPlaneCount() const {
|
||||||
|
const DxvkFormatInfo* formatInfo = m_mapping.FormatColor != VK_FORMAT_UNDEFINED
|
||||||
|
? lookupFormatInfo(m_mapping.FormatColor)
|
||||||
|
: m_device->UnsupportedFormatInfo(m_desc.Format);
|
||||||
|
|
||||||
|
return vk::getPlaneCount(formatInfo->aspectMask);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -179,11 +179,14 @@ namespace dxvk {
|
||||||
* Fills in undefined values and validates the texture
|
* Fills in undefined values and validates the texture
|
||||||
* parameters. Any error returned by this method should
|
* parameters. Any error returned by this method should
|
||||||
* be forwarded to the application.
|
* be forwarded to the application.
|
||||||
|
* \param [in] pDevice D3D9 device
|
||||||
|
* \param [in] ResourceType Resource type
|
||||||
* \param [in,out] pDesc Texture description
|
* \param [in,out] pDesc Texture description
|
||||||
* \returns \c S_OK if the parameters are valid
|
* \returns \c S_OK if the parameters are valid
|
||||||
*/
|
*/
|
||||||
static HRESULT NormalizeTextureProperties(
|
static HRESULT NormalizeTextureProperties(
|
||||||
D3D9DeviceEx* pDevice,
|
D3D9DeviceEx* pDevice,
|
||||||
|
D3DRESOURCETYPE ResourceType,
|
||||||
D3D9_COMMON_TEXTURE_DESC* pDesc);
|
D3D9_COMMON_TEXTURE_DESC* pDesc);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -307,14 +310,16 @@ namespace dxvk {
|
||||||
return util::computeMipLevelExtent(GetExtent(), MipLevel);
|
return util::computeMipLevelExtent(GetExtent(), MipLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MarkHazardous() {
|
bool MarkTransitionedToHazardLayout() {
|
||||||
return std::exchange(m_hazardous, true);
|
return std::exchange(m_transitionedToHazardLayout, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
D3DRESOURCETYPE GetType() {
|
D3DRESOURCETYPE GetType() {
|
||||||
return m_type;
|
return m_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t GetPlaneCount() const;
|
||||||
|
|
||||||
const D3D9_VK_FORMAT_MAPPING& GetMapping() { return m_mapping; }
|
const D3D9_VK_FORMAT_MAPPING& GetMapping() { return m_mapping; }
|
||||||
|
|
||||||
void SetLocked(UINT Subresource, bool value) { m_locked.set(Subresource, value); }
|
void SetLocked(UINT Subresource, bool value) { m_locked.set(Subresource, value); }
|
||||||
|
@ -338,7 +343,7 @@ namespace dxvk {
|
||||||
}
|
}
|
||||||
|
|
||||||
VkImageLayout DetermineRenderTargetLayout(VkImageLayout hazardLayout) const {
|
VkImageLayout DetermineRenderTargetLayout(VkImageLayout hazardLayout) const {
|
||||||
if (unlikely(m_hazardous))
|
if (unlikely(m_transitionedToHazardLayout))
|
||||||
return hazardLayout;
|
return hazardLayout;
|
||||||
|
|
||||||
return m_image != nullptr &&
|
return m_image != nullptr &&
|
||||||
|
@ -348,18 +353,16 @@ namespace dxvk {
|
||||||
}
|
}
|
||||||
|
|
||||||
VkImageLayout DetermineDepthStencilLayout(bool write, bool hazardous, VkImageLayout hazardLayout) const {
|
VkImageLayout DetermineDepthStencilLayout(bool write, bool hazardous, VkImageLayout hazardLayout) const {
|
||||||
VkImageLayout layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
if (unlikely(m_transitionedToHazardLayout))
|
||||||
|
return hazardLayout;
|
||||||
if (unlikely(hazardous)) {
|
|
||||||
layout = write
|
|
||||||
? hazardLayout
|
|
||||||
: VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (unlikely(m_image->info().tiling != VK_IMAGE_TILING_OPTIMAL))
|
if (unlikely(m_image->info().tiling != VK_IMAGE_TILING_OPTIMAL))
|
||||||
layout = VK_IMAGE_LAYOUT_GENERAL;
|
return VK_IMAGE_LAYOUT_GENERAL;
|
||||||
|
|
||||||
return layout;
|
if (unlikely(hazardous && !write))
|
||||||
|
return VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL;
|
||||||
|
|
||||||
|
return VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Rc<DxvkImageView> CreateView(
|
Rc<DxvkImageView> CreateView(
|
||||||
|
@ -510,7 +513,7 @@ namespace dxvk {
|
||||||
|
|
||||||
int64_t m_size = 0;
|
int64_t m_size = 0;
|
||||||
|
|
||||||
bool m_hazardous = false;
|
bool m_transitionedToHazardLayout = false;
|
||||||
|
|
||||||
D3D9ColorView m_sampleView;
|
D3D9ColorView m_sampleView;
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace dxvk {
|
||||||
DxsoProgramType ShaderStage,
|
DxsoProgramType ShaderStage,
|
||||||
DxsoConstantBuffers BufferType,
|
DxsoConstantBuffers BufferType,
|
||||||
VkDeviceSize Size)
|
VkDeviceSize Size)
|
||||||
: D3D9ConstantBuffer(pDevice, getBufferUsage(pDevice, ShaderStage, BufferType), GetShaderStage(ShaderStage),
|
: D3D9ConstantBuffer(pDevice, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, GetShaderStage(ShaderStage),
|
||||||
computeResourceSlotId(ShaderStage, DxsoBindingType::ConstantBuffer, BufferType),
|
computeResourceSlotId(ShaderStage, DxsoBindingType::ConstantBuffer, BufferType),
|
||||||
Size) {
|
Size) {
|
||||||
|
|
||||||
|
@ -135,21 +135,4 @@ namespace dxvk {
|
||||||
device->properties().extRobustness2.robustUniformBufferAccessSizeAlignment);
|
device->properties().extRobustness2.robustUniformBufferAccessSizeAlignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VkBufferUsageFlags D3D9ConstantBuffer::getBufferUsage(
|
|
||||||
D3D9DeviceEx* pDevice,
|
|
||||||
DxsoProgramType ShaderStage,
|
|
||||||
DxsoConstantBuffers BufferType) {
|
|
||||||
VkBufferUsageFlags result = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
|
|
||||||
|
|
||||||
// We won't always need this, but the only buffer that
|
|
||||||
// this applies to is so large that it will not matter.
|
|
||||||
if (pDevice->CanSWVP()
|
|
||||||
&& ShaderStage == DxsoProgramType::VertexShader
|
|
||||||
&& BufferType == DxsoConstantBuffers::VSConstantBuffer)
|
|
||||||
result |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,11 +80,6 @@ namespace dxvk {
|
||||||
|
|
||||||
VkDeviceSize getAlignment(const Rc<DxvkDevice>& device) const;
|
VkDeviceSize getAlignment(const Rc<DxvkDevice>& device) const;
|
||||||
|
|
||||||
static VkBufferUsageFlags getBufferUsage(
|
|
||||||
D3D9DeviceEx* pDevice,
|
|
||||||
DxsoProgramType ShaderStage,
|
|
||||||
DxsoConstantBuffers BufferType);
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
|
@ -16,7 +16,11 @@ namespace dxvk {
|
||||||
|
|
||||||
|
|
||||||
BOOL D3D9Cursor::ShowCursor(BOOL bShow) {
|
BOOL D3D9Cursor::ShowCursor(BOOL bShow) {
|
||||||
::SetCursor(bShow ? m_hCursor : nullptr);
|
if (likely(m_hCursor != nullptr))
|
||||||
|
::SetCursor(bShow ? m_hCursor : nullptr);
|
||||||
|
else
|
||||||
|
Logger::debug("D3D9Cursor::ShowCursor: Software cursor not implemented.");
|
||||||
|
|
||||||
return std::exchange(m_visible, bShow);
|
return std::exchange(m_visible, bShow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,4 +67,4 @@ namespace dxvk {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -28,12 +28,17 @@
|
||||||
|
|
||||||
#include "d3d9_spec_constants.h"
|
#include "d3d9_spec_constants.h"
|
||||||
#include "d3d9_interop.h"
|
#include "d3d9_interop.h"
|
||||||
|
#include "d3d9_on_12.h"
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
#include "d3d9_bridge.h"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
|
#include "../util/util_flush.h"
|
||||||
#include "../util/util_lru.h"
|
#include "../util/util_lru.h"
|
||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
@ -61,6 +66,8 @@ namespace dxvk {
|
||||||
DirtyInputLayout,
|
DirtyInputLayout,
|
||||||
DirtyViewportScissor,
|
DirtyViewportScissor,
|
||||||
DirtyMultiSampleState,
|
DirtyMultiSampleState,
|
||||||
|
DirtyVertexBuffers,
|
||||||
|
DirtyIndexBuffer,
|
||||||
|
|
||||||
DirtyFogState,
|
DirtyFogState,
|
||||||
DirtyFogColor,
|
DirtyFogColor,
|
||||||
|
@ -87,6 +94,12 @@ namespace dxvk {
|
||||||
|
|
||||||
using D3D9DeviceFlags = Flags<D3D9DeviceFlag>;
|
using D3D9DeviceFlags = Flags<D3D9DeviceFlag>;
|
||||||
|
|
||||||
|
enum class D3D9DeviceLostState {
|
||||||
|
Ok = 0,
|
||||||
|
Lost = 1,
|
||||||
|
NotReset = 2,
|
||||||
|
};
|
||||||
|
|
||||||
struct D3D9DrawInfo {
|
struct D3D9DrawInfo {
|
||||||
uint32_t vertexCount;
|
uint32_t vertexCount;
|
||||||
uint32_t instanceCount;
|
uint32_t instanceCount;
|
||||||
|
@ -117,8 +130,10 @@ namespace dxvk {
|
||||||
constexpr static VkDeviceSize StagingBufferSize = 4ull << 20;
|
constexpr static VkDeviceSize StagingBufferSize = 4ull << 20;
|
||||||
|
|
||||||
friend class D3D9SwapChainEx;
|
friend class D3D9SwapChainEx;
|
||||||
|
friend struct D3D9WindowContext;
|
||||||
friend class D3D9ConstantBuffer;
|
friend class D3D9ConstantBuffer;
|
||||||
friend class D3D9UserDefinedAnnotation;
|
friend class D3D9UserDefinedAnnotation;
|
||||||
|
friend class DxvkD3D8Bridge;
|
||||||
friend D3D9VkInteropDevice;
|
friend D3D9VkInteropDevice;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -751,6 +766,24 @@ namespace dxvk {
|
||||||
HRESULT UnlockBuffer(
|
HRESULT UnlockBuffer(
|
||||||
D3D9CommonBuffer* pResource);
|
D3D9CommonBuffer* pResource);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Uploads data from D3DPOOL_SYSMEM + D3DUSAGE_DYNAMIC buffers and binds the temporary buffers.
|
||||||
|
*
|
||||||
|
* @param FirstVertexIndex The first vertex
|
||||||
|
* @param NumVertices The number of vertices that are accessed. If this is 0, the vertex buffer binding will not be modified.
|
||||||
|
* @param FirstIndex The first index
|
||||||
|
* @param NumIndices The number of indices that will be drawn. If this is 0, the index buffer binding will not be modified.
|
||||||
|
*/
|
||||||
|
void UploadDynamicSysmemBuffers(
|
||||||
|
UINT& FirstVertexIndex,
|
||||||
|
UINT NumVertices,
|
||||||
|
UINT& FirstIndex,
|
||||||
|
UINT NumIndices,
|
||||||
|
INT& BaseVertexIndex,
|
||||||
|
bool* pDynamicVBOs,
|
||||||
|
bool* pDynamicIBO);
|
||||||
|
|
||||||
|
|
||||||
void SetupFPU();
|
void SetupFPU();
|
||||||
|
|
||||||
int64_t DetermineInitialTextureMemory();
|
int64_t DetermineInitialTextureMemory();
|
||||||
|
@ -760,6 +793,7 @@ namespace dxvk {
|
||||||
void SynchronizeCsThread(uint64_t SequenceNumber);
|
void SynchronizeCsThread(uint64_t SequenceNumber);
|
||||||
|
|
||||||
void Flush();
|
void Flush();
|
||||||
|
void FlushAndSync9On12();
|
||||||
|
|
||||||
void EndFrame();
|
void EndFrame();
|
||||||
|
|
||||||
|
@ -767,6 +801,9 @@ namespace dxvk {
|
||||||
|
|
||||||
void UpdateActiveRTs(uint32_t index);
|
void UpdateActiveRTs(uint32_t index);
|
||||||
|
|
||||||
|
template <uint32_t Index>
|
||||||
|
void UpdateAnyColorWrites(bool has);
|
||||||
|
|
||||||
void UpdateActiveTextures(uint32_t index, DWORD combinedUsage);
|
void UpdateActiveTextures(uint32_t index, DWORD combinedUsage);
|
||||||
|
|
||||||
void UpdateActiveHazardsRT(uint32_t rtMask);
|
void UpdateActiveHazardsRT(uint32_t rtMask);
|
||||||
|
@ -800,7 +837,7 @@ namespace dxvk {
|
||||||
inline bool IsAlphaToCoverageEnabled() {
|
inline bool IsAlphaToCoverageEnabled() {
|
||||||
const bool alphaTest = m_state.renderStates[D3DRS_ALPHATESTENABLE] != 0;
|
const bool alphaTest = m_state.renderStates[D3DRS_ALPHATESTENABLE] != 0;
|
||||||
|
|
||||||
return m_amdATOC || (m_nvATOC && alphaTest);
|
return (m_amdATOC || (m_nvATOC && alphaTest)) && m_flags.test(D3D9DeviceFlag::ValidSampleMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool IsDepthBiasEnabled() {
|
inline bool IsDepthBiasEnabled() {
|
||||||
|
@ -868,6 +905,10 @@ namespace dxvk {
|
||||||
|
|
||||||
void MarkTextureBindingDirty(IDirect3DBaseTexture9* texture);
|
void MarkTextureBindingDirty(IDirect3DBaseTexture9* texture);
|
||||||
|
|
||||||
|
HRESULT STDMETHODCALLTYPE SetRenderTargetInternal(
|
||||||
|
DWORD RenderTargetIndex,
|
||||||
|
IDirect3DSurface9* pRenderTarget);
|
||||||
|
|
||||||
D3D9DrawInfo GenerateDrawInfo(
|
D3D9DrawInfo GenerateDrawInfo(
|
||||||
D3DPRIMITIVETYPE PrimitiveType,
|
D3DPRIMITIVETYPE PrimitiveType,
|
||||||
UINT PrimitiveCount,
|
UINT PrimitiveCount,
|
||||||
|
@ -875,7 +916,7 @@ namespace dxvk {
|
||||||
|
|
||||||
uint32_t GetInstanceCount() const;
|
uint32_t GetInstanceCount() const;
|
||||||
|
|
||||||
void PrepareDraw(D3DPRIMITIVETYPE PrimitiveType);
|
void PrepareDraw(D3DPRIMITIVETYPE PrimitiveType, bool UploadVBOs, bool UploadIBOs);
|
||||||
|
|
||||||
template <DxsoProgramType ShaderStage>
|
template <DxsoProgramType ShaderStage>
|
||||||
void BindShader(
|
void BindShader(
|
||||||
|
@ -909,7 +950,7 @@ namespace dxvk {
|
||||||
void SetVertexBoolBitfield(uint32_t idx, uint32_t mask, uint32_t bits);
|
void SetVertexBoolBitfield(uint32_t idx, uint32_t mask, uint32_t bits);
|
||||||
void SetPixelBoolBitfield (uint32_t idx, uint32_t mask, uint32_t bits);
|
void SetPixelBoolBitfield (uint32_t idx, uint32_t mask, uint32_t bits);
|
||||||
|
|
||||||
void FlushImplicit(BOOL StrongHint);
|
void ConsiderFlush(GpuFlushType FlushType);
|
||||||
|
|
||||||
bool ChangeReportedMemory(int64_t delta) {
|
bool ChangeReportedMemory(int64_t delta) {
|
||||||
if (IsExtended())
|
if (IsExtended())
|
||||||
|
@ -933,7 +974,7 @@ namespace dxvk {
|
||||||
const D3D9ConstantLayout& GetVertexConstantLayout() { return m_vsLayout; }
|
const D3D9ConstantLayout& GetVertexConstantLayout() { return m_vsLayout; }
|
||||||
const D3D9ConstantLayout& GetPixelConstantLayout() { return m_psLayout; }
|
const D3D9ConstantLayout& GetPixelConstantLayout() { return m_psLayout; }
|
||||||
|
|
||||||
HRESULT ResetState(D3DPRESENT_PARAMETERS* pPresentationParameters);
|
void ResetState(D3DPRESENT_PARAMETERS* pPresentationParameters);
|
||||||
HRESULT ResetSwapChain(D3DPRESENT_PARAMETERS* pPresentationParameters, D3DDISPLAYMODEEX* pFullscreenDisplayMode);
|
HRESULT ResetSwapChain(D3DPRESENT_PARAMETERS* pPresentationParameters, D3DDISPLAYMODEEX* pFullscreenDisplayMode);
|
||||||
|
|
||||||
HRESULT InitialReset(D3DPRESENT_PARAMETERS* pPresentationParameters, D3DDISPLAYMODEEX* pFullscreenDisplayMode);
|
HRESULT InitialReset(D3DPRESENT_PARAMETERS* pPresentationParameters, D3DDISPLAYMODEEX* pFullscreenDisplayMode);
|
||||||
|
@ -950,6 +991,37 @@ namespace dxvk {
|
||||||
void TouchMappedTexture(D3D9CommonTexture* pTexture);
|
void TouchMappedTexture(D3D9CommonTexture* pTexture);
|
||||||
void RemoveMappedTexture(D3D9CommonTexture* pTexture);
|
void RemoveMappedTexture(D3D9CommonTexture* pTexture);
|
||||||
|
|
||||||
|
bool IsD3D8Compatible() const {
|
||||||
|
return m_isD3D8Compatible;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetD3D8CompatibilityMode(bool compatMode) {
|
||||||
|
if (compatMode)
|
||||||
|
Logger::info("The D3D9 device is now operating in D3D8 compatibility mode.");
|
||||||
|
|
||||||
|
m_isD3D8Compatible = compatMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Device Lost
|
||||||
|
bool IsDeviceLost() const {
|
||||||
|
return m_deviceLostState != D3D9DeviceLostState::Ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotifyFullscreen(HWND window, bool fullscreen);
|
||||||
|
void NotifyWindowActivated(HWND window, bool activated);
|
||||||
|
|
||||||
|
void IncrementLosableCounter() {
|
||||||
|
m_losableResourceCounter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DecrementLosableCounter() {
|
||||||
|
m_losableResourceCounter--;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CanOnlySWVP() const {
|
||||||
|
return m_behaviorFlags & D3DCREATE_SOFTWARE_VERTEXPROCESSING;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
DxvkCsChunkRef AllocCsChunk() {
|
DxvkCsChunkRef AllocCsChunk() {
|
||||||
|
@ -957,12 +1029,15 @@ namespace dxvk {
|
||||||
return DxvkCsChunkRef(chunk, &m_csChunkPool);
|
return DxvkCsChunkRef(chunk, &m_csChunkPool);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Cmd>
|
template<bool AllowFlush = true, typename Cmd>
|
||||||
void EmitCs(Cmd&& command) {
|
void EmitCs(Cmd&& command) {
|
||||||
if (unlikely(!m_csChunk->push(command))) {
|
if (unlikely(!m_csChunk->push(command))) {
|
||||||
EmitCsChunk(std::move(m_csChunk));
|
EmitCsChunk(std::move(m_csChunk));
|
||||||
|
|
||||||
m_csChunk = AllocCsChunk();
|
m_csChunk = AllocCsChunk();
|
||||||
|
|
||||||
|
if constexpr (AllowFlush)
|
||||||
|
ConsiderFlush(GpuFlushType::ImplicitWeakHint);
|
||||||
|
|
||||||
m_csChunk->push(command);
|
m_csChunk->push(command);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -976,10 +1051,18 @@ namespace dxvk {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CanSWVP() {
|
bool CanSWVP() const {
|
||||||
return m_behaviorFlags & (D3DCREATE_MIXED_VERTEXPROCESSING | D3DCREATE_SOFTWARE_VERTEXPROCESSING);
|
return m_behaviorFlags & (D3DCREATE_MIXED_VERTEXPROCESSING | D3DCREATE_SOFTWARE_VERTEXPROCESSING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Device Reset detection for D3D9SwapChainEx::Present
|
||||||
|
bool IsDeviceReset() {
|
||||||
|
return std::exchange(m_deviceHasBeenReset, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <bool Synchronize9On12>
|
||||||
|
void ExecuteFlush();
|
||||||
|
|
||||||
void DetermineConstantLayouts(bool canSWVP);
|
void DetermineConstantLayouts(bool canSWVP);
|
||||||
|
|
||||||
D3D9BufferSlice AllocUPBuffer(VkDeviceSize size);
|
D3D9BufferSlice AllocUPBuffer(VkDeviceSize size);
|
||||||
|
@ -1004,7 +1087,7 @@ namespace dxvk {
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint32_t GetUPBufferSize(uint32_t vertexCount, uint32_t stride) {
|
inline uint32_t GetUPBufferSize(uint32_t vertexCount, uint32_t stride) {
|
||||||
return (vertexCount - 1) * stride + std::max(m_state.vertexDecl->GetSize(), stride);
|
return (vertexCount - 1) * stride + std::max(m_state.vertexDecl->GetSize(0), stride);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void FillUPVertexBuffer(void* buffer, const void* userData, uint32_t dataSize, uint32_t bufferSize) {
|
inline void FillUPVertexBuffer(void* buffer, const void* userData, uint32_t dataSize, uint32_t bufferSize) {
|
||||||
|
@ -1093,13 +1176,13 @@ namespace dxvk {
|
||||||
return D3DERR_INVALIDCALL;
|
return D3DERR_INVALIDCALL;
|
||||||
|
|
||||||
if constexpr (ConstantType == D3D9ConstantType::Float) {
|
if constexpr (ConstantType == D3D9ConstantType::Float) {
|
||||||
const float* source = set.fConsts[StartRegister].data;
|
const float* source = set->fConsts[StartRegister].data;
|
||||||
const size_t size = Count * sizeof(Vector4);
|
const size_t size = Count * sizeof(Vector4);
|
||||||
|
|
||||||
std::memcpy(pConstantData, source, size);
|
std::memcpy(pConstantData, source, size);
|
||||||
}
|
}
|
||||||
else if constexpr (ConstantType == D3D9ConstantType::Int) {
|
else if constexpr (ConstantType == D3D9ConstantType::Int) {
|
||||||
const int* source = set.iConsts[StartRegister].data;
|
const int* source = set->iConsts[StartRegister].data;
|
||||||
const size_t size = Count * sizeof(Vector4i);
|
const size_t size = Count * sizeof(Vector4i);
|
||||||
|
|
||||||
std::memcpy(pConstantData, source, size);
|
std::memcpy(pConstantData, source, size);
|
||||||
|
@ -1112,7 +1195,7 @@ namespace dxvk {
|
||||||
|
|
||||||
const uint32_t bit = (1u << bitIdx);
|
const uint32_t bit = (1u << bitIdx);
|
||||||
|
|
||||||
bool constValue = set.bConsts[arrayIdx] & bit;
|
bool constValue = set->bConsts[arrayIdx] & bit;
|
||||||
pConstantData[i] = constValue ? TRUE : FALSE;
|
pConstantData[i] = constValue ? TRUE : FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1162,11 +1245,38 @@ namespace dxvk {
|
||||||
|
|
||||||
uint64_t GetCurrentSequenceNumber();
|
uint64_t GetCurrentSequenceNumber();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the swapchain that was used the most recently for presenting
|
||||||
|
* Has to be externally synchronized.
|
||||||
|
*
|
||||||
|
* @return D3D9SwapChainEx* Swapchain
|
||||||
|
*/
|
||||||
|
D3D9SwapChainEx* GetMostRecentlyUsedSwapchain() {
|
||||||
|
return m_mostRecentlyUsedSwapchain;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the swapchain that was used the most recently for presenting
|
||||||
|
* Has to be externally synchronized.
|
||||||
|
*
|
||||||
|
* @param swapchain Swapchain
|
||||||
|
*/
|
||||||
|
void SetMostRecentlyUsedSwapchain(D3D9SwapChainEx* swapchain) {
|
||||||
|
m_mostRecentlyUsedSwapchain = swapchain;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reset the most recently swapchain back to the implicit one
|
||||||
|
* Has to be externally synchronized.
|
||||||
|
*/
|
||||||
|
void ResetMostRecentlyUsedSwapchain() {
|
||||||
|
m_mostRecentlyUsedSwapchain = m_implicitSwapchain.ptr();
|
||||||
|
}
|
||||||
|
|
||||||
Com<D3D9InterfaceEx> m_parent;
|
Com<D3D9InterfaceEx> m_parent;
|
||||||
D3DDEVTYPE m_deviceType;
|
D3DDEVTYPE m_deviceType;
|
||||||
HWND m_window;
|
HWND m_window;
|
||||||
WORD m_behaviorFlags;
|
WORD m_behaviorFlags;
|
||||||
D3DPRESENT_PARAMETERS m_presentParams;
|
|
||||||
|
|
||||||
D3D9Adapter* m_adapter;
|
D3D9Adapter* m_adapter;
|
||||||
Rc<DxvkDevice> m_dxvkDevice;
|
Rc<DxvkDevice> m_dxvkDevice;
|
||||||
|
@ -1245,14 +1355,16 @@ namespace dxvk {
|
||||||
uint32_t m_dirtySamplerStates = 0;
|
uint32_t m_dirtySamplerStates = 0;
|
||||||
uint32_t m_dirtyTextures = 0;
|
uint32_t m_dirtyTextures = 0;
|
||||||
|
|
||||||
uint32_t m_boundRTs = 0;
|
uint32_t m_boundRTs : 4;
|
||||||
|
uint32_t m_anyColorWrites : 4;
|
||||||
|
uint32_t m_activeRTsWhichAreTextures : 4;
|
||||||
|
uint32_t m_alphaSwizzleRTs : 4;
|
||||||
|
uint32_t m_lastHazardsRT : 4;
|
||||||
|
|
||||||
uint32_t m_activeRTs = 0;
|
uint32_t m_activeTextureRTs = 0;
|
||||||
uint32_t m_activeRTTextures = 0;
|
uint32_t m_activeTextureDSs = 0;
|
||||||
uint32_t m_activeDSTextures = 0;
|
|
||||||
uint32_t m_activeHazardsRT = 0;
|
uint32_t m_activeHazardsRT = 0;
|
||||||
uint32_t m_activeHazardsDS = 0;
|
uint32_t m_activeHazardsDS = 0;
|
||||||
uint32_t m_alphaSwizzleRTs = 0;
|
|
||||||
uint32_t m_activeTextures = 0;
|
uint32_t m_activeTextures = 0;
|
||||||
uint32_t m_activeTexturesToUpload = 0;
|
uint32_t m_activeTexturesToUpload = 0;
|
||||||
uint32_t m_activeTexturesToGen = 0;
|
uint32_t m_activeTexturesToGen = 0;
|
||||||
|
@ -1267,7 +1379,6 @@ namespace dxvk {
|
||||||
uint32_t m_fetch4 = 0;
|
uint32_t m_fetch4 = 0;
|
||||||
|
|
||||||
uint32_t m_lastHazardsDS = 0;
|
uint32_t m_lastHazardsDS = 0;
|
||||||
uint32_t m_lastHazardsRT = 0;
|
|
||||||
uint32_t m_lastSamplerTypesFF = 0;
|
uint32_t m_lastSamplerTypesFF = 0;
|
||||||
|
|
||||||
D3D9SpecializationInfo m_specInfo = D3D9SpecializationInfo();
|
D3D9SpecializationInfo m_specInfo = D3D9SpecializationInfo();
|
||||||
|
@ -1276,14 +1387,17 @@ namespace dxvk {
|
||||||
D3D9ShaderMasks m_psShaderMasks = FixedFunctionMask;
|
D3D9ShaderMasks m_psShaderMasks = FixedFunctionMask;
|
||||||
|
|
||||||
bool m_isSWVP;
|
bool m_isSWVP;
|
||||||
bool m_amdATOC = false;
|
bool m_isD3D8Compatible = false;
|
||||||
bool m_nvATOC = false;
|
bool m_amdATOC = false;
|
||||||
bool m_ffZTest = false;
|
bool m_nvATOC = false;
|
||||||
|
bool m_ffZTest = false;
|
||||||
|
|
||||||
VkImageLayout m_hazardLayout = VK_IMAGE_LAYOUT_GENERAL;
|
VkImageLayout m_hazardLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||||
|
|
||||||
bool m_usingGraphicsPipelines = false;
|
bool m_usingGraphicsPipelines = false;
|
||||||
|
bool m_deviceHasBeenReset = false;
|
||||||
|
|
||||||
|
DxvkDepthBiasRepresentation m_depthBiasRepresentation = { VK_DEPTH_BIAS_REPRESENTATION_LEAST_REPRESENTABLE_VALUE_FORMAT_EXT, false };
|
||||||
float m_depthBiasScale = 0.0f;
|
float m_depthBiasScale = 0.0f;
|
||||||
|
|
||||||
uint32_t m_robustSSBOAlignment = 1;
|
uint32_t m_robustSSBOAlignment = 1;
|
||||||
|
@ -1305,23 +1419,37 @@ namespace dxvk {
|
||||||
D3D9ViewportInfo m_viewportInfo;
|
D3D9ViewportInfo m_viewportInfo;
|
||||||
|
|
||||||
DxvkCsChunkPool m_csChunkPool;
|
DxvkCsChunkPool m_csChunkPool;
|
||||||
dxvk::high_resolution_clock::time_point m_lastFlush
|
|
||||||
= dxvk::high_resolution_clock::now();
|
|
||||||
DxvkCsThread m_csThread;
|
DxvkCsThread m_csThread;
|
||||||
DxvkCsChunkRef m_csChunk;
|
DxvkCsChunkRef m_csChunk;
|
||||||
uint64_t m_csSeqNum = 0ull;
|
uint64_t m_csSeqNum = 0ull;
|
||||||
bool m_csIsBusy = false;
|
|
||||||
|
Rc<sync::Fence> m_submissionFence;
|
||||||
|
uint64_t m_submissionId = 0ull;
|
||||||
|
DxvkSubmitStatus m_submitStatus;
|
||||||
|
|
||||||
|
uint64_t m_flushSeqNum = 0ull;
|
||||||
|
GpuFlushTracker m_flushTracker;
|
||||||
|
|
||||||
std::atomic<int64_t> m_availableMemory = { 0 };
|
std::atomic<int64_t> m_availableMemory = { 0 };
|
||||||
std::atomic<int32_t> m_samplerCount = { 0 };
|
std::atomic<int32_t> m_samplerCount = { 0 };
|
||||||
|
|
||||||
Direct3DState9 m_state;
|
D3D9DeviceLostState m_deviceLostState = D3D9DeviceLostState::Ok;
|
||||||
|
HWND m_fullscreenWindow = NULL;
|
||||||
|
std::atomic<uint32_t> m_losableResourceCounter = { 0 };
|
||||||
|
|
||||||
|
D3D9SwapChainEx* m_mostRecentlyUsedSwapchain = nullptr;
|
||||||
|
|
||||||
#ifdef D3D9_ALLOW_UNMAPPING
|
#ifdef D3D9_ALLOW_UNMAPPING
|
||||||
lru_list<D3D9CommonTexture*> m_mappedTextures;
|
lru_list<D3D9CommonTexture*> m_mappedTextures;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// m_state should be declared last (i.e. freed first), because it
|
||||||
|
// references objects that can call back into the device when freed.
|
||||||
|
Direct3DState9 m_state;
|
||||||
|
|
||||||
D3D9VkInteropDevice m_d3d9Interop;
|
D3D9VkInteropDevice m_d3d9Interop;
|
||||||
|
D3D9On12 m_d3d9On12;
|
||||||
|
DxvkD3D8Bridge m_d3d8Bridge;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -336,7 +336,7 @@ namespace dxvk {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint32_t SetupRenderStateBlock(SpirvModule& spvModule, uint32_t count) {
|
uint32_t SetupRenderStateBlock(SpirvModule& spvModule) {
|
||||||
uint32_t floatType = spvModule.defFloatType(32);
|
uint32_t floatType = spvModule.defFloatType(32);
|
||||||
uint32_t uintType = spvModule.defIntType(32, 0);
|
uint32_t uintType = spvModule.defIntType(32, 0);
|
||||||
uint32_t vec3Type = spvModule.defVectorType(floatType, 3);
|
uint32_t vec3Type = spvModule.defVectorType(floatType, 3);
|
||||||
|
@ -357,7 +357,7 @@ namespace dxvk {
|
||||||
floatType,
|
floatType,
|
||||||
}};
|
}};
|
||||||
|
|
||||||
uint32_t rsStruct = spvModule.defStructTypeUnique(count, rsMembers.data());
|
uint32_t rsStruct = spvModule.defStructTypeUnique(rsMembers.size(), rsMembers.data());
|
||||||
uint32_t rsBlock = spvModule.newVar(
|
uint32_t rsBlock = spvModule.newVar(
|
||||||
spvModule.defPointerType(rsStruct, spv::StorageClassPushConstant),
|
spvModule.defPointerType(rsStruct, spv::StorageClassPushConstant),
|
||||||
spv::StorageClassPushConstant);
|
spv::StorageClassPushConstant);
|
||||||
|
@ -369,9 +369,6 @@ namespace dxvk {
|
||||||
|
|
||||||
uint32_t memberIdx = 0;
|
uint32_t memberIdx = 0;
|
||||||
auto SetMemberName = [&](const char* name, uint32_t offset) {
|
auto SetMemberName = [&](const char* name, uint32_t offset) {
|
||||||
if (memberIdx >= count)
|
|
||||||
return;
|
|
||||||
|
|
||||||
spvModule.setDebugMemberName (rsStruct, memberIdx, name);
|
spvModule.setDebugMemberName (rsStruct, memberIdx, name);
|
||||||
spvModule.memberDecorateOffset (rsStruct, memberIdx, offset);
|
spvModule.memberDecorateOffset (rsStruct, memberIdx, offset);
|
||||||
memberIdx++;
|
memberIdx++;
|
||||||
|
@ -781,8 +778,6 @@ namespace dxvk {
|
||||||
uint32_t m_inputMask = 0u;
|
uint32_t m_inputMask = 0u;
|
||||||
uint32_t m_outputMask = 0u;
|
uint32_t m_outputMask = 0u;
|
||||||
uint32_t m_flatShadingMask = 0u;
|
uint32_t m_flatShadingMask = 0u;
|
||||||
uint32_t m_pushConstOffset = 0u;
|
|
||||||
uint32_t m_pushConstSize = 0u;
|
|
||||||
|
|
||||||
DxsoProgramType m_programType;
|
DxsoProgramType m_programType;
|
||||||
D3D9FFShaderKeyVS m_vsKey;
|
D3D9FFShaderKeyVS m_vsKey;
|
||||||
|
@ -892,8 +887,8 @@ namespace dxvk {
|
||||||
info.inputMask = m_inputMask;
|
info.inputMask = m_inputMask;
|
||||||
info.outputMask = m_outputMask;
|
info.outputMask = m_outputMask;
|
||||||
info.flatShadingInputs = m_flatShadingMask;
|
info.flatShadingInputs = m_flatShadingMask;
|
||||||
info.pushConstOffset = m_pushConstOffset;
|
info.pushConstStages = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||||
info.pushConstSize = m_pushConstSize;
|
info.pushConstSize = sizeof(D3D9RenderStateInfo);
|
||||||
|
|
||||||
return new DxvkShader(info, m_module.compile());
|
return new DxvkShader(info, m_module.compile());
|
||||||
}
|
}
|
||||||
|
@ -1102,35 +1097,60 @@ namespace dxvk {
|
||||||
m_module.opStore(m_vs.out.NORMAL, outNrm);
|
m_module.opStore(m_vs.out.NORMAL, outNrm);
|
||||||
|
|
||||||
for (uint32_t i = 0; i < caps::TextureStageCount; i++) {
|
for (uint32_t i = 0; i < caps::TextureStageCount; i++) {
|
||||||
uint32_t inputIndex = (m_vsKey.Data.Contents.TexcoordIndices >> (i * 3)) & 0b111;
|
uint32_t inputIndex = (m_vsKey.Data.Contents.TexcoordIndices >> (i * 3)) & 0b111;
|
||||||
uint32_t inputFlags = (m_vsKey.Data.Contents.TexcoordFlags >> (i * 3)) & 0b111;
|
uint32_t inputFlags = (m_vsKey.Data.Contents.TexcoordFlags >> (i * 3)) & 0b111;
|
||||||
|
uint32_t texcoordCount = (m_vsKey.Data.Contents.TexcoordDeclMask >> (inputIndex * 3)) & 0b111;
|
||||||
|
|
||||||
uint32_t transformed;
|
uint32_t transformed;
|
||||||
|
|
||||||
const uint32_t wIndex = 3;
|
const uint32_t wIndex = 3;
|
||||||
|
|
||||||
uint32_t flags = (m_vsKey.Data.Contents.TransformFlags >> (i * 3)) & 0b111;
|
uint32_t flags = (m_vsKey.Data.Contents.TransformFlags >> (i * 3)) & 0b111;
|
||||||
uint32_t count = flags;
|
|
||||||
|
if (flags == D3DTTFF_COUNT1) {
|
||||||
|
// D3DTTFF_COUNT1 behaves like D3DTTFF_DISABLE on NV and like D3DTTFF_COUNT2 on AMD.
|
||||||
|
// The Nvidia behavior is easier to implement.
|
||||||
|
flags = D3DTTFF_DISABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Passing 0xffffffff results in it getting clamped to the dimensions of the texture coords and getting treated as PROJECTED
|
||||||
|
// but D3D9 does not apply the transformation matrix.
|
||||||
|
bool applyTransform = flags >= D3DTTFF_COUNT1 && flags <= D3DTTFF_COUNT4;
|
||||||
|
|
||||||
|
uint32_t count;
|
||||||
switch (inputFlags) {
|
switch (inputFlags) {
|
||||||
default:
|
default:
|
||||||
case (DXVK_TSS_TCI_PASSTHRU >> TCIOffset):
|
case (DXVK_TSS_TCI_PASSTHRU >> TCIOffset):
|
||||||
transformed = m_vs.in.TEXCOORD[inputIndex & 0xFF];
|
transformed = m_vs.in.TEXCOORD[inputIndex & 0xFF];
|
||||||
|
// flags is actually the number of elements that get passed
|
||||||
|
// to the rasterizer.
|
||||||
|
count = flags;
|
||||||
|
if (texcoordCount) {
|
||||||
|
// Clamp by the number of elements in the texcoord input.
|
||||||
|
if (!count || count > texcoordCount) {
|
||||||
|
count = texcoordCount;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
count = 0;
|
||||||
|
flags = D3DTTFF_DISABLE;
|
||||||
|
applyTransform = false;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case (DXVK_TSS_TCI_CAMERASPACENORMAL >> TCIOffset):
|
case (DXVK_TSS_TCI_CAMERASPACENORMAL >> TCIOffset):
|
||||||
transformed = outNrm;
|
transformed = outNrm;
|
||||||
count = 4;
|
count = std::min(flags, 4u);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case (DXVK_TSS_TCI_CAMERASPACEPOSITION >> TCIOffset):
|
case (DXVK_TSS_TCI_CAMERASPACEPOSITION >> TCIOffset):
|
||||||
transformed = m_module.opCompositeInsert(m_vec4Type, m_module.constf32(1.0f), vtx, 1, &wIndex);
|
transformed = m_module.opCompositeInsert(m_vec4Type, m_module.constf32(1.0f), vtx, 1, &wIndex);
|
||||||
count = 4;
|
count = std::min(flags, 4u);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case (DXVK_TSS_TCI_CAMERASPACEREFLECTIONVECTOR >> TCIOffset): {
|
case (DXVK_TSS_TCI_CAMERASPACEREFLECTIONVECTOR >> TCIOffset): {
|
||||||
uint32_t vtx3 = m_module.opVectorShuffle(m_vec3Type, vtx, vtx, 3, indices.data());
|
uint32_t vtx3 = m_module.opVectorShuffle(m_vec3Type, vtx, vtx, 3, indices.data());
|
||||||
vtx3 = m_module.opNormalize(m_vec3Type, vtx3);
|
vtx3 = m_module.opNormalize(m_vec3Type, vtx3);
|
||||||
|
|
||||||
uint32_t reflection = m_module.opReflect(m_vec3Type, vtx3, normal);
|
uint32_t reflection = m_module.opReflect(m_vec3Type, vtx3, normal);
|
||||||
|
|
||||||
std::array<uint32_t, 4> transformIndices;
|
std::array<uint32_t, 4> transformIndices;
|
||||||
|
@ -1139,7 +1159,7 @@ namespace dxvk {
|
||||||
transformIndices[3] = m_module.constf32(1.0f);
|
transformIndices[3] = m_module.constf32(1.0f);
|
||||||
|
|
||||||
transformed = m_module.opCompositeConstruct(m_vec4Type, transformIndices.size(), transformIndices.data());
|
transformed = m_module.opCompositeConstruct(m_vec4Type, transformIndices.size(), transformIndices.data());
|
||||||
count = 4;
|
count = std::min(flags, 4u);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1163,37 +1183,43 @@ namespace dxvk {
|
||||||
transformIndices[3] = m_module.constf32(1.0f);
|
transformIndices[3] = m_module.constf32(1.0f);
|
||||||
|
|
||||||
transformed = m_module.opCompositeConstruct(m_vec4Type, transformIndices.size(), transformIndices.data());
|
transformed = m_module.opCompositeConstruct(m_vec4Type, transformIndices.size(), transformIndices.data());
|
||||||
count = 4;
|
count = std::min(flags, 4u);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t type = flags;
|
if (applyTransform && !m_vsKey.Data.Contents.HasPositionT) {
|
||||||
if (type != D3DTTFF_DISABLE) {
|
for (uint32_t j = count; j < 4; j++) {
|
||||||
if (!m_vsKey.Data.Contents.HasPositionT) {
|
// If we're outside the component count of the vertex decl for this texcoord then we pad with zeroes.
|
||||||
for (uint32_t j = count; j < 4; j++) {
|
// Otherwise, pad with ones.
|
||||||
// If we're outside the component count of the vertex decl for this texcoord then we pad with zeroes.
|
|
||||||
// Otherwise, pad with ones.
|
|
||||||
|
|
||||||
// Very weird quirk in order to get texcoord transforms to work like they do in native.
|
// Very weird quirk in order to get texcoord transforms to work like they do in native.
|
||||||
// In future, maybe we could sort this out properly by chopping matrices of different sizes, but thats
|
// In future, maybe we could sort this out properly by chopping matrices of different sizes, but thats
|
||||||
// a project for another day.
|
// a project for another day.
|
||||||
uint32_t texcoordCount = (m_vsKey.Data.Contents.TexcoordDeclMask >> (3 * inputIndex)) & 0x7;
|
uint32_t texcoordCount = (m_vsKey.Data.Contents.TexcoordDeclMask >> (3 * inputIndex)) & 0x7;
|
||||||
uint32_t value = j > texcoordCount ? m_module.constf32(0) : m_module.constf32(1);
|
uint32_t value = j > texcoordCount ? m_module.constf32(0) : m_module.constf32(1);
|
||||||
transformed = m_module.opCompositeInsert(m_vec4Type, value, transformed, 1, &j);
|
transformed = m_module.opCompositeInsert(m_vec4Type, value, transformed, 1, &j);
|
||||||
}
|
|
||||||
|
|
||||||
transformed = m_module.opVectorTimesMatrix(m_vec4Type, transformed, m_vs.constants.texcoord[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pad the unused section of it with the value for projection.
|
transformed = m_module.opVectorTimesMatrix(m_vec4Type, transformed, m_vs.constants.texcoord[i]);
|
||||||
uint32_t lastIdx = count - 1;
|
|
||||||
uint32_t projValue = m_module.opCompositeExtract(m_floatType, transformed, 1, &lastIdx);
|
|
||||||
|
|
||||||
for (uint32_t j = count; j < 4; j++)
|
|
||||||
transformed = m_module.opCompositeInsert(m_vec4Type, projValue, transformed, 1, &j);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The projection idx is always based on the flags, even when the input mode is not DXVK_TSS_TCI_PASSTHRU.
|
||||||
|
uint32_t projValue;
|
||||||
|
if (count < 3) {
|
||||||
|
// Not enough components to do projection.
|
||||||
|
// Native drivers render normally or garbage with D3DFVF_TEXCOORDSIZE2 or D3DTTFF_COUNT <3
|
||||||
|
projValue = m_module.constf32(1.0f);
|
||||||
|
} else {
|
||||||
|
uint32_t projIdx = count - 1;
|
||||||
|
projValue = m_module.opCompositeExtract(m_floatType, transformed, 1, &projIdx);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The w component is only used for projection or unused, so always insert the component that's supposed to be divided by there.
|
||||||
|
// The fragment shader will then decide whether to project or not.
|
||||||
|
uint32_t wIdx = 3;
|
||||||
|
transformed = m_module.opCompositeInsert(m_vec4Type, projValue, transformed, 1, &wIdx);
|
||||||
|
|
||||||
m_module.opStore(m_vs.out.TEXCOORD[i], transformed);
|
m_module.opStore(m_vs.out.TEXCOORD[i], transformed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1373,20 +1399,7 @@ namespace dxvk {
|
||||||
|
|
||||||
|
|
||||||
void D3D9FFShaderCompiler::setupRenderStateInfo() {
|
void D3D9FFShaderCompiler::setupRenderStateInfo() {
|
||||||
uint32_t count;
|
m_rsBlock = SetupRenderStateBlock(m_module);
|
||||||
|
|
||||||
if (m_programType == DxsoProgramType::PixelShader) {
|
|
||||||
m_pushConstOffset = 0;
|
|
||||||
m_pushConstSize = offsetof(D3D9RenderStateInfo, pointSize);
|
|
||||||
count = 5;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
m_pushConstOffset = offsetof(D3D9RenderStateInfo, pointSize);
|
|
||||||
m_pushConstSize = sizeof(float) * 6;
|
|
||||||
count = 11;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_rsBlock = SetupRenderStateBlock(m_module, count);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1797,22 +1810,17 @@ namespace dxvk {
|
||||||
texcoord = m_module.opVectorShuffle(texcoord_t,
|
texcoord = m_module.opVectorShuffle(texcoord_t,
|
||||||
texcoord, texcoord, texcoordCnt, indices.data());
|
texcoord, texcoord, texcoordCnt, indices.data());
|
||||||
|
|
||||||
uint32_t projIdx = m_fsKey.Stages[i].Contents.ProjectedCount;
|
bool shouldProject = m_fsKey.Stages[i].Contents.Projected;
|
||||||
if (projIdx == 0)
|
|
||||||
projIdx = texcoordCnt;
|
|
||||||
else
|
|
||||||
projIdx--;
|
|
||||||
|
|
||||||
uint32_t projValue = 0;
|
uint32_t projValue = 0;
|
||||||
|
|
||||||
if (m_fsKey.Stages[i].Contents.Projected) {
|
if (shouldProject) {
|
||||||
|
// Always use w, the vertex shader puts the correct value there.
|
||||||
|
const uint32_t projIdx = 3;
|
||||||
projValue = m_module.opCompositeExtract(m_floatType, m_ps.in.TEXCOORD[i], 1, &projIdx);
|
projValue = m_module.opCompositeExtract(m_floatType, m_ps.in.TEXCOORD[i], 1, &projIdx);
|
||||||
uint32_t insertIdx = texcoordCnt - 1;
|
uint32_t insertIdx = texcoordCnt - 1;
|
||||||
texcoord = m_module.opCompositeInsert(texcoord_t, projValue, texcoord, 1, &insertIdx);
|
texcoord = m_module.opCompositeInsert(texcoord_t, projValue, texcoord, 1, &insertIdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool shouldProject = m_fsKey.Stages[i].Contents.Projected;
|
|
||||||
|
|
||||||
if (i != 0 && (
|
if (i != 0 && (
|
||||||
m_fsKey.Stages[i - 1].Contents.ColorOp == D3DTOP_BUMPENVMAP ||
|
m_fsKey.Stages[i - 1].Contents.ColorOp == D3DTOP_BUMPENVMAP ||
|
||||||
m_fsKey.Stages[i - 1].Contents.ColorOp == D3DTOP_BUMPENVMAPLUMINANCE)) {
|
m_fsKey.Stages[i - 1].Contents.ColorOp == D3DTOP_BUMPENVMAPLUMINANCE)) {
|
||||||
|
|
|
@ -59,7 +59,7 @@ namespace dxvk {
|
||||||
void DoFixedFunctionAlphaTest(SpirvModule& spvModule, const D3D9AlphaTestContext& ctx);
|
void DoFixedFunctionAlphaTest(SpirvModule& spvModule, const D3D9AlphaTestContext& ctx);
|
||||||
|
|
||||||
// Returns a render state block
|
// Returns a render state block
|
||||||
uint32_t SetupRenderStateBlock(SpirvModule& spvModule, uint32_t count);
|
uint32_t SetupRenderStateBlock(SpirvModule& spvModule);
|
||||||
|
|
||||||
struct D3D9PointSizeInfoVS {
|
struct D3D9PointSizeInfoVS {
|
||||||
uint32_t defaultValue;
|
uint32_t defaultValue;
|
||||||
|
|
|
@ -132,7 +132,7 @@ namespace dxvk {
|
||||||
VK_IMAGE_ASPECT_COLOR_BIT,
|
VK_IMAGE_ASPECT_COLOR_BIT,
|
||||||
{ VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G,
|
{ VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G,
|
||||||
VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A },
|
VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A },
|
||||||
{ D3D9ConversionFormat_L6V5U5, 1u,
|
{ D3D9ConversionFormat_L6V5U5,
|
||||||
// Convert -> float (this is a mixed snorm and unorm type)
|
// Convert -> float (this is a mixed snorm and unorm type)
|
||||||
VK_FORMAT_R16G16B16A16_SFLOAT } };
|
VK_FORMAT_R16G16B16A16_SFLOAT } };
|
||||||
|
|
||||||
|
@ -142,7 +142,7 @@ namespace dxvk {
|
||||||
VK_IMAGE_ASPECT_COLOR_BIT,
|
VK_IMAGE_ASPECT_COLOR_BIT,
|
||||||
{ VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G,
|
{ VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G,
|
||||||
VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_ONE },
|
VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_ONE },
|
||||||
{ D3D9ConversionFormat_X8L8V8U8, 1u,
|
{ D3D9ConversionFormat_X8L8V8U8,
|
||||||
// Convert -> float (this is a mixed snorm and unorm type)
|
// Convert -> float (this is a mixed snorm and unorm type)
|
||||||
VK_FORMAT_R16G16B16A16_SFLOAT } };
|
VK_FORMAT_R16G16B16A16_SFLOAT } };
|
||||||
|
|
||||||
|
@ -164,7 +164,7 @@ namespace dxvk {
|
||||||
VK_IMAGE_ASPECT_COLOR_BIT,
|
VK_IMAGE_ASPECT_COLOR_BIT,
|
||||||
{ VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G,
|
{ VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G,
|
||||||
VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A },
|
VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A },
|
||||||
{ D3D9ConversionFormat_A2W10V10U10, 1u,
|
{ D3D9ConversionFormat_A2W10V10U10,
|
||||||
// Convert -> float (this is a mixed snorm and unorm type)
|
// Convert -> float (this is a mixed snorm and unorm type)
|
||||||
VK_FORMAT_R16G16B16A16_SFLOAT } };
|
VK_FORMAT_R16G16B16A16_SFLOAT } };
|
||||||
|
|
||||||
|
@ -174,17 +174,17 @@ namespace dxvk {
|
||||||
VK_IMAGE_ASPECT_COLOR_BIT,
|
VK_IMAGE_ASPECT_COLOR_BIT,
|
||||||
{ VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G,
|
{ VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G,
|
||||||
VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_ONE },
|
VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_ONE },
|
||||||
{ D3D9ConversionFormat_W11V11U10, 1u,
|
{ D3D9ConversionFormat_W11V11U10,
|
||||||
// can't use B10G11R11 bc this is a snorm type
|
// can't use B10G11R11 bc this is a snorm type
|
||||||
VK_FORMAT_R16G16B16A16_SNORM } };
|
VK_FORMAT_R16G16B16A16_SNORM } };
|
||||||
|
|
||||||
case D3D9Format::UYVY: return {
|
case D3D9Format::UYVY: return {
|
||||||
VK_FORMAT_B8G8R8A8_UNORM,
|
VK_FORMAT_G8B8G8R8_422_UNORM,
|
||||||
VK_FORMAT_UNDEFINED,
|
VK_FORMAT_UNDEFINED,
|
||||||
VK_IMAGE_ASPECT_COLOR_BIT,
|
VK_IMAGE_ASPECT_COLOR_BIT,
|
||||||
{ VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
|
{ VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||||
VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY },
|
VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY },
|
||||||
{ D3D9ConversionFormat_UYVY, 1u }
|
{ D3D9ConversionFormat_UYVY, VK_FORMAT_B8G8R8A8_UNORM }
|
||||||
};
|
};
|
||||||
|
|
||||||
case D3D9Format::R8G8_B8G8: return {
|
case D3D9Format::R8G8_B8G8: return {
|
||||||
|
@ -193,12 +193,12 @@ namespace dxvk {
|
||||||
VK_IMAGE_ASPECT_COLOR_BIT };
|
VK_IMAGE_ASPECT_COLOR_BIT };
|
||||||
|
|
||||||
case D3D9Format::YUY2: return {
|
case D3D9Format::YUY2: return {
|
||||||
VK_FORMAT_B8G8R8A8_UNORM,
|
VK_FORMAT_G8B8G8R8_422_UNORM,
|
||||||
VK_FORMAT_UNDEFINED,
|
VK_FORMAT_UNDEFINED,
|
||||||
VK_IMAGE_ASPECT_COLOR_BIT,
|
VK_IMAGE_ASPECT_COLOR_BIT,
|
||||||
{ VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
|
{ VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||||
VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY },
|
VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY },
|
||||||
{ D3D9ConversionFormat_YUY2, 1u }
|
{ D3D9ConversionFormat_YUY2, VK_FORMAT_B8G8R8A8_UNORM }
|
||||||
};
|
};
|
||||||
|
|
||||||
case D3D9Format::G8R8_G8B8: return {
|
case D3D9Format::G8R8_G8B8: return {
|
||||||
|
@ -410,21 +410,21 @@ namespace dxvk {
|
||||||
VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R }};
|
VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R }};
|
||||||
|
|
||||||
case D3D9Format::NV12: return {
|
case D3D9Format::NV12: return {
|
||||||
VK_FORMAT_R8_UNORM,
|
VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,
|
||||||
VK_FORMAT_UNDEFINED,
|
VK_FORMAT_UNDEFINED,
|
||||||
VK_IMAGE_ASPECT_COLOR_BIT,
|
VK_IMAGE_ASPECT_COLOR_BIT,
|
||||||
{ VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
|
{ VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||||
VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY },
|
VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY },
|
||||||
{ D3D9ConversionFormat_NV12, 2u, VK_FORMAT_B8G8R8A8_UNORM }
|
{ D3D9ConversionFormat_NV12, VK_FORMAT_B8G8R8A8_UNORM }
|
||||||
};
|
};
|
||||||
|
|
||||||
case D3D9Format::YV12: return {
|
case D3D9Format::YV12: return {
|
||||||
VK_FORMAT_R8_UNORM,
|
VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM,
|
||||||
VK_FORMAT_UNDEFINED,
|
VK_FORMAT_UNDEFINED,
|
||||||
VK_IMAGE_ASPECT_COLOR_BIT,
|
VK_IMAGE_ASPECT_COLOR_BIT,
|
||||||
{ VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
|
{ VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||||
VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY },
|
VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY },
|
||||||
{ D3D9ConversionFormat_YV12, 3u, VK_FORMAT_B8G8R8A8_UNORM }
|
{ D3D9ConversionFormat_YV12, VK_FORMAT_B8G8R8A8_UNORM }
|
||||||
};
|
};
|
||||||
|
|
||||||
case D3D9Format::RAWZ: return {}; // Unsupported
|
case D3D9Format::RAWZ: return {}; // Unsupported
|
||||||
|
|
|
@ -143,7 +143,6 @@ namespace dxvk {
|
||||||
|
|
||||||
struct D3D9_CONVERSION_FORMAT_INFO {
|
struct D3D9_CONVERSION_FORMAT_INFO {
|
||||||
D3D9ConversionFormat FormatType = D3D9ConversionFormat_None;
|
D3D9ConversionFormat FormatType = D3D9ConversionFormat_None;
|
||||||
uint32_t PlaneCount = 1;
|
|
||||||
VkFormat FormatColor = VK_FORMAT_UNDEFINED;
|
VkFormat FormatColor = VK_FORMAT_UNDEFINED;
|
||||||
VkFormat FormatSrgb = VK_FORMAT_UNDEFINED;
|
VkFormat FormatSrgb = VK_FORMAT_UNDEFINED;
|
||||||
};
|
};
|
||||||
|
|
|
@ -134,7 +134,7 @@ namespace dxvk {
|
||||||
info.stage = VK_SHADER_STAGE_COMPUTE_BIT;
|
info.stage = VK_SHADER_STAGE_COMPUTE_BIT;
|
||||||
info.bindingCount = bindings.size();
|
info.bindingCount = bindings.size();
|
||||||
info.bindings = bindings.data();
|
info.bindings = bindings.data();
|
||||||
info.pushConstOffset = 0;
|
info.pushConstStages = VK_SHADER_STAGE_COMPUTE_BIT;
|
||||||
info.pushConstSize = sizeof(VkExtent2D);
|
info.pushConstSize = sizeof(VkExtent2D);
|
||||||
|
|
||||||
return new DxvkShader(info, std::move(code));
|
return new DxvkShader(info, std::move(code));
|
||||||
|
@ -142,7 +142,7 @@ namespace dxvk {
|
||||||
|
|
||||||
|
|
||||||
void D3D9FormatHelper::FlushInternal() {
|
void D3D9FormatHelper::FlushInternal() {
|
||||||
m_context->flushCommandList();
|
m_context->flushCommandList(nullptr);
|
||||||
|
|
||||||
m_transferCommands = 0;
|
m_transferCommands = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,9 +12,9 @@
|
||||||
|
|
||||||
//for some reason we need to specify __declspec(dllexport) for MinGW
|
//for some reason we need to specify __declspec(dllexport) for MinGW
|
||||||
#if defined(__WINE__) || !defined(_WIN32)
|
#if defined(__WINE__) || !defined(_WIN32)
|
||||||
#define DLLEXPORT __attribute__((visibility("default")))
|
#define DLLEXPORT __attribute__((visibility("default")))
|
||||||
#else
|
#else
|
||||||
#define DLLEXPORT
|
#define DLLEXPORT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -40,55 +40,68 @@
|
||||||
|
|
||||||
// Missed definitions in Wine/MinGW.
|
// Missed definitions in Wine/MinGW.
|
||||||
|
|
||||||
#ifndef D3DPRESENT_BACK_BUFFERS_MAX_EX
|
|
||||||
#define D3DPRESENT_BACK_BUFFERS_MAX_EX 30
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef D3DSI_OPCODE_MASK
|
|
||||||
#define D3DSI_OPCODE_MASK 0x0000FFFF
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef D3DSP_TEXTURETYPE_MASK
|
|
||||||
#define D3DSP_TEXTURETYPE_MASK 0x78000000
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef D3DUSAGE_AUTOGENMIPMAP
|
|
||||||
#define D3DUSAGE_AUTOGENMIPMAP 0x00000400L
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef D3DSP_DCL_USAGE_MASK
|
|
||||||
#define D3DSP_DCL_USAGE_MASK 0x0000000f
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef D3DSP_OPCODESPECIFICCONTROL_MASK
|
|
||||||
#define D3DSP_OPCODESPECIFICCONTROL_MASK 0x00ff0000
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef D3DSP_OPCODESPECIFICCONTROL_SHIFT
|
|
||||||
#define D3DSP_OPCODESPECIFICCONTROL_SHIFT 16
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef D3DCURSOR_IMMEDIATE_UPDATE
|
|
||||||
#define D3DCURSOR_IMMEDIATE_UPDATE 0x00000001L
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef D3DPRESENT_FORCEIMMEDIATE
|
#ifndef D3DPRESENT_FORCEIMMEDIATE
|
||||||
#define D3DPRESENT_FORCEIMMEDIATE 0x00000100L
|
#define D3DPRESENT_FORCEIMMEDIATE 0x00000100L
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef D3DSWAPEFFECT_COPY_VSYNC
|
||||||
|
#define D3DSWAPEFFECT_COPY_VSYNC 4
|
||||||
|
#endif
|
||||||
|
|
||||||
// MinGW headers are broken. Who'dve guessed?
|
// MinGW headers are broken. Who'dve guessed?
|
||||||
#ifndef _MSC_VER
|
#ifndef _MSC_VER
|
||||||
typedef struct _D3DDEVINFO_RESOURCEMANAGER
|
typedef struct _D3DDEVINFO_RESOURCEMANAGER
|
||||||
{
|
{
|
||||||
char dummy;
|
char dummy;
|
||||||
} D3DDEVINFO_RESOURCEMANAGER, * LPD3DDEVINFO_RESOURCEMANAGER;
|
} D3DDEVINFO_RESOURCEMANAGER, * LPD3DDEVINFO_RESOURCEMANAGER;
|
||||||
|
|
||||||
#ifndef __WINE__
|
|
||||||
extern "C" WINUSERAPI WINBOOL WINAPI SetProcessDPIAware(VOID);
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// This is the managed pool on D3D9Ex, it's just hidden!
|
// This is the managed pool on D3D9Ex, it's just hidden!
|
||||||
#define D3DPOOL_MANAGED_EX D3DPOOL(6)
|
#define D3DPOOL_MANAGED_EX D3DPOOL(6)
|
||||||
|
|
||||||
using D3D9VertexElements = std::vector<D3DVERTEXELEMENT9>;
|
using D3D9VertexElements = std::vector<D3DVERTEXELEMENT9>;
|
||||||
|
|
||||||
|
/////////////////////
|
||||||
|
// D3D9On12 content
|
||||||
|
/////////////////////
|
||||||
|
|
||||||
|
#include <d3d12.h>
|
||||||
|
|
||||||
|
#define MAX_D3D9ON12_QUEUES 2
|
||||||
|
|
||||||
|
struct D3D9ON12_ARGS {
|
||||||
|
BOOL Enable9On12;
|
||||||
|
IUnknown* pD3D12Device;
|
||||||
|
IUnknown* ppD3D12Queues[MAX_D3D9ON12_QUEUES];
|
||||||
|
UINT NumQueues;
|
||||||
|
UINT NodeMask;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
// Ordinal 20
|
||||||
|
typedef IDirect3D9* (WINAPI* PFN_Direct3DCreate9On12)(UINT sdk_version, D3D9ON12_ARGS* override_list, UINT override_entry_count);
|
||||||
|
IDirect3D9* WINAPI Direct3DCreate9On12(UINT sdk_version, D3D9ON12_ARGS* override_list, UINT override_entry_count);
|
||||||
|
|
||||||
|
// Ordinal 21
|
||||||
|
typedef HRESULT(WINAPI* PFN_Direct3DCreate9On12Ex)(UINT sdk_version, D3D9ON12_ARGS* override_list, UINT override_entry_count, IDirect3D9Ex** output);
|
||||||
|
HRESULT WINAPI Direct3DCreate9On12Ex(UINT sdk_version, D3D9ON12_ARGS* override_list, UINT override_entry_count, IDirect3D9Ex** output);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
MIDL_INTERFACE("e7fda234-b589-4049-940d-8878977531c8")
|
||||||
|
IDirect3DDevice9On12 : public IUnknown {
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** object) = 0;
|
||||||
|
virtual ULONG STDMETHODCALLTYPE AddRef() = 0;
|
||||||
|
virtual ULONG STDMETHODCALLTYPE Release() = 0;
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE GetD3D12Device(REFIID riid, void** object) = 0;
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE UnwrapUnderlyingResource(IDirect3DResource9* resource, ID3D12CommandQueue* command_queue, REFIID riid, void** object) = 0;
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE ReturnUnderlyingResource(IDirect3DResource9* resource, UINT num_sync, UINT64* signal_values, ID3D12Fence** fences) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef _MSC_VER
|
||||||
|
__CRT_UUID_DECL(IDirect3DDevice9On12, 0xe7fda234,0xb589,0x4049,0x94,0x0d,0x88,0x78,0x97,0x75,0x31,0xc8);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -153,7 +153,7 @@ namespace dxvk {
|
||||||
|
|
||||||
|
|
||||||
void D3D9Initializer::FlushInternal() {
|
void D3D9Initializer::FlushInternal() {
|
||||||
m_context->flushCommandList();
|
m_context->flushCommandList(nullptr);
|
||||||
|
|
||||||
m_transferCommands = 0;
|
m_transferCommands = 0;
|
||||||
m_transferMemory = 0;
|
m_transferMemory = 0;
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include "d3d9_monitor.h"
|
#include "d3d9_monitor.h"
|
||||||
#include "d3d9_caps.h"
|
#include "d3d9_caps.h"
|
||||||
#include "d3d9_device.h"
|
#include "d3d9_device.h"
|
||||||
|
#include "d3d9_bridge.h"
|
||||||
|
|
||||||
#include "../util/util_singleton.h"
|
#include "../util/util_singleton.h"
|
||||||
|
|
||||||
|
@ -13,7 +14,8 @@ namespace dxvk {
|
||||||
Singleton<DxvkInstance> g_dxvkInstance;
|
Singleton<DxvkInstance> g_dxvkInstance;
|
||||||
|
|
||||||
D3D9InterfaceEx::D3D9InterfaceEx(bool bExtended)
|
D3D9InterfaceEx::D3D9InterfaceEx(bool bExtended)
|
||||||
: m_instance ( g_dxvkInstance.acquire() )
|
: m_instance ( g_dxvkInstance.acquire(DxvkInstanceFlag::ClientApiIsD3D9) )
|
||||||
|
, m_d3d8Bridge ( this )
|
||||||
, m_extended ( bExtended )
|
, m_extended ( bExtended )
|
||||||
, m_d3d9Options ( nullptr, m_instance->config() )
|
, m_d3d9Options ( nullptr, m_instance->config() )
|
||||||
, m_d3d9Interop ( this ) {
|
, m_d3d9Interop ( this ) {
|
||||||
|
@ -86,13 +88,21 @@ namespace dxvk {
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (riid == __uuidof(IDxvkD3D8InterfaceBridge)) {
|
||||||
|
*ppvObject = ref(&m_d3d8Bridge);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
if (riid == __uuidof(ID3D9VkInteropInterface)) {
|
if (riid == __uuidof(ID3D9VkInteropInterface)) {
|
||||||
*ppvObject = ref(&m_d3d9Interop);
|
*ppvObject = ref(&m_d3d9Interop);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::warn("D3D9InterfaceEx::QueryInterface: Unknown interface query");
|
if (logQueryInterfaceError(__uuidof(IDirect3D9), riid)) {
|
||||||
Logger::warn(str::format(riid));
|
Logger::warn("D3D9InterfaceEx::QueryInterface: Unknown interface query");
|
||||||
|
Logger::warn(str::format(riid));
|
||||||
|
}
|
||||||
|
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "d3d9_adapter.h"
|
#include "d3d9_adapter.h"
|
||||||
|
#include "d3d9_bridge.h"
|
||||||
#include "d3d9_interop.h"
|
#include "d3d9_interop.h"
|
||||||
|
|
||||||
#include "../dxvk/dxvk_instance.h"
|
#include "../dxvk/dxvk_instance.h"
|
||||||
|
@ -140,6 +141,8 @@ namespace dxvk {
|
||||||
|
|
||||||
Rc<DxvkInstance> m_instance;
|
Rc<DxvkInstance> m_instance;
|
||||||
|
|
||||||
|
DxvkD3D8InterfaceBridge m_d3d8Bridge;
|
||||||
|
|
||||||
bool m_extended;
|
bool m_extended;
|
||||||
|
|
||||||
D3D9Options m_d3d9Options;
|
D3D9Options m_d3d9Options;
|
||||||
|
|
|
@ -196,12 +196,42 @@ ID3D9VkInteropDevice : public IUnknown {
|
||||||
DWORD MapFlags) = 0;
|
DWORD MapFlags) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
/**
|
||||||
struct __declspec(uuid("3461a81b-ce41-485b-b6b5-fcf08ba6a6bd")) ID3D9VkInteropInterface;
|
* \brief D3D9 current output metadata
|
||||||
struct __declspec(uuid("d56344f5-8d35-46fd-806d-94c351b472c1")) ID3D9VkInteropTexture;
|
*/
|
||||||
struct __declspec(uuid("2eaa4b89-0107-4bdb-87f7-0f541c493ce0")) ID3D9VkInteropDevice;
|
struct D3D9VkExtOutputMetadata {
|
||||||
#else
|
float RedPrimary[2];
|
||||||
|
float GreenPrimary[2];
|
||||||
|
float BluePrimary[2];
|
||||||
|
float WhitePoint[2];
|
||||||
|
float MinLuminance;
|
||||||
|
float MaxLuminance;
|
||||||
|
float MaxFullFrameLuminance;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief D3D9 extended swapchain
|
||||||
|
*/
|
||||||
|
MIDL_INTERFACE("13776e93-4aa9-430a-a4ec-fe9e281181d5")
|
||||||
|
ID3D9VkExtSwapchain : public IUnknown {
|
||||||
|
virtual BOOL STDMETHODCALLTYPE CheckColorSpaceSupport(
|
||||||
|
VkColorSpaceKHR ColorSpace) = 0;
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE SetColorSpace(
|
||||||
|
VkColorSpaceKHR ColorSpace) = 0;
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE SetHDRMetaData(
|
||||||
|
const VkHdrMetadataEXT *pHDRMetadata) = 0;
|
||||||
|
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE GetCurrentOutputDesc(
|
||||||
|
D3D9VkExtOutputMetadata *pOutputDesc) = 0;
|
||||||
|
|
||||||
|
virtual void STDMETHODCALLTYPE UnlockAdditionalFormats() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef _MSC_VER
|
||||||
__CRT_UUID_DECL(ID3D9VkInteropInterface, 0x3461a81b,0xce41,0x485b,0xb6,0xb5,0xfc,0xf0,0x8b,0xa6,0xa6,0xbd);
|
__CRT_UUID_DECL(ID3D9VkInteropInterface, 0x3461a81b,0xce41,0x485b,0xb6,0xb5,0xfc,0xf0,0x8b,0xa6,0xa6,0xbd);
|
||||||
__CRT_UUID_DECL(ID3D9VkInteropTexture, 0xd56344f5,0x8d35,0x46fd,0x80,0x6d,0x94,0xc3,0x51,0xb4,0x72,0xc1);
|
__CRT_UUID_DECL(ID3D9VkInteropTexture, 0xd56344f5,0x8d35,0x46fd,0x80,0x6d,0x94,0xc3,0x51,0xb4,0x72,0xc1);
|
||||||
__CRT_UUID_DECL(ID3D9VkInteropDevice, 0x2eaa4b89,0x0107,0x4bdb,0x87,0xf7,0x0f,0x54,0x1c,0x49,0x3c,0xe0);
|
__CRT_UUID_DECL(ID3D9VkInteropDevice, 0x2eaa4b89,0x0107,0x4bdb,0x87,0xf7,0x0f,0x54,0x1c,0x49,0x3c,0xe0);
|
||||||
|
__CRT_UUID_DECL(ID3D9VkExtSwapchain, 0x13776e93,0x4aa9,0x430a,0xa4,0xec,0xfe,0x9e,0x28,0x11,0x81,0xd5);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -101,4 +101,14 @@ extern "C" {
|
||||||
DLLEXPORT void __stdcall Direct3D9ForceHybridEnumeration(UINT uHybrid) {
|
DLLEXPORT void __stdcall Direct3D9ForceHybridEnumeration(UINT uHybrid) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DLLEXPORT IDirect3D9* __stdcall Direct3DCreate9On12(UINT sdk_version, D3D9ON12_ARGS* override_list, UINT override_entry_count) {
|
||||||
|
dxvk::Logger::warn("Direct3DCreate9On12: 9On12 functionality is unimplemented.");
|
||||||
|
return Direct3DCreate9(sdk_version);
|
||||||
|
}
|
||||||
|
|
||||||
|
DLLEXPORT HRESULT __stdcall Direct3DCreate9On12Ex(UINT sdk_version, D3D9ON12_ARGS* override_list, UINT override_entry_count, IDirect3D9Ex** output) {
|
||||||
|
dxvk::Logger::warn("Direct3DCreate9On12Ex: 9On12 functionality is unimplemented.");
|
||||||
|
return Direct3DCreate9Ex(sdk_version, output);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,7 +81,7 @@ namespace dxvk {
|
||||||
D3D9Memory (D3D9Memory&& other);
|
D3D9Memory (D3D9Memory&& other);
|
||||||
D3D9Memory& operator = (D3D9Memory&& other);
|
D3D9Memory& operator = (D3D9Memory&& other);
|
||||||
|
|
||||||
operator bool() const { return m_chunk != nullptr; }
|
explicit operator bool() const { return m_chunk != nullptr; }
|
||||||
|
|
||||||
void Map();
|
void Map();
|
||||||
void Unmap();
|
void Unmap();
|
||||||
|
@ -139,7 +139,7 @@ namespace dxvk {
|
||||||
D3D9Memory (D3D9Memory&& other);
|
D3D9Memory (D3D9Memory&& other);
|
||||||
D3D9Memory& operator = (D3D9Memory&& other);
|
D3D9Memory& operator = (D3D9Memory&& other);
|
||||||
|
|
||||||
operator bool() const { return m_ptr != nullptr; }
|
explicit operator bool() const { return m_ptr != nullptr; }
|
||||||
|
|
||||||
void Map() {}
|
void Map() {}
|
||||||
void Unmap() {}
|
void Unmap() {}
|
||||||
|
|
|
@ -27,9 +27,10 @@ namespace dxvk {
|
||||||
|
|
||||||
bool IsSupportedAdapterFormat(
|
bool IsSupportedAdapterFormat(
|
||||||
D3D9Format Format) {
|
D3D9Format Format) {
|
||||||
|
// D3D9Format::X1R5G5B5 is unsupported by native drivers and some apps,
|
||||||
|
// such as the BGE SettingsApplication, rely on it not being exposed.
|
||||||
return Format == D3D9Format::A2R10G10B10
|
return Format == D3D9Format::A2R10G10B10
|
||||||
|| Format == D3D9Format::X8R8G8B8
|
|| Format == D3D9Format::X8R8G8B8
|
||||||
|| Format == D3D9Format::X1R5G5B5
|
|
||||||
|| Format == D3D9Format::R5G6B5;
|
|| Format == D3D9Format::R5G6B5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,8 +43,6 @@ namespace dxvk {
|
||||||
return (AdapterFormat == D3D9Format::A2R10G10B10 && BackBufferFormat == D3D9Format::A2R10G10B10) ||
|
return (AdapterFormat == D3D9Format::A2R10G10B10 && BackBufferFormat == D3D9Format::A2R10G10B10) ||
|
||||||
(AdapterFormat == D3D9Format::X8R8G8B8 && BackBufferFormat == D3D9Format::X8R8G8B8) ||
|
(AdapterFormat == D3D9Format::X8R8G8B8 && BackBufferFormat == D3D9Format::X8R8G8B8) ||
|
||||||
(AdapterFormat == D3D9Format::X8R8G8B8 && BackBufferFormat == D3D9Format::A8R8G8B8) ||
|
(AdapterFormat == D3D9Format::X8R8G8B8 && BackBufferFormat == D3D9Format::A8R8G8B8) ||
|
||||||
(AdapterFormat == D3D9Format::X1R5G5B5 && BackBufferFormat == D3D9Format::X1R5G5B5) ||
|
|
||||||
(AdapterFormat == D3D9Format::X1R5G5B5 && BackBufferFormat == D3D9Format::A1R5G5B5) ||
|
|
||||||
(AdapterFormat == D3D9Format::R5G6B5 && BackBufferFormat == D3D9Format::R5G6B5);
|
(AdapterFormat == D3D9Format::R5G6B5 && BackBufferFormat == D3D9Format::R5G6B5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,8 +54,6 @@ namespace dxvk {
|
||||||
return BackBufferFormat == D3D9Format::A2R10G10B10
|
return BackBufferFormat == D3D9Format::A2R10G10B10
|
||||||
|| BackBufferFormat == D3D9Format::A8R8G8B8
|
|| BackBufferFormat == D3D9Format::A8R8G8B8
|
||||||
|| BackBufferFormat == D3D9Format::X8R8G8B8
|
|| BackBufferFormat == D3D9Format::X8R8G8B8
|
||||||
|| BackBufferFormat == D3D9Format::A1R5G5B5
|
|
||||||
|| BackBufferFormat == D3D9Format::X1R5G5B5
|
|
||||||
|| BackBufferFormat == D3D9Format::R5G6B5
|
|| BackBufferFormat == D3D9Format::R5G6B5
|
||||||
|| BackBufferFormat == D3D9Format::Unknown;
|
|| BackBufferFormat == D3D9Format::Unknown;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
#include "d3d9_on_12.h"
|
||||||
|
|
||||||
|
#include "d3d9_device.h"
|
||||||
|
|
||||||
|
namespace dxvk {
|
||||||
|
|
||||||
|
D3D9On12::D3D9On12(D3D9DeviceEx* device)
|
||||||
|
: m_device(device) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT STDMETHODCALLTYPE D3D9On12::QueryInterface(REFIID riid, void** object) {
|
||||||
|
return m_device->QueryInterface(riid, object);
|
||||||
|
}
|
||||||
|
ULONG STDMETHODCALLTYPE D3D9On12::AddRef() {
|
||||||
|
return m_device->AddRef();
|
||||||
|
}
|
||||||
|
ULONG STDMETHODCALLTYPE D3D9On12::Release() {
|
||||||
|
return m_device->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT STDMETHODCALLTYPE D3D9On12::GetD3D12Device(REFIID riid, void** object) {
|
||||||
|
InitReturnPtr(object);
|
||||||
|
|
||||||
|
Logger::err("D3D9On12::GetD3D12Device: Stub");
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
}
|
||||||
|
HRESULT STDMETHODCALLTYPE D3D9On12::UnwrapUnderlyingResource(IDirect3DResource9* resource, ID3D12CommandQueue* command_queue, REFIID riid, void** object) {
|
||||||
|
Logger::err("D3D9On12::GetD3D12Device: UnwrapUnderlyingResource: Stub");
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
}
|
||||||
|
HRESULT STDMETHODCALLTYPE D3D9On12::ReturnUnderlyingResource(IDirect3DResource9* resource, UINT num_sync, UINT64* signal_values, ID3D12Fence** fences) {
|
||||||
|
if (num_sync)
|
||||||
|
Logger::err("D3D9On12::GetD3D12Device: ReturnUnderlyingResource: Stub");
|
||||||
|
|
||||||
|
m_device->FlushAndSync9On12();
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "d3d9_include.h"
|
||||||
|
|
||||||
|
namespace dxvk {
|
||||||
|
|
||||||
|
class D3D9DeviceEx;
|
||||||
|
|
||||||
|
class D3D9On12 final : public IDirect3DDevice9On12 {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
D3D9On12(D3D9DeviceEx* device);
|
||||||
|
|
||||||
|
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** object);
|
||||||
|
ULONG STDMETHODCALLTYPE AddRef();
|
||||||
|
ULONG STDMETHODCALLTYPE Release();
|
||||||
|
|
||||||
|
HRESULT STDMETHODCALLTYPE GetD3D12Device(REFIID riid, void** object);
|
||||||
|
HRESULT STDMETHODCALLTYPE UnwrapUnderlyingResource(IDirect3DResource9* resource, ID3D12CommandQueue* command_queue, REFIID riid, void** object);
|
||||||
|
HRESULT STDMETHODCALLTYPE ReturnUnderlyingResource(IDirect3DResource9* resource, UINT num_sync, UINT64* signal_values, ID3D12Fence** fences);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
D3D9DeviceEx* m_device;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -1,3 +1,5 @@
|
||||||
|
#include "../util/util_math.h"
|
||||||
|
|
||||||
#include "d3d9_options.h"
|
#include "d3d9_options.h"
|
||||||
|
|
||||||
#include "d3d9_caps.h"
|
#include "d3d9_caps.h"
|
||||||
|
@ -35,8 +37,8 @@ namespace dxvk {
|
||||||
this->customDeviceId = parsePciId(config.getOption<std::string>("d3d9.customDeviceId"));
|
this->customDeviceId = parsePciId(config.getOption<std::string>("d3d9.customDeviceId"));
|
||||||
this->customDeviceDesc = config.getOption<std::string>("d3d9.customDeviceDesc");
|
this->customDeviceDesc = config.getOption<std::string>("d3d9.customDeviceDesc");
|
||||||
|
|
||||||
const int32_t vendorId = this->customDeviceId != -1
|
const uint32_t vendorId = this->customVendorId != -1
|
||||||
? this->customDeviceId
|
? this->customVendorId
|
||||||
: (adapter != nullptr ? adapter->deviceProperties().vendorID : 0);
|
: (adapter != nullptr ? adapter->deviceProperties().vendorID : 0);
|
||||||
|
|
||||||
this->maxFrameLatency = config.getOption<int32_t> ("d3d9.maxFrameLatency", 0);
|
this->maxFrameLatency = config.getOption<int32_t> ("d3d9.maxFrameLatency", 0);
|
||||||
|
@ -48,32 +50,37 @@ namespace dxvk {
|
||||||
this->strictPow = config.getOption<bool> ("d3d9.strictPow", true);
|
this->strictPow = config.getOption<bool> ("d3d9.strictPow", true);
|
||||||
this->lenientClear = config.getOption<bool> ("d3d9.lenientClear", false);
|
this->lenientClear = config.getOption<bool> ("d3d9.lenientClear", false);
|
||||||
this->numBackBuffers = config.getOption<int32_t> ("d3d9.numBackBuffers", 0);
|
this->numBackBuffers = config.getOption<int32_t> ("d3d9.numBackBuffers", 0);
|
||||||
this->noExplicitFrontBuffer = config.getOption<bool> ("d3d9.noExplicitFrontBuffer", false);
|
|
||||||
this->deferSurfaceCreation = config.getOption<bool> ("d3d9.deferSurfaceCreation", false);
|
this->deferSurfaceCreation = config.getOption<bool> ("d3d9.deferSurfaceCreation", false);
|
||||||
this->samplerAnisotropy = config.getOption<int32_t> ("d3d9.samplerAnisotropy", -1);
|
this->samplerAnisotropy = config.getOption<int32_t> ("d3d9.samplerAnisotropy", -1);
|
||||||
this->maxAvailableMemory = config.getOption<int32_t> ("d3d9.maxAvailableMemory", 4096);
|
this->maxAvailableMemory = config.getOption<int32_t> ("d3d9.maxAvailableMemory", 4096);
|
||||||
this->supportDFFormats = config.getOption<bool> ("d3d9.supportDFFormats", true);
|
this->supportDFFormats = config.getOption<bool> ("d3d9.supportDFFormats", vendorId != uint32_t(DxvkGpuVendor::Nvidia));
|
||||||
this->supportX4R4G4B4 = config.getOption<bool> ("d3d9.supportX4R4G4B4", true);
|
this->supportX4R4G4B4 = config.getOption<bool> ("d3d9.supportX4R4G4B4", true);
|
||||||
this->supportD32 = config.getOption<bool> ("d3d9.supportD32", true);
|
this->supportD32 = config.getOption<bool> ("d3d9.supportD32", true);
|
||||||
this->useD32forD24 = config.getOption<bool> ("d3d9.useD32forD24", false);
|
this->useD32forD24 = config.getOption<bool> ("d3d9.useD32forD24", false);
|
||||||
this->disableA8RT = config.getOption<bool> ("d3d9.disableA8RT", false);
|
this->disableA8RT = config.getOption<bool> ("d3d9.disableA8RT", false);
|
||||||
this->invariantPosition = config.getOption<bool> ("d3d9.invariantPosition", true);
|
this->invariantPosition = config.getOption<bool> ("d3d9.invariantPosition", true);
|
||||||
this->memoryTrackTest = config.getOption<bool> ("d3d9.memoryTrackTest", false);
|
this->memoryTrackTest = config.getOption<bool> ("d3d9.memoryTrackTest", false);
|
||||||
this->supportVCache = config.getOption<bool> ("d3d9.supportVCache", vendorId == 0x10de);
|
this->supportVCache = config.getOption<bool> ("d3d9.supportVCache", vendorId == uint32_t(DxvkGpuVendor::Nvidia));
|
||||||
this->enableDialogMode = config.getOption<bool> ("d3d9.enableDialogMode", false);
|
this->enableDialogMode = config.getOption<bool> ("d3d9.enableDialogMode", false);
|
||||||
this->forceSamplerTypeSpecConstants = config.getOption<bool> ("d3d9.forceSamplerTypeSpecConstants", false);
|
this->forceSamplerTypeSpecConstants = config.getOption<bool> ("d3d9.forceSamplerTypeSpecConstants", false);
|
||||||
this->forceSwapchainMSAA = config.getOption<int32_t> ("d3d9.forceSwapchainMSAA", -1);
|
this->forceSwapchainMSAA = config.getOption<int32_t> ("d3d9.forceSwapchainMSAA", -1);
|
||||||
this->forceSampleRateShading = config.getOption<bool> ("d3d9.forceSampleRateShading", false);
|
this->forceSampleRateShading = config.getOption<bool> ("d3d9.forceSampleRateShading", false);
|
||||||
this->forceAspectRatio = config.getOption<std::string> ("d3d9.forceAspectRatio", "");
|
this->forceAspectRatio = config.getOption<std::string> ("d3d9.forceAspectRatio", "");
|
||||||
this->allowDiscard = config.getOption<bool> ("d3d9.allowDiscard", true);
|
|
||||||
this->enumerateByDisplays = config.getOption<bool> ("d3d9.enumerateByDisplays", true);
|
this->enumerateByDisplays = config.getOption<bool> ("d3d9.enumerateByDisplays", true);
|
||||||
this->longMad = config.getOption<bool> ("d3d9.longMad", false);
|
this->longMad = config.getOption<bool> ("d3d9.longMad", false);
|
||||||
this->tearFree = config.getOption<Tristate> ("d3d9.tearFree", Tristate::Auto);
|
this->cachedDynamicBuffers = config.getOption<bool> ("d3d9.cachedDynamicBuffers", false);
|
||||||
this->apitraceMode = config.getOption<bool> ("d3d9.apitraceMode", false);
|
|
||||||
this->deviceLocalConstantBuffers = config.getOption<bool> ("d3d9.deviceLocalConstantBuffers", false);
|
this->deviceLocalConstantBuffers = config.getOption<bool> ("d3d9.deviceLocalConstantBuffers", false);
|
||||||
this->allowDirectBufferMapping = config.getOption<bool> ("d3d9.allowDirectBufferMapping", true);
|
this->allowDirectBufferMapping = config.getOption<bool> ("d3d9.allowDirectBufferMapping", true);
|
||||||
this->seamlessCubes = config.getOption<bool> ("d3d9.seamlessCubes", false);
|
this->seamlessCubes = config.getOption<bool> ("d3d9.seamlessCubes", false);
|
||||||
this->textureMemory = config.getOption<int32_t> ("d3d9.textureMemory", 100) << 20;
|
this->textureMemory = config.getOption<int32_t> ("d3d9.textureMemory", 100) << 20;
|
||||||
|
this->deviceLossOnFocusLoss = config.getOption<bool> ("d3d9.deviceLossOnFocusLoss", false);
|
||||||
|
this->samplerLodBias = config.getOption<float> ("d3d9.samplerLodBias", 0.0f);
|
||||||
|
this->clampNegativeLodBias = config.getOption<bool> ("d3d9.clampNegativeLodBias", false);
|
||||||
|
this->countLosableResources = config.getOption<bool> ("d3d9.countLosableResources", true);
|
||||||
|
this->reproducibleCommandStream = config.getOption<bool> ("d3d9.reproducibleCommandStream", false);
|
||||||
|
|
||||||
|
// Clamp LOD bias so that people don't abuse this in unintended ways
|
||||||
|
this->samplerLodBias = dxvk::fclamp(this->samplerLodBias, -2.0f, 1.0f);
|
||||||
|
|
||||||
std::string floatEmulation = Config::toLower(config.getOption<std::string>("d3d9.floatEmulation", "auto"));
|
std::string floatEmulation = Config::toLower(config.getOption<std::string>("d3d9.floatEmulation", "auto"));
|
||||||
if (floatEmulation == "strict") {
|
if (floatEmulation == "strict") {
|
||||||
|
@ -84,7 +91,8 @@ namespace dxvk {
|
||||||
d3d9FloatEmulation = D3D9FloatEmulation::Enabled;
|
d3d9FloatEmulation = D3D9FloatEmulation::Enabled;
|
||||||
} else {
|
} else {
|
||||||
bool hasMulz = adapter != nullptr
|
bool hasMulz = adapter != nullptr
|
||||||
&& adapter->matchesDriver(VK_DRIVER_ID_MESA_RADV, 0, 0);
|
&& (adapter->matchesDriver(VK_DRIVER_ID_MESA_RADV)
|
||||||
|
|| adapter->matchesDriver(VK_DRIVER_ID_MESA_NVK));
|
||||||
d3d9FloatEmulation = hasMulz ? D3D9FloatEmulation::Strict : D3D9FloatEmulation::Enabled;
|
d3d9FloatEmulation = hasMulz ? D3D9FloatEmulation::Strict : D3D9FloatEmulation::Enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,16 +54,6 @@ namespace dxvk {
|
||||||
/// Overrides buffer count in present parameters.
|
/// Overrides buffer count in present parameters.
|
||||||
int32_t numBackBuffers;
|
int32_t numBackBuffers;
|
||||||
|
|
||||||
/// Don't create an explicit front buffer in our own swapchain. The Vulkan swapchain is unaffected.
|
|
||||||
/// Some games don't handle front/backbuffer flipping very well because they don't always redraw
|
|
||||||
/// each frame completely, and rely on old pixel data from the previous frame to still be there.
|
|
||||||
/// When this option is set and a game only requests one backbuffer, there will be no flipping in
|
|
||||||
/// our own swapchain, so the game will always draw to the same buffer and can rely on old pixel
|
|
||||||
/// data to still be there after a Present call.
|
|
||||||
/// This means that D3D9SwapChainEx::GetFrontBufferData returns data from the backbuffer of the
|
|
||||||
/// previous frame, which is the same as the current backbuffer if only 1 backbuffer was requested.
|
|
||||||
bool noExplicitFrontBuffer;
|
|
||||||
|
|
||||||
/// Defer surface creation
|
/// Defer surface creation
|
||||||
bool deferSurfaceCreation;
|
bool deferSurfaceCreation;
|
||||||
|
|
||||||
|
@ -126,9 +116,6 @@ namespace dxvk {
|
||||||
/// Forces sample rate shading
|
/// Forces sample rate shading
|
||||||
bool forceSampleRateShading;
|
bool forceSampleRateShading;
|
||||||
|
|
||||||
/// Allow D3DLOCK_DISCARD
|
|
||||||
bool allowDiscard;
|
|
||||||
|
|
||||||
/// Enumerate adapters by displays
|
/// Enumerate adapters by displays
|
||||||
bool enumerateByDisplays;
|
bool enumerateByDisplays;
|
||||||
|
|
||||||
|
@ -137,12 +124,8 @@ namespace dxvk {
|
||||||
/// don't match entirely to the regular vertex shader in this way.
|
/// don't match entirely to the regular vertex shader in this way.
|
||||||
bool longMad;
|
bool longMad;
|
||||||
|
|
||||||
/// Tear-free mode if vsync is disabled
|
/// Cached dynamic buffers: Maps all buffers in cached memory.
|
||||||
/// Tearing mode if vsync is enabled
|
bool cachedDynamicBuffers;
|
||||||
Tristate tearFree;
|
|
||||||
|
|
||||||
/// Apitrace mode: Maps all buffers in cached memory.
|
|
||||||
bool apitraceMode;
|
|
||||||
|
|
||||||
/// Use device local memory for constant buffers.
|
/// Use device local memory for constant buffers.
|
||||||
bool deviceLocalConstantBuffers;
|
bool deviceLocalConstantBuffers;
|
||||||
|
@ -153,11 +136,30 @@ namespace dxvk {
|
||||||
/// Don't use non seamless cube maps
|
/// Don't use non seamless cube maps
|
||||||
bool seamlessCubes;
|
bool seamlessCubes;
|
||||||
|
|
||||||
|
/// Mipmap LOD bias
|
||||||
|
///
|
||||||
|
/// Enforces the given LOD bias for all samplers.
|
||||||
|
float samplerLodBias;
|
||||||
|
|
||||||
|
/// Clamps negative LOD bias
|
||||||
|
bool clampNegativeLodBias;
|
||||||
|
|
||||||
/// How much virtual memory will be used for textures (in MB).
|
/// How much virtual memory will be used for textures (in MB).
|
||||||
int32_t textureMemory;
|
int32_t textureMemory;
|
||||||
|
|
||||||
/// Shader dump path
|
/// Shader dump path
|
||||||
std::string shaderDumpPath;
|
std::string shaderDumpPath;
|
||||||
|
|
||||||
|
/// Enable emulation of device loss when a fullscreen app loses focus
|
||||||
|
bool deviceLossOnFocusLoss;
|
||||||
|
|
||||||
|
/// Disable counting losable resources and rejecting calls to Reset() if any are still alive
|
||||||
|
bool countLosableResources;
|
||||||
|
|
||||||
|
/// Ensure that for the same D3D commands the output VK commands
|
||||||
|
/// don't change between runs. Useful for comparative benchmarking,
|
||||||
|
/// can negatively affect performance.
|
||||||
|
bool reproducibleCommandStream;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,11 +41,6 @@ namespace dxvk {
|
||||||
case D3DQUERYTYPE_TIMESTAMPFREQ:
|
case D3DQUERYTYPE_TIMESTAMPFREQ:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case D3DQUERYTYPE_VERTEXSTATS:
|
|
||||||
m_query[0] = dxvkDevice->createGpuQuery(
|
|
||||||
VK_QUERY_TYPE_PIPELINE_STATISTICS, 0, 0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw DxvkError(str::format("D3D9Query: Unsupported query type ", m_queryType));
|
throw DxvkError(str::format("D3D9Query: Unsupported query type ", m_queryType));
|
||||||
}
|
}
|
||||||
|
@ -64,8 +59,11 @@ namespace dxvk {
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::warn("D3D9Query::QueryInterface: Unknown interface query");
|
if (logQueryInterfaceError(__uuidof(IDirect3DQuery9), riid)) {
|
||||||
Logger::warn(str::format(riid));
|
Logger::warn("D3D9Query::QueryInterface: Unknown interface query");
|
||||||
|
Logger::warn(str::format(riid));
|
||||||
|
}
|
||||||
|
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,6 +127,14 @@ namespace dxvk {
|
||||||
|
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE D3D9Query::GetData(void* pData, DWORD dwSize, DWORD dwGetDataFlags) {
|
HRESULT STDMETHODCALLTYPE D3D9Query::GetData(void* pData, DWORD dwSize, DWORD dwGetDataFlags) {
|
||||||
|
D3D9DeviceLock lock = m_parent->LockDevice();
|
||||||
|
|
||||||
|
bool flush = dwGetDataFlags & D3DGETDATA_FLUSH;
|
||||||
|
|
||||||
|
if (unlikely(m_parent->IsDeviceLost())) {
|
||||||
|
return flush ? D3DERR_DEVICELOST : S_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_state == D3D9_VK_QUERY_CACHED) {
|
if (m_state == D3D9_VK_QUERY_CACHED) {
|
||||||
// Query data was already retrieved once.
|
// Query data was already retrieved once.
|
||||||
// Use cached query data to prevent having to check the VK event
|
// Use cached query data to prevent having to check the VK event
|
||||||
|
@ -145,13 +151,11 @@ namespace dxvk {
|
||||||
|
|
||||||
HRESULT hr = this->GetQueryData(pData, dwSize);
|
HRESULT hr = this->GetQueryData(pData, dwSize);
|
||||||
|
|
||||||
bool flush = dwGetDataFlags & D3DGETDATA_FLUSH;
|
|
||||||
|
|
||||||
// If we get S_FALSE and it's not from the fact
|
// If we get S_FALSE and it's not from the fact
|
||||||
// they didn't call end, do some flushy stuff...
|
// they didn't call end, do some flushy stuff...
|
||||||
if (flush && hr == S_FALSE && m_state != D3D9_VK_QUERY_BEGUN) {
|
if (flush && hr == S_FALSE && m_state != D3D9_VK_QUERY_BEGUN) {
|
||||||
this->NotifyStall();
|
this->NotifyStall();
|
||||||
m_parent->FlushImplicit(FALSE);
|
m_parent->ConsiderFlush(GpuFlushType::ImplicitSynchronization);
|
||||||
}
|
}
|
||||||
|
|
||||||
return hr;
|
return hr;
|
||||||
|
@ -213,12 +217,10 @@ namespace dxvk {
|
||||||
|
|
||||||
switch (m_queryType) {
|
switch (m_queryType) {
|
||||||
case D3DQUERYTYPE_VCACHE:
|
case D3DQUERYTYPE_VCACHE:
|
||||||
// Don't know what the hell any of this means.
|
m_dataCache.VCache.Pattern = MAKEFOURCC('C', 'A', 'C', 'H');
|
||||||
// Nor do I care. This just makes games work.
|
|
||||||
m_dataCache.VCache.Pattern = MAKEFOURCC('H', 'C', 'A', 'C');
|
|
||||||
m_dataCache.VCache.OptMethod = 1;
|
m_dataCache.VCache.OptMethod = 1;
|
||||||
m_dataCache.VCache.CacheSize = 24;
|
m_dataCache.VCache.CacheSize = 16;
|
||||||
m_dataCache.VCache.MagicNumber = 20;
|
m_dataCache.VCache.MagicNumber = 7;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case D3DQUERYTYPE_OCCLUSION:
|
case D3DQUERYTYPE_OCCLUSION:
|
||||||
|
@ -237,11 +239,6 @@ namespace dxvk {
|
||||||
m_dataCache.TimestampFreq = GetTimestampQueryFrequency();
|
m_dataCache.TimestampFreq = GetTimestampQueryFrequency();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case D3DQUERYTYPE_VERTEXSTATS:
|
|
||||||
m_dataCache.VertexStats.NumRenderedTriangles = queryData[0].statistic.iaPrimitives;
|
|
||||||
m_dataCache.VertexStats.NumExtraClippingTriangles = queryData[0].statistic.clipPrimitives;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -267,7 +264,6 @@ namespace dxvk {
|
||||||
void D3D9Query::Begin(DxvkContext* ctx) {
|
void D3D9Query::Begin(DxvkContext* ctx) {
|
||||||
switch (m_queryType) {
|
switch (m_queryType) {
|
||||||
case D3DQUERYTYPE_OCCLUSION:
|
case D3DQUERYTYPE_OCCLUSION:
|
||||||
case D3DQUERYTYPE_VERTEXSTATS:
|
|
||||||
ctx->beginQuery(m_query[0]);
|
ctx->beginQuery(m_query[0]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -287,7 +283,6 @@ namespace dxvk {
|
||||||
ctx->writeTimestamp(m_query[0]);
|
ctx->writeTimestamp(m_query[0]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case D3DQUERYTYPE_VERTEXSTATS:
|
|
||||||
case D3DQUERYTYPE_OCCLUSION:
|
case D3DQUERYTYPE_OCCLUSION:
|
||||||
ctx->endQuery(m_query[0]);
|
ctx->endQuery(m_query[0]);
|
||||||
break;
|
break;
|
||||||
|
@ -305,7 +300,6 @@ namespace dxvk {
|
||||||
|
|
||||||
bool D3D9Query::QueryBeginnable(D3DQUERYTYPE QueryType) {
|
bool D3D9Query::QueryBeginnable(D3DQUERYTYPE QueryType) {
|
||||||
return QueryType == D3DQUERYTYPE_OCCLUSION
|
return QueryType == D3DQUERYTYPE_OCCLUSION
|
||||||
|| QueryType == D3DQUERYTYPE_VERTEXSTATS
|
|
||||||
|| QueryType == D3DQUERYTYPE_TIMESTAMPDISJOINT;
|
|| QueryType == D3DQUERYTYPE_TIMESTAMPDISJOINT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -329,7 +323,6 @@ namespace dxvk {
|
||||||
case D3DQUERYTYPE_TIMESTAMP:
|
case D3DQUERYTYPE_TIMESTAMP:
|
||||||
case D3DQUERYTYPE_TIMESTAMPDISJOINT:
|
case D3DQUERYTYPE_TIMESTAMPDISJOINT:
|
||||||
case D3DQUERYTYPE_TIMESTAMPFREQ:
|
case D3DQUERYTYPE_TIMESTAMPFREQ:
|
||||||
case D3DQUERYTYPE_VERTEXSTATS:
|
|
||||||
return D3D_OK;
|
return D3D_OK;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -109,8 +109,11 @@ namespace dxvk {
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::warn("D3D9Shader::QueryInterface: Unknown interface query");
|
if (logQueryInterfaceError(__uuidof(Base), riid)) {
|
||||||
Logger::warn(str::format(riid));
|
Logger::warn("D3D9Shader::QueryInterface: Unknown interface query");
|
||||||
|
Logger::warn(str::format(riid));
|
||||||
|
}
|
||||||
|
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,14 +13,14 @@ namespace dxvk {
|
||||||
enum D3D9SpecConstantId : uint32_t {
|
enum D3D9SpecConstantId : uint32_t {
|
||||||
SpecSamplerType, // 2 bits for 16 PS samplers | Bits: 32
|
SpecSamplerType, // 2 bits for 16 PS samplers | Bits: 32
|
||||||
|
|
||||||
SpecSamplerDepthMode, // 1 bit for 20 VS + PS samplers | Bits: 20
|
SpecSamplerDepthMode, // 1 bit for 21 VS + PS samplers | Bits: 21
|
||||||
SpecAlphaCompareOp, // Range: 0 -> 7 | Bits: 3
|
SpecAlphaCompareOp, // Range: 0 -> 7 | Bits: 3
|
||||||
SpecPointMode, // Range: 0 -> 3 | Bits: 2
|
SpecPointMode, // Range: 0 -> 3 | Bits: 2
|
||||||
SpecVertexFogMode, // Range: 0 -> 3 | Bits: 2
|
SpecVertexFogMode, // Range: 0 -> 3 | Bits: 2
|
||||||
SpecPixelFogMode, // Range: 0 -> 3 | Bits: 2
|
SpecPixelFogMode, // Range: 0 -> 3 | Bits: 2
|
||||||
SpecFogEnabled, // Range: 0 -> 1 | Bits: 1
|
SpecFogEnabled, // Range: 0 -> 1 | Bits: 1
|
||||||
|
|
||||||
SpecSamplerNull, // 1 bit for 20 samplers | Bits: 20
|
SpecSamplerNull, // 1 bit for 21 samplers | Bits: 21
|
||||||
SpecProjectionType, // 1 bit for 6 PS 1.x samplers | Bits: 6
|
SpecProjectionType, // 1 bit for 6 PS 1.x samplers | Bits: 6
|
||||||
SpecAlphaPrecisionBits, // Range: 0 -> 8 or 0xF | Bits: 4
|
SpecAlphaPrecisionBits, // Range: 0 -> 8 or 0xF | Bits: 4
|
||||||
|
|
||||||
|
@ -49,16 +49,16 @@ namespace dxvk {
|
||||||
static constexpr std::array<BitfieldPosition, SpecConstantCount> Layout{{
|
static constexpr std::array<BitfieldPosition, SpecConstantCount> Layout{{
|
||||||
{ 0, 0, 32 }, // SamplerType
|
{ 0, 0, 32 }, // SamplerType
|
||||||
|
|
||||||
{ 1, 0, 20 }, // SamplerDepthMode
|
{ 1, 0, 21 }, // SamplerDepthMode
|
||||||
{ 1, 20, 3 }, // AlphaCompareOp
|
{ 1, 21, 3 }, // AlphaCompareOp
|
||||||
{ 1, 23, 2 }, // PointMode
|
{ 1, 24, 2 }, // PointMode
|
||||||
{ 1, 25, 2 }, // VertexFogMode
|
{ 1, 26, 2 }, // VertexFogMode
|
||||||
{ 1, 27, 2 }, // PixelFogMode
|
{ 1, 28, 2 }, // PixelFogMode
|
||||||
{ 1, 29, 1 }, // FogEnabled
|
{ 1, 30, 1 }, // FogEnabled
|
||||||
|
|
||||||
{ 2, 0, 20 }, // SamplerNull
|
{ 2, 0, 21 }, // SamplerNull
|
||||||
{ 2, 20, 6 }, // ProjectionType
|
{ 2, 21, 6 }, // ProjectionType
|
||||||
{ 2, 26, 4 }, // AlphaPrecisionBits
|
{ 2, 27, 4 }, // AlphaPrecisionBits
|
||||||
|
|
||||||
{ 3, 0, 16 }, // VertexShaderBools
|
{ 3, 0, 16 }, // VertexShaderBools
|
||||||
{ 3, 16, 16 }, // PixelShaderBools
|
{ 3, 16, 16 }, // PixelShaderBools
|
||||||
|
|
|
@ -4,17 +4,25 @@
|
||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
D3D9CapturableState::D3D9CapturableState() {
|
template <template <typename T> typename ItemType>
|
||||||
for (uint32_t i = 0; i < streamFreq.size(); i++)
|
D3D9State<ItemType>::D3D9State() {
|
||||||
streamFreq[i] = 1;
|
for (uint32_t i = 0; i < streamFreq.size(); i++)
|
||||||
|
streamFreq[i] = 1;
|
||||||
|
|
||||||
for (uint32_t i = 0; i < enabledLightIndices.size(); i++)
|
for (uint32_t i = 0; i < enabledLightIndices.size(); i++)
|
||||||
enabledLightIndices[i] = UINT32_MAX;
|
enabledLightIndices[i] = UINT32_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
D3D9CapturableState::~D3D9CapturableState() {
|
|
||||||
for (uint32_t i = 0; i < textures.size(); i++)
|
template <template <typename T> typename ItemType>
|
||||||
TextureChangePrivate(textures[i], nullptr);
|
D3D9State<ItemType>::~D3D9State() {
|
||||||
}
|
if (textures) {
|
||||||
|
for (uint32_t i = 0; i < textures->size(); i++)
|
||||||
|
TextureChangePrivate(textures[i], nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template struct D3D9State<dynamic_item>;
|
||||||
|
template struct D3D9State<static_item>;
|
||||||
|
|
||||||
}
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue