Compare commits
1 Commits
Author | SHA1 | Date |
---|---|---|
Hans-Kristian Arntzen | c8f53852f4 |
|
@ -1,31 +0,0 @@
|
||||||
name: Artifacts (Package)
|
|
||||||
|
|
||||||
on: [push, pull_request, workflow_dispatch]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build-artifacts:
|
|
||||||
runs-on: ubuntu-20.04
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
id: checkout-code
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
|
|
||||||
- name: Build release
|
|
||||||
id: build-release
|
|
||||||
uses: Joshua-Ashton/arch-mingw-github-action@v8
|
|
||||||
with:
|
|
||||||
command: |
|
|
||||||
export VERSION_NAME="${GITHUB_REF##*/}-${GITHUB_SHA##*/}"
|
|
||||||
./package-release.sh ${VERSION_NAME} build --no-package
|
|
||||||
echo "VERSION_NAME=${VERSION_NAME}" >> $GITHUB_ENV
|
|
||||||
|
|
||||||
- name: Upload artifacts
|
|
||||||
id: upload-artifacts
|
|
||||||
uses: actions/upload-artifact@v2
|
|
||||||
with:
|
|
||||||
name: vkd3d-proton-${{ env.VERSION_NAME }}
|
|
||||||
path: build/vkd3d-proton-${{ env.VERSION_NAME }}
|
|
||||||
if-no-files-found: error
|
|
|
@ -1,75 +0,0 @@
|
||||||
name: Test Builds on Linux
|
|
||||||
|
|
||||||
on: [push, pull_request, workflow_dispatch]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build-set-linux:
|
|
||||||
runs-on: ubuntu-20.04
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
id: checkout-code
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
|
|
||||||
- name: Setup problem matcher
|
|
||||||
uses: Joshua-Ashton/gcc-problem-matcher@v1
|
|
||||||
|
|
||||||
- name: Build MinGW x86
|
|
||||||
id: build-mingw-x86
|
|
||||||
uses: Joshua-Ashton/arch-mingw-github-action@v8
|
|
||||||
with:
|
|
||||||
command: |
|
|
||||||
meson -Denable_tests=True -Denable_extras=True --cross-file=build-win32.txt --buildtype release build-mingw-x86
|
|
||||||
ninja -C build-mingw-x86
|
|
||||||
|
|
||||||
- name: Build MinGW x64
|
|
||||||
id: build-mingw-x64
|
|
||||||
uses: Joshua-Ashton/arch-mingw-github-action@v8
|
|
||||||
with:
|
|
||||||
command: |
|
|
||||||
meson -Denable_tests=True -Denable_extras=True --cross-file=build-win64.txt --buildtype release build-mingw-x64
|
|
||||||
ninja -C build-mingw-x64
|
|
||||||
|
|
||||||
- name: Build Native GCC x86
|
|
||||||
id: build-native-gcc-x86
|
|
||||||
uses: Joshua-Ashton/arch-mingw-github-action@v8
|
|
||||||
with:
|
|
||||||
command: |
|
|
||||||
export CC="gcc -m32"
|
|
||||||
export CXX="g++ -m32"
|
|
||||||
export PKG_CONFIG_PATH="/usr/lib32/pkgconfig:/usr/lib/i386-linux-gnu/pkgconfig:/usr/lib/pkgconfig"
|
|
||||||
meson -Denable_tests=True -Denable_extras=True --buildtype release build-native-gcc-x86
|
|
||||||
ninja -C build-native-gcc-x86
|
|
||||||
|
|
||||||
- name: Build Native GCC x64
|
|
||||||
id: build-native-gcc-x64
|
|
||||||
uses: Joshua-Ashton/arch-mingw-github-action@v8
|
|
||||||
with:
|
|
||||||
command: |
|
|
||||||
export CC="gcc"
|
|
||||||
export CXX="g++"
|
|
||||||
meson -Denable_tests=True -Denable_extras=True --buildtype release build-native-gcc-x64
|
|
||||||
ninja -C build-native-gcc-x64
|
|
||||||
|
|
||||||
- name: Build Native Clang x86
|
|
||||||
id: build-native-clang-x86
|
|
||||||
uses: Joshua-Ashton/arch-mingw-github-action@v8
|
|
||||||
with:
|
|
||||||
command: |
|
|
||||||
export CC="clang -m32"
|
|
||||||
export CXX="clang++ -m32"
|
|
||||||
export PKG_CONFIG_PATH="/usr/lib32/pkgconfig:/usr/lib/i386-linux-gnu/pkgconfig:/usr/lib/pkgconfig"
|
|
||||||
meson -Denable_tests=True -Denable_extras=True --buildtype release build-native-clang-x86
|
|
||||||
ninja -C build-native-clang-x86
|
|
||||||
|
|
||||||
- name: Build Native Clang x64
|
|
||||||
id: build-native-clang-x64
|
|
||||||
uses: Joshua-Ashton/arch-mingw-github-action@v8
|
|
||||||
with:
|
|
||||||
command: |
|
|
||||||
export CC="clang"
|
|
||||||
export CXX="clang++"
|
|
||||||
meson -Denable_tests=True -Denable_extras=True --buildtype release build-native-clang-x64
|
|
||||||
ninja -C build-native-clang-x64
|
|
|
@ -1,53 +0,0 @@
|
||||||
name: Test Builds on Windows
|
|
||||||
|
|
||||||
on: [push, pull_request, workflow_dispatch]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build-set-windows:
|
|
||||||
runs-on: windows-2022
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
id: checkout-code
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
|
|
||||||
- name: Setup widl and glslangValidator
|
|
||||||
shell: pwsh
|
|
||||||
run: |
|
|
||||||
choco install strawberryperl vulkan-sdk -y
|
|
||||||
Write-Output "C:\Strawberry\c\bin" | Out-File -FilePath "${Env:GITHUB_PATH}" -Append
|
|
||||||
Write-Output "$([System.Environment]::GetEnvironmentVariable('VULKAN_SDK', 'Machine'))\Bin" `
|
|
||||||
| Out-File -FilePath "${Env:GITHUB_PATH}" -Append
|
|
||||||
|
|
||||||
- name: Setup Meson
|
|
||||||
shell: pwsh
|
|
||||||
run: pip install meson
|
|
||||||
|
|
||||||
- name: Find Visual Studio
|
|
||||||
shell: pwsh
|
|
||||||
run: |
|
|
||||||
$installationPath = Get-VSSetupInstance `
|
|
||||||
| Select-VSSetupInstance -Require Microsoft.VisualStudio.Workload.NativeDesktop -Latest `
|
|
||||||
| Select-Object -ExpandProperty InstallationPath
|
|
||||||
Write-Output "VSDEVCMD=${installationPath}\Common7\Tools\VsDevCmd.bat" `
|
|
||||||
| Out-File -FilePath "${Env:GITHUB_ENV}" -Append
|
|
||||||
|
|
||||||
- name: Build MSVC x86
|
|
||||||
shell: pwsh
|
|
||||||
run: |
|
|
||||||
& "${Env:COMSPEC}" /s /c "`"${Env:VSDEVCMD}`" -arch=x86 -host_arch=x64 -no_logo && set" `
|
|
||||||
| % { , ($_ -Split '=', 2) } `
|
|
||||||
| % { [System.Environment]::SetEnvironmentVariable($_[0], $_[1]) }
|
|
||||||
meson -Denable_tests=True -Denable_extras=True --buildtype release --backend vs2022 build-msvc-x86
|
|
||||||
msbuild -m build-msvc-x86/vkd3d-proton.sln
|
|
||||||
|
|
||||||
- name: Build MSVC x64
|
|
||||||
shell: pwsh
|
|
||||||
run: |
|
|
||||||
& "${Env:COMSPEC}" /s /c "`"${Env:VSDEVCMD}`" -arch=x64 -host_arch=x64 -no_logo && set" `
|
|
||||||
| % { , ($_ -Split '=', 2) } `
|
|
||||||
| % { [System.Environment]::SetEnvironmentVariable($_[0], $_[1]) }
|
|
||||||
meson -Denable_tests=True -Denable_extras=True --buildtype release --backend vs2022 build-msvc-x64
|
|
||||||
msbuild -m build-msvc-x64/vkd3d-proton.sln
|
|
|
@ -1,5 +1,28 @@
|
||||||
build
|
aclocal.m4
|
||||||
build.*
|
autom4te.cache
|
||||||
vkd3d-proton-*.tar.zst
|
config.log
|
||||||
vkd3d-proton-*/
|
config.status
|
||||||
|
configure
|
||||||
|
libtool
|
||||||
|
Makefile
|
||||||
|
Makefile.in
|
||||||
|
test-suite.log
|
||||||
|
vkd3d-compiler
|
||||||
|
|
||||||
|
vkd3d-*.tar.xz
|
||||||
|
|
||||||
|
*.exe
|
||||||
|
*.la
|
||||||
|
*.lo
|
||||||
|
*.log
|
||||||
|
*.o
|
||||||
|
*.pc
|
||||||
|
*.trs
|
||||||
|
*~
|
||||||
|
|
||||||
|
.deps
|
||||||
|
.dirstamp
|
||||||
|
.libs
|
||||||
|
build
|
||||||
|
build.native
|
||||||
|
build.cross
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
vkd3d:
|
||||||
|
variables:
|
||||||
|
GIT_SUBMODULE_STRATEGY: recursive
|
||||||
|
script:
|
||||||
|
- ./package-release.sh release build --no-package
|
||||||
|
artifacts:
|
||||||
|
name: "vkd3d-${CI_COMMIT_REF_NAME}.${CI_COMMIT_SHA}"
|
||||||
|
paths:
|
||||||
|
- build/vkd3d-release
|
4
.mailmap
4
.mailmap
|
@ -1,4 +0,0 @@
|
||||||
Conor McCarthy <cmccarthy@codeweavers.com>
|
|
||||||
Ivan Fedorov <ifedorov@nvidia.com>
|
|
||||||
James Beddek <telans@protonmail.com>
|
|
||||||
Roshan Chaudhari <rochaudhari@nvidia.com>
|
|
33
AUTHORS
33
AUTHORS
|
@ -1,34 +1,7 @@
|
||||||
Alexander Gabello
|
|
||||||
Alexandre Julliard
|
|
||||||
Andrew Eikum
|
|
||||||
Arkadiusz Hiler
|
|
||||||
Biswapriyo Nath
|
|
||||||
Chip Davis
|
Chip Davis
|
||||||
Conor McCarthy
|
|
||||||
Danylo Piliaiev
|
|
||||||
David Gow
|
|
||||||
David McCloskey
|
|
||||||
Derek Lesho
|
|
||||||
Fabian Bornschein
|
|
||||||
Georg Lehmann
|
|
||||||
Hans-Kristian Arntzen
|
|
||||||
Henri Verbeet
|
Henri Verbeet
|
||||||
Ivan Fedorov
|
|
||||||
Jactry Zeng
|
|
||||||
James Beddek
|
|
||||||
Jens Peters
|
|
||||||
Joshua Ashton
|
|
||||||
Józef Kucia
|
Józef Kucia
|
||||||
Juuso Alasuutari
|
|
||||||
Krzysztof Bogacki
|
|
||||||
Paul Gofman
|
|
||||||
Philip Rebohle
|
|
||||||
Rémi Bernon
|
|
||||||
Robin Kertels
|
|
||||||
Rodrigo Locatti
|
|
||||||
Roshan Chaudhari
|
|
||||||
Samuel Pitoiset
|
|
||||||
Sveinar Søpler
|
|
||||||
Sven Hesse
|
Sven Hesse
|
||||||
Thomas Crider
|
Hans-Kristian Arntzen
|
||||||
Zhiyi Zhang
|
Philip Rebohle
|
||||||
|
Joshua Ashton
|
||||||
|
|
388
CHANGELOG.md
388
CHANGELOG.md
|
@ -1,388 +0,0 @@
|
||||||
# Change Log
|
|
||||||
|
|
||||||
## 2.6
|
|
||||||
|
|
||||||
It has been a long while since 2.5, and this release rolls up a lot of fixes, features and optimizations.
|
|
||||||
|
|
||||||
### Fixes
|
|
||||||
|
|
||||||
- Fix black screen rendering bug in Horizon Zero Dawn after latest game updates.
|
|
||||||
- Fix crashes on startup in Final Fantasy VII: Remake and Warframe.
|
|
||||||
- Fix crashes in Guardians of the Galaxy when interacting with certain game objects.
|
|
||||||
- Fix hang on game shutdown in Elden Ring.
|
|
||||||
- Fix broken geometry rendering in Age of Empires: IV.
|
|
||||||
|
|
||||||
### Optimization
|
|
||||||
|
|
||||||
- Improve generated shader code for vectorized load-store operations in DXIL.
|
|
||||||
- Greatly reduce CPU overhead for descriptor copy operations,
|
|
||||||
which is a key contributor to CPU overhead in D3D12.
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
#### Pipeline library rewrite
|
|
||||||
|
|
||||||
Support D3D12 pipeline libraries better where we can now also cache
|
|
||||||
generated SPIR-V from DXBC/DXIL.
|
|
||||||
Massively reduces subsequent load times in Monster Hunter: Rise,
|
|
||||||
and helps other titles like Guardian of the Galaxy and Elden Ring.
|
|
||||||
Also lays the groundwork for internal driver caches down the line for games which do not use this API.
|
|
||||||
Also, deduplicates binary blobs for reduced disk size requirements.
|
|
||||||
|
|
||||||
#### Shader models
|
|
||||||
|
|
||||||
Shader model 6.6 is now fully implemented. This includes support for:
|
|
||||||
- ResourceDescriptorHeap[] direct access
|
|
||||||
- 64-bit atomics
|
|
||||||
- IsHelperLane()
|
|
||||||
- Compute shader derivatives
|
|
||||||
- WaveSize attribute
|
|
||||||
- Packed math intrinsics
|
|
||||||
|
|
||||||
#### Minor features
|
|
||||||
|
|
||||||
- Handle API feature MinResourceLODClamp correctly if `VK_EXT_image_view_min_lod` is supported.
|
|
||||||
- Expose CastFullyTypedFormat feature.
|
|
||||||
- Expose some advanced shader features on Intel related to UAV formats (`VK_KHR_format_feature_flags2`).
|
|
||||||
- Support COLOR -> STENCIL copies.
|
|
||||||
|
|
||||||
### Workarounds
|
|
||||||
|
|
||||||
- Workaround DEATHLOOP not emitting synchronization commands correctly. Fixes menu flicker on RADV.
|
|
||||||
- Workaround quirky API usage in Elden Ring. Removes many kinds of stutter and chug when traversing the scenery.
|
|
||||||
- Workaround certain environments failing to create Vulkan device if some `VK_NVX_*` extensions are enabled.
|
|
||||||
- Workaround glitched foliage rendering in Horizon Zero Dawn after latest game updates.
|
|
||||||
- Workaround some questionable UE4 shaders causing glitched rendering on RADV.
|
|
||||||
|
|
||||||
### Note on future Vulkan driver requirements
|
|
||||||
|
|
||||||
2.6 is expected to be the last vkd3d-proton release before we require some newer Vulkan extensions.
|
|
||||||
`VK_KHR_dynamic_rendering` and `VK_EXT_extended_dynamic_state`
|
|
||||||
(and likely `dynamic_state_2` as well) will be required.
|
|
||||||
|
|
||||||
`VK_KHR_dynamic_rendering` in particular requires up-to-date drivers and the legacy render pass path
|
|
||||||
will be abandoned in favor of it. Supporting both paths at the same time is not practical.
|
|
||||||
Moving to `VK_KHR_dynamic_rendering` allows us to fix some critical flaws with the legacy API
|
|
||||||
which caused potential shader compilation stutters and extra CPU overhead.
|
|
||||||
|
|
||||||
## 2.5
|
|
||||||
|
|
||||||
This is a release with a little bit of everything!
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
#### DXR progress
|
|
||||||
|
|
||||||
DXR has seen significant work in the background.
|
|
||||||
|
|
||||||
- DXR 1.1 is now experimentally exposed. It can be enabled with `VKD3D_CONFIG=dxr11`.
|
|
||||||
Note that DXR 1.1 cannot be fully implemented in `VK_KHR_ray_tracing`'s current form, in particular
|
|
||||||
DispatchRays() indirect is not compatible yet,
|
|
||||||
although we have not observed a game which requires this API feature.
|
|
||||||
- DXR 1.1 inline raytracing support is fully implemented.
|
|
||||||
- DXR 1.0 support is more or less feature complete.
|
|
||||||
Some weird edge cases remain, but will likely not be implemented unless required by a game.
|
|
||||||
`VKD3D_CONFIG=dxr` will eventually be dropped when it matures.
|
|
||||||
|
|
||||||
Some new DXR games are starting to come alive, especially with DXR 1.1 enabled,
|
|
||||||
but there are significant bugs as well that we currently cannot easily debug.
|
|
||||||
Some experimental results on NVIDIA:
|
|
||||||
|
|
||||||
- **Control** - already worked
|
|
||||||
- **DEATHLOOP** - appears to work correctly
|
|
||||||
- **Cyberpunk 2077** - DXR can be enabled, but GPU timeouts
|
|
||||||
- **World of Warcraft** - according to a user, it works, but we have not confirmed ourselves
|
|
||||||
- **Metro Exodus: Enhanced Edition** -
|
|
||||||
gets ingame and appears to work? Not sure if it looks correct.
|
|
||||||
Heavy CPU stutter for some reason ...
|
|
||||||
- **Metro Exodus** (original release) - GPU timeouts when enabling DXR
|
|
||||||
- **Resident Evil: Village** - Appears to work, but the visual difference is subtle.
|
|
||||||
|
|
||||||
It's worth experimenting with these and others.
|
|
||||||
DXR is incredibly complicated, so expect bugs.
|
|
||||||
From here, DXR support is mostly a case of stamping out issues one by one.
|
|
||||||
|
|
||||||
#### NVIDIA DLSS
|
|
||||||
|
|
||||||
NVIDIA contributed integration APIs in vkd3d-proton which enables DLSS support in D3D12 titles in Proton.
|
|
||||||
See Proton documentation for how to enable NvAPI support.
|
|
||||||
|
|
||||||
#### Shader models
|
|
||||||
|
|
||||||
A fair bit of work went into DXIL translation support to catch up with native drivers.
|
|
||||||
|
|
||||||
- Shader model 6.5 is exposed.
|
|
||||||
Shader model 6.6 should be straight forward once that becomes relevant.
|
|
||||||
- Shader model 6.4 implementation takes advantage of `VK_KHR_shader_integer_dot_product` when supported.
|
|
||||||
- Proper fallback for FP16 math on GPUs which do not expose native FP16 support (Polaris, Pascal).
|
|
||||||
Notably fixes AMD FSR shaders in Resident Evil: Village (and others).
|
|
||||||
- Shader model 6.1 SV_Barycentric support implemented (NVIDIA only for now).
|
|
||||||
- Support shader model 6.2 FP32 denorm control.
|
|
||||||
|
|
||||||
### Performance
|
|
||||||
|
|
||||||
Resizable BAR can improve GPU performance about 10-15% in the best case, depends a lot on the game.
|
|
||||||
Horizon Zero Dawn and Death Stranding in particular improve massively with this change.
|
|
||||||
|
|
||||||
By default, vkd3d-proton will now take advantage of PCI-e BAR memory types through heuristics
|
|
||||||
as D3D12 does not expose direct support for resizable BAR, and native D3D12 drivers are known to use heuristics as well.
|
|
||||||
Without resizable BAR enabled in BIOS/vBIOS, we only get 256 MiB which can help performance,
|
|
||||||
but many games will improve performance even more
|
|
||||||
when we are allowed to use more than that.
|
|
||||||
There is an upper limit for how much VRAM is dedicated to this purpose.
|
|
||||||
We also added `VKD3D_CONFIG=no_upload_hvv` to disable all uses of PCI-e BAR memory.
|
|
||||||
|
|
||||||
Other performance improvements:
|
|
||||||
|
|
||||||
- Avoid redundant descriptor update work in certain scenarios (NVIDIA contribution).
|
|
||||||
- Minor tweaks here and there to reduce CPU overhead.
|
|
||||||
|
|
||||||
### Fixes and workarounds
|
|
||||||
|
|
||||||
- Fix behavior for swap chain presentation latency HANDLE. Fixes spurious deadlocks in some cases.
|
|
||||||
- Fix many issues related to depth-stencil handling, which fixed various issues in DEATHLOOP, F1 2021, WRC 10.
|
|
||||||
- Fix DIRT 5 rendering issues and crashes. Should be fully playable now.
|
|
||||||
- Fix some Diablo II Resurrected rendering issues.
|
|
||||||
- Workaround shader bugs in Psychonauts 2.
|
|
||||||
- Workaround some Unreal Engine 4 shader bugs which multiple titles trigger.
|
|
||||||
- Fix some stability issues when VRAM is exhausted on NVIDIA.
|
|
||||||
- Fix CPU crash in boot-up sequence of Far Cry 6 (game is still kinda buggy though, but gets in-game).
|
|
||||||
- Fix various bugs with host visible images. Fixes DEATHLOOP.
|
|
||||||
- Fix various DXIL conversion bugs.
|
|
||||||
- Add Invariant geometry workarounds for specific games which require it.
|
|
||||||
- Fix how d3d12.dll exports symbols to be more in line with MSVC.
|
|
||||||
- Fix some edge cases in bitfield instructions.
|
|
||||||
- Work around extreme CPU memory bloat on the specific NVIDIA driver versions which had this bug.
|
|
||||||
- Fix regression in Evil Genius 2: World Domination.
|
|
||||||
- Fix crashes in Hitman 3.
|
|
||||||
- Fix terrain rendering in Anno 1800.
|
|
||||||
- Various correctness and crash fixes.
|
|
||||||
|
|
||||||
## 2.4
|
|
||||||
|
|
||||||
This is a release which focuses on performance and bug-fixes.
|
|
||||||
|
|
||||||
### Performance
|
|
||||||
|
|
||||||
- Improve swapchain latency and frame pacing by up to one frame.
|
|
||||||
- Optimize lookup of format info.
|
|
||||||
- Avoid potential pipeline compilation stutter in certain scenarios.
|
|
||||||
- Rewrite how we handle image layouts for color and depth-stencil targets.
|
|
||||||
Allows us to remove a lot of dumb
|
|
||||||
barriers giving significant GPU-bound performance improvements.
|
|
||||||
~15%-20% GPU bound uplift in Horizon Zero Dawn,
|
|
||||||
~10% in Death Stranding,
|
|
||||||
and 5%-10% improvements in many other titles.
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
- Enable support for sparse 3D textures (tiled resources tier 3).
|
|
||||||
|
|
||||||
### Bug fixes and workarounds
|
|
||||||
|
|
||||||
- Various bug fixes in DXIL.
|
|
||||||
- Fix weird bug where sun would pop through walls in RE: Village.
|
|
||||||
- Workaround game bug in Cyberpunk 2077 where certain locales would render a black screen.
|
|
||||||
- Fix various bugs (in benchmark and in vkd3d-proton) allowing GravityMark to run.
|
|
||||||
- Improve robustness against certain app bugs related to NULL descriptors.
|
|
||||||
- Fix bug with constant FP64 vector handling in DXBC.
|
|
||||||
- Fix bug where Cyberpunk 2077 inventory screen could spuriously hang GPU on RADV.
|
|
||||||
- Add workaround for Necromunda: Hired Gun where character models would render random garbage on RADV.
|
|
||||||
- Fix bug in Necromunda: Hired Gun causing random screen flicker.
|
|
||||||
- Fix windowed mode tracking when leaving fullscreen. Fix Alt-Tab handling in Horizon Zero Dawn.
|
|
||||||
- Temporary workaround for SRV ResourceMinLODClamp. Fix black ground rendering in DIRT 5.
|
|
||||||
The overbright HDR rendering in DIRT 5 sadly persists however :(
|
|
||||||
- Implement fallback maximum swapchain latency correctly.
|
|
||||||
|
|
||||||
### Development features
|
|
||||||
|
|
||||||
Various features which are useful for developers were added to aid debugging.
|
|
||||||
|
|
||||||
- Descriptor QA can instrument shaders in runtime for GPU-assisted validation.
|
|
||||||
Performance is good enough (> 40 FPS) that games are actually playable in this mode.
|
|
||||||
See README for details.
|
|
||||||
- Allow forcing off CONCURRENT queue, and using EXCLUSIVE queue.
|
|
||||||
Not valid, but can be useful as a speed hack on Polaris when `single_queue` is not an option
|
|
||||||
and for testing driver behavior differences.
|
|
||||||
|
|
||||||
## 2.3.1
|
|
||||||
|
|
||||||
This is a minor bugfix release to address some issues solved shortly after the last release.
|
|
||||||
|
|
||||||
### Fixes
|
|
||||||
|
|
||||||
- Improved support for older Wine and Vulkan Loader versions.
|
|
||||||
- Fix blocky shadows in Horizon Zero Dawn.
|
|
||||||
- Fix the install script failing on Wine installs not built with upstream vkd3d.
|
|
||||||
- Fix minor dxil translation issues.
|
|
||||||
|
|
||||||
## 2.3
|
|
||||||
|
|
||||||
This release adds support for more D3D12 features and greatly improves GPU bound performance
|
|
||||||
in many scenarios.
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
#### Early DXR 1.0 support
|
|
||||||
|
|
||||||
`VK_KHR_raytracing` is used to enable cross-vendor ray-tracing support.
|
|
||||||
The implementation is WIP, but it is good enough to run some real content.
|
|
||||||
|
|
||||||
As of writing, only the NVIDIA driver works correctly.
|
|
||||||
It is expected AMD RDNA2 GPUs will work when working drivers are available
|
|
||||||
(amdgpu-pro 21.10 is known to not work).
|
|
||||||
|
|
||||||
Games which are expected to work include:
|
|
||||||
- Control (appears to be fully working)
|
|
||||||
- Ghostrunner (seems to work, not exhaustively tested)
|
|
||||||
|
|
||||||
To enable DXR support, `VKD3D_CONFIG=dxr %command%` should be used when launching game.
|
|
||||||
Certain games may be unstable if DXR is enabled by default.
|
|
||||||
|
|
||||||
#### Conservative rasterization
|
|
||||||
|
|
||||||
Full support (tier 3) for conservative rasterization was added.
|
|
||||||
|
|
||||||
#### Variable rate shading
|
|
||||||
|
|
||||||
Full support (tier 2) for variable rate shading was added.
|
|
||||||
|
|
||||||
#### Command list bundles
|
|
||||||
|
|
||||||
Allows Kingdom Hearts remaster to get past the errors, unsure if game fully works yet.
|
|
||||||
|
|
||||||
#### Write Watch and APITrace
|
|
||||||
|
|
||||||
Support for `D3D12_HEAP_FLAG_ALLOW_WRITE_WATCH` has been added.
|
|
||||||
This means [APITraces](https://github.com/Joshua-Ashton/apitrace/releases) of titles can now be captured.
|
|
||||||
|
|
||||||
### Performance
|
|
||||||
|
|
||||||
- Improve GPU bound performance in RE2 by up to 20% on NVIDIA.
|
|
||||||
- Enable async compute queues. Greatly improves GPU performance and frame pacing in many titles.
|
|
||||||
Horizon Zero Dawn and Death Stranding see exceptional gains with this fix,
|
|
||||||
due to how the engines work. GPU utilization should now reach ~100%.
|
|
||||||
For best results, AMD Navi+ GPUs are recommended, but Polaris and earlier still
|
|
||||||
see great results. It is possible to disable this path, if for whatever reason
|
|
||||||
multiple queues are causing issues. See README.
|
|
||||||
- Optimize bindless constant buffer GPU-bound performance on NVIDIA if certain API code paths are used.
|
|
||||||
- Optimize sparse binding CPU overhead.
|
|
||||||
- `TRACE` logging calls are disabled by default on release builds.
|
|
||||||
|
|
||||||
### Fixes and workarounds
|
|
||||||
|
|
||||||
- Fix various DXIL bugs.
|
|
||||||
- Be more robust against broken pipeline creation API calls.
|
|
||||||
Avoids driver crashes in Forza Horizon 4.
|
|
||||||
- Workaround some buggy shaders in F1 2020.
|
|
||||||
- Fix bugs if depth bounds test is used in certain ways.
|
|
||||||
- Fix a read out-of-bounds in `UpdateTileMappings`.
|
|
||||||
- Fix `SV_ClipDistance` and `SV_CullDistance` in Hull Shaders.
|
|
||||||
|
|
||||||
## 2.2
|
|
||||||
|
|
||||||
This release is mostly a maintenance release which fixes bugs and regressions.
|
|
||||||
It also unblocks significant future feature development.
|
|
||||||
|
|
||||||
### Workaround removals
|
|
||||||
|
|
||||||
- Replace old `force_bindless_texel_buffer` workaround with
|
|
||||||
a more correct and performant implementation.
|
|
||||||
Death Stranding and Cyberpunk 2077 (and probably other games as well) do the right thing by default without the hack now.
|
|
||||||
- Remove old workaround `disable_query_optimization` for occlusion queries which was enabled for AC: Valhalla,
|
|
||||||
and is now replaced by a correct and efficient implementation.
|
|
||||||
|
|
||||||
#### Cyberpunk 2077 status
|
|
||||||
From recent testing on our end, it is unknown at this time if `VK_VALVE_mutable_descriptor_type` is still required for
|
|
||||||
Cyberpunk 2077. Manual testing hasn't been able to trigger a GPU hang.
|
|
||||||
The memory allocation rewrite in 2.2 can plausibly work around some of the bugs that `VK_VALVE_mutable_descriptor_type` fixed by accident.
|
|
||||||
The bugs in question could also have been fixed since release day, but we cannot prove this since the bug is completely random in nature.
|
|
||||||
|
|
||||||
### Regression fixes
|
|
||||||
|
|
||||||
- Fix regression in Horizon Zero Dawn for screen space reflections on water surfaces.
|
|
||||||
|
|
||||||
### Stability fixes
|
|
||||||
|
|
||||||
- Greatly improve stability on Polaris or older cards for certain titles.
|
|
||||||
Crashes which used to happen in Horizon Zero Dawn and Death Stranding seem to have disappeared
|
|
||||||
after the memory allocation rewrite.
|
|
||||||
GPU memory usage should decrease on these cards as well.
|
|
||||||
- DIRT 5 can get in-game now due to DXIL fixes, but is not yet playable.
|
|
||||||
|
|
||||||
### New features
|
|
||||||
|
|
||||||
- Add support for Variable Rate Shading tier 1.
|
|
||||||
|
|
||||||
### Future development
|
|
||||||
|
|
||||||
DXR is not yet supported, but has seen a fair bit of background work.
|
|
||||||
|
|
||||||
- Basic DXR pipelines can be created successfully.
|
|
||||||
- Memory allocation rewrite in 2.2 unblocks further DXR development.
|
|
||||||
|
|
||||||
## 2.1
|
|
||||||
|
|
||||||
This release fixes various bugs (mostly workarounds) and improves GPU-bound performance.
|
|
||||||
|
|
||||||
New games added to "expected to work" list:
|
|
||||||
- The Division (was working already in 2.0, but missing from list)
|
|
||||||
- AC: Valhalla (*)
|
|
||||||
|
|
||||||
(*): Game requires full D3D12 sparse texture support to work.
|
|
||||||
Currently only works on NVIDIA drivers.
|
|
||||||
RADV status remains unknown until support for this feature lands in Mesa.
|
|
||||||
|
|
||||||
New games added to "kinda works, but expect a lot of jank" list:
|
|
||||||
- Cyberpunk 2077 (**)
|
|
||||||
|
|
||||||
(**): Currently only runs correctly on AMD hardware with RADV and `VK_VALVE_mutable_descriptor_type`.
|
|
||||||
As of game version 1.03, this requires the latest Mesa Git build.
|
|
||||||
The game has some fatal bugs where it relies on undefined behavior with descriptor management
|
|
||||||
which this extension works around by accident.
|
|
||||||
The game will start and run on NVIDIA, but just like what happens without the extension on AMD,
|
|
||||||
the GPU will randomly hang, making the game effectively unplayable.
|
|
||||||
A game update to fix this bug would likely make the game playable on NVIDIA as well.
|
|
||||||
Game version 1.04 changed some behavior, and support for this game will likely fluctuate over time as future patches come in.
|
|
||||||
|
|
||||||
Bug fixes and workarounds:
|
|
||||||
- Fix various implementation bugs which caused AC: Valhalla to not work.
|
|
||||||
- Work around game bug in Death Stranding where accessing map could cause corrupt rendering.
|
|
||||||
(Several games appear to have the same kind of application bug.)
|
|
||||||
- Fix corrupt textures in Horizon Zero Dawn benchmark.
|
|
||||||
- Fix SM 6.0 wave-op detection for Horizon Zero Dawn and DIRT 5.
|
|
||||||
- Work around GPU hangs in certain situations where games do not use D3D12 correctly,
|
|
||||||
but native D3D12 drivers just render wrong results rather than hang the system.
|
|
||||||
- Fix invalid SPIR-V generated by FP64 code.
|
|
||||||
- Fix crash with minimized windows in certain cases.
|
|
||||||
|
|
||||||
Performance:
|
|
||||||
- ~15% GPU-bound uplift in Ghostrunner. Might help UE4 titles in general.
|
|
||||||
- Slightly improve GPU bound performance when fully GPU bound on both AMD and NVIDIA.
|
|
||||||
- Slightly improve GPU bound performance on RADV in various titles.
|
|
||||||
- Reduce multi-threaded CPU overhead for certain D3D12 API usage patterns.
|
|
||||||
- Add support for `VK_VALVE_mutable_descriptor_type` which
|
|
||||||
improves CPU overhead, memory bloat, and avoids potential memory management thrashing on RADV.
|
|
||||||
Also avoids GPU hangs in certain situations where games misuse the D3D12 API.
|
|
||||||
|
|
||||||
Misc:
|
|
||||||
- Implement `DXGI_PRESENT_TEST`.
|
|
||||||
- Fix log spam when `DXGI_PRESENT_ALLOW_TEARING` is used.
|
|
||||||
|
|
||||||
## 2.0
|
|
||||||
|
|
||||||
This initial release supports D3D12 Feature Level 12.0 and Shader Model 6.0 (DXIL).
|
|
||||||
|
|
||||||
Games expected to work include:
|
|
||||||
|
|
||||||
- Control
|
|
||||||
- Death Stranding
|
|
||||||
- Devil May Cry 5
|
|
||||||
- Ghostrunner
|
|
||||||
- Horizon Zero Dawn
|
|
||||||
- Metro Exodus
|
|
||||||
- Monster Hunter World
|
|
||||||
- Resident Evil 2 / 3
|
|
||||||
|
|
||||||
Please refer to the README for supported driver versions.
|
|
||||||
|
|
2
COPYING
2
COPYING
|
@ -1,4 +1,4 @@
|
||||||
Copyright 2016-2022 the vkd3d-proton project authors (see the file AUTHORS for a
|
Copyright 2016-2020 the vkd3d-proton project authors (see the file AUTHORS for a
|
||||||
complete list)
|
complete list)
|
||||||
|
|
||||||
vkd3d-proton is free software; you can redistribute it and/or modify it under
|
vkd3d-proton is free software; you can redistribute it and/or modify it under
|
||||||
|
|
245
README.md
245
README.md
|
@ -22,36 +22,31 @@ There are some hard requirements on drivers to be able to implement D3D12 in a r
|
||||||
- `VK_EXT_descriptor_indexing` with at least 1000000 UpdateAfterBind descriptors for all types except UniformBuffer.
|
- `VK_EXT_descriptor_indexing` with at least 1000000 UpdateAfterBind descriptors for all types except UniformBuffer.
|
||||||
Essentially all features in `VkPhysicalDeviceDescriptorIndexingFeatures` must be supported.
|
Essentially all features in `VkPhysicalDeviceDescriptorIndexingFeatures` must be supported.
|
||||||
- `VK_KHR_timeline_semaphore`
|
- `VK_KHR_timeline_semaphore`
|
||||||
- `VK_KHR_sampler_mirror_clamp_to_edge`
|
|
||||||
- `VK_EXT_robustness2`
|
|
||||||
- `VK_KHR_separate_depth_stencil_layouts`
|
|
||||||
- `VK_KHR_bind_memory2`
|
|
||||||
- `VK_KHR_copy_commands2`
|
|
||||||
- `VK_KHR_dynamic_rendering`
|
|
||||||
- `VK_EXT_extended_dynamic_state`
|
|
||||||
- `VK_EXT_extended_dynamic_state2`
|
|
||||||
|
|
||||||
Some notable extensions that **should** be supported for optimal or correct behavior.
|
Some notable extensions that **should** be supported for optimal or correct behavior.
|
||||||
These extensions will likely become mandatory later.
|
These extensions will likely become mandatory later.
|
||||||
|
|
||||||
|
- `VK_EXT_robustness2`
|
||||||
- `VK_KHR_buffer_device_address`
|
- `VK_KHR_buffer_device_address`
|
||||||
- `VK_EXT_image_view_min_lod`
|
- `VK_EXT_extended_dynamic_state`
|
||||||
|
|
||||||
`VK_VALVE_mutable_descriptor_type` is also highly recommended, but not mandatory.
|
### AMD (RADV / ACO)
|
||||||
|
|
||||||
### AMD (RADV)
|
|
||||||
|
|
||||||
For AMD, RADV is the recommended driver and the one that sees most testing on AMD GPUs.
|
For AMD, RADV is the recommended driver and the one that sees most testing on AMD GPUs.
|
||||||
The minimum requirement at the moment is Mesa 22.0 since it supports `VK_KHR_dynamic_rendering`.
|
The recommendation here is to use a driver built from Git.
|
||||||
|
|
||||||
NOTE: For older Mesa versions, use the v2.6 release.
|
|
||||||
|
|
||||||
### NVIDIA
|
### NVIDIA
|
||||||
|
|
||||||
The [Vulkan beta drivers](https://developer.nvidia.com/vulkan-driver) generally contain the latest
|
The [Vulkan beta drivers](https://developer.nvidia.com/vulkan-driver) generally contain the latest
|
||||||
driver fixes that we identify while getting games to work.
|
driver fixes that we identify while getting games to work.
|
||||||
The latest drivers (stable, beta or Vulkan beta tracks) are always preferred.
|
At least Linux 455.26.01 (2020-10-20) is recommended as it contains fixes for:
|
||||||
If you're having problems, always try the latest drivers.
|
|
||||||
|
> Reduce host memory consumption for descriptor memory when VkDescriptorSetVariableDescriptorCountAllocateInfo is used.
|
||||||
|
|
||||||
|
> Fixed a bug in a barrier optimization that allowed some back-to-back copies to run unordered
|
||||||
|
|
||||||
|
These fixes should find their way into stable drivers eventually, but if you're having issues, test the latest development drivers,
|
||||||
|
as that is what we test against.
|
||||||
|
|
||||||
### Intel
|
### Intel
|
||||||
|
|
||||||
|
@ -151,16 +146,8 @@ commas or semicolons.
|
||||||
- `vk_debug` - enables Vulkan debug extensions and loads validation layer.
|
- `vk_debug` - enables Vulkan debug extensions and loads validation layer.
|
||||||
- `skip_application_workarounds` - Skips all application workarounds.
|
- `skip_application_workarounds` - Skips all application workarounds.
|
||||||
For debugging purposes.
|
For debugging purposes.
|
||||||
- `dxr` - Enables DXR support if supported by device.
|
- `force_bindless_texel_buffer` - Forces use of texel buffers for bindless Raw/Structured buffers.
|
||||||
- `dxr11` - Enables DXR tier 1.1 support if supported by device.
|
For game workarounds only!
|
||||||
- `force_static_cbv` - Unsafe speed hack on NVIDIA. May or may not give a significant performance uplift.
|
|
||||||
- `single_queue` - Do not use asynchronous compute or transfer queues.
|
|
||||||
- `no_upload_hvv` - Blocks any attempt to use host-visible VRAM (large/resizable BAR) for the UPLOAD heap.
|
|
||||||
May free up vital VRAM in certain critical situations, at cost of lower GPU performance.
|
|
||||||
A fraction of VRAM is reserved for resizable BAR allocations either way,
|
|
||||||
so it should not be a real issue even on lower VRAM cards.
|
|
||||||
- `force_host_cached` - Forces all host visible allocations to be CACHED, which greatly accelerates captures.
|
|
||||||
- `no_invariant_position` - Avoids workarounds for invariant position. The workaround is enabled by default.
|
|
||||||
- `VKD3D_DEBUG` - controls the debug level for log messages produced by
|
- `VKD3D_DEBUG` - controls the debug level for log messages produced by
|
||||||
vkd3d-proton. Accepts the following values: none, err, info, fixme, warn, trace.
|
vkd3d-proton. Accepts the following values: none, err, info, fixme, warn, trace.
|
||||||
- `VKD3D_SHADER_DEBUG` - controls the debug level for log messages produced by
|
- `VKD3D_SHADER_DEBUG` - controls the debug level for log messages produced by
|
||||||
|
@ -168,7 +155,6 @@ commas or semicolons.
|
||||||
- `VKD3D_LOG_FILE` - If set, redirects `VKD3D_DEBUG` logging output to a file instead.
|
- `VKD3D_LOG_FILE` - If set, redirects `VKD3D_DEBUG` logging output to a file instead.
|
||||||
- `VKD3D_VULKAN_DEVICE` - a zero-based device index. Use to force the selected
|
- `VKD3D_VULKAN_DEVICE` - a zero-based device index. Use to force the selected
|
||||||
Vulkan device.
|
Vulkan device.
|
||||||
- `VKD3D_FILTER_DEVICE_NAME` - skips devices that don't include this substring.
|
|
||||||
- `VKD3D_DISABLE_EXTENSIONS` - a list of Vulkan extensions that vkd3d-proton should
|
- `VKD3D_DISABLE_EXTENSIONS` - a list of Vulkan extensions that vkd3d-proton should
|
||||||
not use even if available.
|
not use even if available.
|
||||||
- `VKD3D_TEST_DEBUG` - enables additional debug messages in tests. Set to 0, 1
|
- `VKD3D_TEST_DEBUG` - enables additional debug messages in tests. Set to 0, 1
|
||||||
|
@ -176,8 +162,6 @@ commas or semicolons.
|
||||||
- `VKD3D_TEST_FILTER` - a filter string. Only the tests whose names matches the
|
- `VKD3D_TEST_FILTER` - a filter string. Only the tests whose names matches the
|
||||||
filter string will be run, e.g. `VKD3D_TEST_FILTER=clear_render_target`.
|
filter string will be run, e.g. `VKD3D_TEST_FILTER=clear_render_target`.
|
||||||
Useful for debugging or developing new tests.
|
Useful for debugging or developing new tests.
|
||||||
- `VKD3D_TEST_EXCLUDE` - excludes tests of which the name is included in the string,
|
|
||||||
e.g. `VKD3D_TEST_EXCLUDE=test_root_signature_priority,test_conservative_rasterization_dxil`.
|
|
||||||
- `VKD3D_TEST_PLATFORM` - can be set to "wine", "windows" or "other". The test
|
- `VKD3D_TEST_PLATFORM` - can be set to "wine", "windows" or "other". The test
|
||||||
platform controls the behavior of todo(), todo_if(), bug_if() and broken()
|
platform controls the behavior of todo(), todo_if(), bug_if() and broken()
|
||||||
conditions in tests.
|
conditions in tests.
|
||||||
|
@ -185,39 +169,6 @@ commas or semicolons.
|
||||||
- `VKD3D_PROFILE_PATH` - If profiling is enabled in the build, a profiling block is
|
- `VKD3D_PROFILE_PATH` - If profiling is enabled in the build, a profiling block is
|
||||||
emitted to `${VKD3D_PROFILE_PATH}.${pid}`.
|
emitted to `${VKD3D_PROFILE_PATH}.${pid}`.
|
||||||
|
|
||||||
## Shader cache
|
|
||||||
|
|
||||||
By default, vkd3d-proton manages its own driver cache.
|
|
||||||
This cache is intended to cache DXBC/DXIL -> SPIR-V conversion.
|
|
||||||
This reduces stutter (when pipelines are created last minute and app relies on hot driver cache)
|
|
||||||
and load times (when applications do the right thing of loading PSOs up front).
|
|
||||||
|
|
||||||
Behavior is designed to be close to DXVK state cache.
|
|
||||||
|
|
||||||
#### Default behavior
|
|
||||||
|
|
||||||
`vkd3d-proton.cache` (and `vkd3d-proton.cache.write`) are placed in the current working directory.
|
|
||||||
Generally, this is the game install folder when running in Steam.
|
|
||||||
|
|
||||||
#### Custom directory
|
|
||||||
|
|
||||||
`VKD3D_SHADER_CACHE_PATH=/path/to/directory` overrides the directory where `vkd3d-proton.cache` is placed.
|
|
||||||
|
|
||||||
#### Disable cache
|
|
||||||
|
|
||||||
`VKD3D_SHADER_CACHE_PATH=0` disables the internal cache, and any caching would have to be explicitly managed
|
|
||||||
by application.
|
|
||||||
|
|
||||||
### Behavior of ID3D12PipelineLibrary
|
|
||||||
|
|
||||||
When explicit shader cache is used, the need for application managed pipeline libraries is greatly diminished,
|
|
||||||
and the cache applications interact with is a dummy cache.
|
|
||||||
If the vkd3d-proton shader cache is disabled, ID3D12PipelineLibrary stores everything relevant for a full cache,
|
|
||||||
i.e. SPIR-V and PSO driver cache blob.
|
|
||||||
`VKD3D_CONFIG=pipeline_library_app_cache` is an alternative to `VKD3D_SHADER_CACHE_PATH=0` and can be
|
|
||||||
automatically enabled based on app-profiles if relevant in the future if applications manage the caches better
|
|
||||||
than vkd3d-proton can do automagically.
|
|
||||||
|
|
||||||
## CPU profiling (development)
|
## CPU profiling (development)
|
||||||
|
|
||||||
Pass `-Denable_profiling=true` to Meson to enable a profiled build. With a profiled build, use `VKD3D_PROFILE_PATH` environment variable.
|
Pass `-Denable_profiling=true` to Meson to enable a profiled build. With a profiled build, use `VKD3D_PROFILE_PATH` environment variable.
|
||||||
|
@ -239,26 +190,12 @@ pass `-Denable_renderdoc=true` to Meson.
|
||||||
vkd3d-proton will automatically make a capture when a specific shader is encountered.
|
vkd3d-proton will automatically make a capture when a specific shader is encountered.
|
||||||
- `VKD3D_AUTO_CAPTURE_COUNTS` - A comma-separated list of indices. This can be used to control which queue submissions to capture.
|
- `VKD3D_AUTO_CAPTURE_COUNTS` - A comma-separated list of indices. This can be used to control which queue submissions to capture.
|
||||||
E.g., use `VKD3D_AUTO_CAPTURE_COUNTS=0,4,10` to capture the 0th (first submission), 4th and 10th submissions which are candidates for capturing.
|
E.g., use `VKD3D_AUTO_CAPTURE_COUNTS=0,4,10` to capture the 0th (first submission), 4th and 10th submissions which are candidates for capturing.
|
||||||
If `VKD3D_AUTO_CAPTURE_COUNTS` is `-1`, the entire app runtime can be turned into one big capture.
|
|
||||||
This is only intended to be used when capturing something like the test suite,
|
|
||||||
or tiny applications with a finite runtime to make it easier to debug cross submission work.
|
|
||||||
|
|
||||||
If only `VKD3D_AUTO_CAPTURE_COUNTS` is set, any queue submission is considered for capturing.
|
If only `VKD3D_AUTO_CAPTURE_COUNTS` is set, any queue submission is considered for capturing.
|
||||||
If only `VKD3D_AUTO_CAPTURE_SHADER` is set, `VKD3D_AUTO_CAPTURE_COUNTS` is considered to be equal to `"0"`, i.e. a capture is only
|
If only `VKD3D_AUTO_CAPTURE_SHADER` is set, `VKD3D_AUTO_CAPTURE_COUNTS` is considered to be equal to `"0"`, i.e. a capture is only
|
||||||
made on first encounter with the target shader.
|
made on first encounter with the target shader.
|
||||||
If both are set, the capture counter is only incremented and considered when a submission contains the use of the target shader.
|
If both are set, the capture counter is only incremented and considered when a submission contains the use of the target shader.
|
||||||
|
|
||||||
### Breadcrumbs debugging
|
|
||||||
|
|
||||||
For debugging GPU hangs, it's useful to know where crashes happen.
|
|
||||||
If the build has trace enabled (non-release builds), breadcrumbs support is also enabled.
|
|
||||||
|
|
||||||
`VKD3D_CONFIG=breadcrumbs` will instrument command lists with `VK_AMD_buffer_marker` or `VK_NV_device_checkpoints`.
|
|
||||||
On GPU device lost or timeout, crash dumps are written to the log.
|
|
||||||
For best results on RADV, use `RADV_DEBUG=syncshaders`. The logs will print a digested form of the command lists
|
|
||||||
which were executing at the time, and attempt to narrow down the possible range of commands which could
|
|
||||||
have caused a crash.
|
|
||||||
|
|
||||||
### Shader logging
|
### Shader logging
|
||||||
|
|
||||||
It is possible to log the output of replaced shaders, essentially a custom shader printf. To enable this feature, `VK_KHR_buffer_device_address` must be supported.
|
It is possible to log the output of replaced shaders, essentially a custom shader printf. To enable this feature, `VK_KHR_buffer_device_address` must be supported.
|
||||||
|
@ -270,11 +207,8 @@ and avoids any possible accidental hiding of bugs by introducing validation laye
|
||||||
Using `debugPrintEXT` is also possible if that fits better with your debugging scenario.
|
Using `debugPrintEXT` is also possible if that fits better with your debugging scenario.
|
||||||
With this shader replacement scheme, we're able to add shader logging as unintrusive as possible.
|
With this shader replacement scheme, we're able to add shader logging as unintrusive as possible.
|
||||||
|
|
||||||
```
|
Replaced shaders will need to include `debug_channel.h` from `include/shader-debug`.
|
||||||
# Inside folder full of override shaders, build everything with:
|
Use `glslc -I/path/to/vkd3d-proton/include/shader-debug --target-env=vulkan1.1` when compiling replaced shaders.
|
||||||
make -C /path/to/include/shader-debug M=$PWD
|
|
||||||
```
|
|
||||||
The shader can then include `#include "debug_channel.h"` and use various functions below.
|
|
||||||
|
|
||||||
```
|
```
|
||||||
void DEBUG_CHANNEL_INIT(uvec3 ID);
|
void DEBUG_CHANNEL_INIT(uvec3 ID);
|
||||||
|
@ -298,150 +232,3 @@ void DEBUG_CHANNEL_MSG(float v0, float v1, ...); // Up to 4 components, ...
|
||||||
```
|
```
|
||||||
|
|
||||||
These functions log, formatting is `#%x` for uint, `%d` for int and `%f` for float type.
|
These functions log, formatting is `#%x` for uint, `%d` for int and `%f` for float type.
|
||||||
|
|
||||||
## Descriptor debugging
|
|
||||||
|
|
||||||
If `-Denable_descriptor_qa=true` is enabled in build, you can set the `VKD3D_DESCRIPTOR_QA_LOG` env-var to a file.
|
|
||||||
All descriptor updates and copies are logged so that it's possible to correlate descriptors with
|
|
||||||
GPU crash dumps. `enable_descriptor_qa` is not enabled by default,
|
|
||||||
since it adds some flat overhead in an extremely hot code path.
|
|
||||||
|
|
||||||
### GPU-assisted debugging
|
|
||||||
|
|
||||||
If `VKD3D_CONFIG=descriptor_qa_checks` is set with a build which enables `-Denable_descriptor_qa=true`,
|
|
||||||
all shaders will be instrumented to check for invalid access. In the log, you will see this to
|
|
||||||
make sure the feature is enabled.
|
|
||||||
|
|
||||||
```
|
|
||||||
932:info:vkd3d_descriptor_debug_init_once: Enabling descriptor QA checks!
|
|
||||||
```
|
|
||||||
|
|
||||||
The main motivation is the tight integration and high performance.
|
|
||||||
GPU-assisted debugging can be run at well over playable speeds.
|
|
||||||
|
|
||||||
#### Descriptor heap index out of bounds
|
|
||||||
|
|
||||||
```
|
|
||||||
============
|
|
||||||
Fault type: HEAP_OUT_OF_RANGE
|
|
||||||
Fault type: MISMATCH_DESCRIPTOR_TYPE
|
|
||||||
CBV_SRV_UAV heap cookie: 1800
|
|
||||||
Shader hash and instruction: edbaf1b5ed344467 (1)
|
|
||||||
Accessed resource/view cookie: 0
|
|
||||||
Shader desired descriptor type: 8 (STORAGE_BUFFER)
|
|
||||||
Found descriptor type in heap: 0 (NONE)
|
|
||||||
Failed heap index: 1024000
|
|
||||||
==========
|
|
||||||
```
|
|
||||||
|
|
||||||
The instruction `(1)`, is reported as well,
|
|
||||||
and a disassembly of the shader in question can be used to pinpoint exactly where
|
|
||||||
things are going wrong.
|
|
||||||
Dump all shaders with `VKD3D_SHADER_DUMP_PATH=/my/folder`,
|
|
||||||
and run `spirv-cross -V /my/folder/edbaf1b5ed344467.spv`.
|
|
||||||
(NOTE: clear out the folder before dumping, existing files are not overwritten).
|
|
||||||
The faulting instruction can be identified by looking at last argument, e.g.:
|
|
||||||
|
|
||||||
```
|
|
||||||
uint fixup_index = descriptor_qa_check(heap_index, descriptor_type, 1u /* instruction ID */);
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Mismatch descriptor type
|
|
||||||
|
|
||||||
```
|
|
||||||
============
|
|
||||||
Fault type: MISMATCH_DESCRIPTOR_TYPE
|
|
||||||
CBV_SRV_UAV heap cookie: 1800 // Refer to VKD3D_DESCRIPTOR_QA_LOG
|
|
||||||
Shader hash and instruction: edbaf1b5ed344467 (1)
|
|
||||||
Accessed resource/view cookie: 1802 // Refer to VKD3D_DESCRIPTOR_QA_LOG
|
|
||||||
Shader desired descriptor type: 8 (STORAGE_BUFFER)
|
|
||||||
Found descriptor type in heap: 1 (SAMPLED_IMAGE)
|
|
||||||
Failed heap index: 1025
|
|
||||||
==========
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Accessing destroyed resource
|
|
||||||
|
|
||||||
```
|
|
||||||
============
|
|
||||||
Fault type: DESTROYED_RESOURCE
|
|
||||||
CBV_SRV_UAV heap cookie: 1800
|
|
||||||
Shader hash and instruction: edbaf1b5ed344467 (2)
|
|
||||||
Accessed resource/view cookie: 1806
|
|
||||||
Shader desired descriptor type: 1 (SAMPLED_IMAGE)
|
|
||||||
Found descriptor type in heap: 1 (SAMPLED_IMAGE)
|
|
||||||
Failed heap index: 1029
|
|
||||||
==========
|
|
||||||
```
|
|
||||||
|
|
||||||
### Debugging descriptor crashes with RADV dumps (hardcore ultra nightmare mode)
|
|
||||||
|
|
||||||
For when you're absolutely desperate, there is a way to debug GPU hangs.
|
|
||||||
First, install [umr](https://gitlab.freedesktop.org/tomstdenis/umr) and make the binary setsuid.
|
|
||||||
|
|
||||||
`ACO_DEBUG=force-waitcnt RADV_DEBUG=hang VKD3D_DESCRIPTOR_QA_LOG=/somewhere/desc.txt %command%`
|
|
||||||
|
|
||||||
It is possible to use `RADV_DEBUG=hang,umr` as well, but from within Wine, there are weird things
|
|
||||||
happening where UMR dumps do not always succeed.
|
|
||||||
Instead, it is possible to invoke umr manually from an SSH shell when the GPU hangs.
|
|
||||||
|
|
||||||
```
|
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
mkdir -p "$HOME/umr-dump"
|
|
||||||
|
|
||||||
# For Navi, older GPUs might have different rings. See RADV source.
|
|
||||||
umr -R gfx_0.0.0 > "$HOME/umr-dump/ring.txt" 2>&1
|
|
||||||
umr -O halt_waves -wa gfx_0.0.0 > "$HOME/umr-dump/halt-waves-1.txt" 2>&1
|
|
||||||
umr -O bits,halt_waves -wa gfx_0.0.0 > "$HOME/umr-dump/halt-waves-2.txt" 2>&1
|
|
||||||
```
|
|
||||||
|
|
||||||
A folder is placed in `~/radv_dumps*` by RADV, and the UMR script will place wave dumps in `~/umr-dump`.
|
|
||||||
|
|
||||||
First, we can study the wave dumps to see where things crash, e.g.:
|
|
||||||
|
|
||||||
```
|
|
||||||
pgm[6@0x800120e26c00 + 0x584 ] = 0xf0001108 image_load v47, v[4:5], s[48:55] dmask:0x1 dim:SQ_RSRC_IMG_2D unorm
|
|
||||||
pgm[6@0x800120e26c00 + 0x588 ] = 0x000c2f04 ;;
|
|
||||||
pgm[6@0x800120e26c00 + 0x58c ] = 0xbf8c3f70 s_waitcnt vmcnt(0)
|
|
||||||
* pgm[6@0x800120e26c00 + 0x590 ] = 0x930118c0 s_mul_i32 s1, 64, s24
|
|
||||||
pgm[6@0x800120e26c00 + 0x594 ] = 0xf40c0c09 s_load_dwordx8 s[48:55], s[18:19], s1
|
|
||||||
pgm[6@0x800120e26c00 + 0x598 ] = 0x02000000 ;;
|
|
||||||
```
|
|
||||||
|
|
||||||
excp: 256 is a memory error (at least on 5700xt).
|
|
||||||
```
|
|
||||||
TRAPSTS[50000100]:
|
|
||||||
excp: 256 | illegal_inst: 0 | buffer_oob: 0 | excp_cycle: 0 |
|
|
||||||
excp_wave64hi: 0 | xnack_error: 1 | dp_rate: 2 | excp_group_mask: 0 |
|
|
||||||
```
|
|
||||||
|
|
||||||
We can inspect all VGPRs and all SGPRs, here for the image descriptor.
|
|
||||||
|
|
||||||
```
|
|
||||||
[ 48.. 51] = { 0130a000, c0500080, 810dc1df, 93b00204 }
|
|
||||||
[ 52.. 55] = { 00000000, 00400000, 002b0000, 800130c8 }
|
|
||||||
```
|
|
||||||
|
|
||||||
Decode the VA and study `bo_history.log`. There is a script in RADV which lets you query history for a VA.
|
|
||||||
This lets us verify that the VA in question was freed at some point.
|
|
||||||
At point of writing, there is no easy way to decode raw descriptor blobs, but when you're desperate enough you can do it by hand :|
|
|
||||||
|
|
||||||
In `pipeline.log` we have the full SPIR-V (with OpSource reference to the source DXIL/DXBC)
|
|
||||||
and disassembly of the crashed pipeline. Here we can study the code to figure out which descriptor was read.
|
|
||||||
|
|
||||||
```
|
|
||||||
// s7 is the descriptor heap index, s1 is the offset (64 bytes per image descriptor),
|
|
||||||
// s[18:19] is the descriptor heap.
|
|
||||||
s_mul_i32 s1, 64, s7 ; 930107c0
|
|
||||||
s_load_dwordx8 s[48:55], s[18:19], s1 ; f40c0c09 02000000
|
|
||||||
s_waitcnt lgkmcnt(0) ; bf8cc07f
|
|
||||||
image_load v47, v[4:5], s[48:55] dmask:0x1 dim:SQ_RSRC_IMG_2D unorm ; f0001108 000c2f04
|
|
||||||
```
|
|
||||||
|
|
||||||
```
|
|
||||||
[ 4.. 7] = { 03200020, ffff8000, 0000002b, 00000103 }
|
|
||||||
```
|
|
||||||
|
|
||||||
Which is descriptor index #259. Based on this, we can inspect the descriptor QA log and verify that the application
|
|
||||||
did indeed do something invalid, which caused the GPU hang.
|
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#define DEMO_WINDOW_CLASS_NAME u"demo_wc"
|
#define DEMO_WINDOW_CLASS_NAME L"demo_wc"
|
||||||
|
|
||||||
struct demo
|
struct demo
|
||||||
{
|
{
|
||||||
|
|
|
@ -493,6 +493,8 @@ static inline struct demo_swapchain *demo_swapchain_create(ID3D12CommandQueue *c
|
||||||
WaitForFences(vk_device, 1, &vk_fence, VK_TRUE, UINT64_MAX);
|
WaitForFences(vk_device, 1, &vk_fence, VK_TRUE, UINT64_MAX);
|
||||||
ResetFences(vk_device, 1, &vk_fence);
|
ResetFences(vk_device, 1, &vk_fence);
|
||||||
|
|
||||||
|
resource_create_info.type = VKD3D_STRUCTURE_TYPE_IMAGE_RESOURCE_CREATE_INFO;
|
||||||
|
resource_create_info.next = NULL;
|
||||||
resource_create_info.desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
|
resource_create_info.desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
|
||||||
resource_create_info.desc.Alignment = 0;
|
resource_create_info.desc.Alignment = 0;
|
||||||
resource_create_info.desc.Width = desc->width;
|
resource_create_info.desc.Width = desc->width;
|
||||||
|
|
|
@ -456,8 +456,13 @@ static void cxg_mesh_create(ID3D12Device *device, float inner_radius, float oute
|
||||||
float r0, r1, r2;
|
float r0, r1, r2;
|
||||||
float angle, da;
|
float angle, da;
|
||||||
|
|
||||||
vertices = calloc(tooth_count, 12 * sizeof(*vertices));
|
if (!(vertices = calloc(tooth_count, 12 * sizeof(*vertices))))
|
||||||
faces = calloc(tooth_count, 20 * sizeof(*faces));
|
return;
|
||||||
|
if (!(faces = calloc(tooth_count, 20 * sizeof(*faces))))
|
||||||
|
{
|
||||||
|
free(vertices);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
r0 = inner_radius;
|
r0 = inner_radius;
|
||||||
r1 = outer_radius - tooth_depth / 2.0f;
|
r1 = outer_radius - tooth_depth / 2.0f;
|
||||||
|
|
|
@ -10,8 +10,6 @@ vkd3d_idl = [
|
||||||
'vkd3d_dxgiformat.idl',
|
'vkd3d_dxgiformat.idl',
|
||||||
'vkd3d_dxgitype.idl',
|
'vkd3d_dxgitype.idl',
|
||||||
'vkd3d_swapchain_factory.idl',
|
'vkd3d_swapchain_factory.idl',
|
||||||
'vkd3d_command_list_vkd3d_ext.idl',
|
|
||||||
'vkd3d_device_vkd3d_ext.idl'
|
|
||||||
]
|
]
|
||||||
|
|
||||||
vkd3d_header_files = idl_generator.process(vkd3d_idl)
|
vkd3d_header_files = idl_generator.process(vkd3d_idl)
|
||||||
|
|
|
@ -165,23 +165,18 @@ static inline struct hash_map_entry *hash_map_insert(struct hash_map *hash_map,
|
||||||
struct hash_map_entry *current = hash_map_get_entry(hash_map, entry_idx);
|
struct hash_map_entry *current = hash_map_get_entry(hash_map, entry_idx);
|
||||||
|
|
||||||
if (!(current->flags & HASH_MAP_ENTRY_OCCUPIED) ||
|
if (!(current->flags & HASH_MAP_ENTRY_OCCUPIED) ||
|
||||||
(current->hash_value == hash_value && hash_map->compare_func(key, current)))
|
(current->hash_value == hash_value && hash_map->compare_func(key, entry)))
|
||||||
target = current;
|
target = current;
|
||||||
else
|
|
||||||
entry_idx = hash_map_next_entry_idx(hash_map, entry_idx);
|
entry_idx = hash_map_next_entry_idx(hash_map, entry_idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(target->flags & HASH_MAP_ENTRY_OCCUPIED))
|
if (!(target->flags & HASH_MAP_ENTRY_OCCUPIED))
|
||||||
{
|
|
||||||
hash_map->used_count += 1;
|
hash_map->used_count += 1;
|
||||||
|
|
||||||
|
memcpy(target, entry, hash_map->entry_size);
|
||||||
target->flags = HASH_MAP_ENTRY_OCCUPIED;
|
target->flags = HASH_MAP_ENTRY_OCCUPIED;
|
||||||
target->hash_value = hash_value;
|
target->hash_value = hash_value;
|
||||||
memcpy(target + 1, entry + 1, hash_map->entry_size - sizeof(*entry));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If target is occupied, we already have an entry in the hashmap.
|
|
||||||
* Return old one, caller is responsible for cleaning up the node we attempted to add. */
|
|
||||||
|
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,7 +188,6 @@ static inline void hash_map_init(struct hash_map *hash_map, pfn_hash_func hash_f
|
||||||
hash_map->entry_size = entry_size;
|
hash_map->entry_size = entry_size;
|
||||||
hash_map->entry_count = 0;
|
hash_map->entry_count = 0;
|
||||||
hash_map->used_count = 0;
|
hash_map->used_count = 0;
|
||||||
assert(entry_size > sizeof(struct hash_map_entry));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void hash_map_clear(struct hash_map *hash_map)
|
static inline void hash_map_clear(struct hash_map *hash_map)
|
||||||
|
@ -213,43 +207,4 @@ static inline uint32_t hash_uint64(uint64_t n)
|
||||||
return hash_combine((uint32_t)n, (uint32_t)(n >> 32));
|
return hash_combine((uint32_t)n, (uint32_t)(n >> 32));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* A somewhat stronger hash when we're meant to store the hash (pipeline caches, etc). Based on FNV-1a. */
|
|
||||||
static inline uint64_t hash_fnv1_init()
|
|
||||||
{
|
|
||||||
return 0xcbf29ce484222325ull;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint64_t hash_fnv1_iterate_u8(uint64_t h, uint8_t value)
|
|
||||||
{
|
|
||||||
return (h * 0x100000001b3ull) ^ value;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint64_t hash_fnv1_iterate_u32(uint64_t h, uint32_t value)
|
|
||||||
{
|
|
||||||
return (h * 0x100000001b3ull) ^ value;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint64_t hash_fnv1_iterate_f32(uint64_t h, float value)
|
|
||||||
{
|
|
||||||
union u { float f32; uint32_t u32; } v;
|
|
||||||
v.f32 = value;
|
|
||||||
return hash_fnv1_iterate_u32(h, v.u32);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint64_t hash_fnv1_iterate_u64(uint64_t h, uint64_t value)
|
|
||||||
{
|
|
||||||
h = hash_fnv1_iterate_u32(h, value & UINT32_MAX);
|
|
||||||
h = hash_fnv1_iterate_u32(h, value >> 32);
|
|
||||||
return h;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint64_t hash_fnv1_iterate_string(uint64_t h, const char *str)
|
|
||||||
{
|
|
||||||
if (str)
|
|
||||||
while (*str)
|
|
||||||
h = hash_fnv1_iterate_u8(h, *str++);
|
|
||||||
h = hash_fnv1_iterate_u8(h, 0);
|
|
||||||
return h;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* __VKD3D_HASHMAP_H */
|
#endif /* __VKD3D_HASHMAP_H */
|
||||||
|
|
|
@ -108,34 +108,6 @@ FORCEINLINE uint32_t vkd3d_atomic_uint32_decrement(uint32_t *target, vkd3d_memor
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCEINLINE uint32_t vkd3d_atomic_uint32_add(uint32_t *target, uint32_t value, vkd3d_memory_order order)
|
|
||||||
{
|
|
||||||
uint32_t result;
|
|
||||||
vkd3d_atomic_choose_intrinsic(order, result, InterlockedAdd, /* no suffix */,(LONG*)target, value);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
FORCEINLINE uint32_t vkd3d_atomic_uint32_sub(uint32_t *target, uint32_t value, vkd3d_memory_order order)
|
|
||||||
{
|
|
||||||
uint32_t result;
|
|
||||||
vkd3d_atomic_choose_intrinsic(order, result, InterlockedAdd, /* no suffix */,(LONG*)target, (uint32_t)(-(int32_t)value));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
FORCEINLINE uint32_t vkd3d_atomic_uint32_and(uint32_t *target, uint32_t value, vkd3d_memory_order order)
|
|
||||||
{
|
|
||||||
uint32_t result;
|
|
||||||
vkd3d_atomic_choose_intrinsic(order, result, InterlockedAnd, /* no suffix */,(LONG*)target, value);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
FORCEINLINE uint32_t vkd3d_atomic_uint32_or(uint32_t *target, uint32_t value, vkd3d_memory_order order)
|
|
||||||
{
|
|
||||||
uint32_t result;
|
|
||||||
vkd3d_atomic_choose_intrinsic(order, result, InterlockedOr, /* no suffix */,(LONG*)target, value);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
FORCEINLINE uint32_t vkd3d_atomic_uint32_compare_exchange(uint32_t* target, uint32_t expected, uint32_t desired,
|
FORCEINLINE uint32_t vkd3d_atomic_uint32_compare_exchange(uint32_t* target, uint32_t expected, uint32_t desired,
|
||||||
vkd3d_memory_order success_order, vkd3d_memory_order fail_order)
|
vkd3d_memory_order success_order, vkd3d_memory_order fail_order)
|
||||||
{
|
{
|
||||||
|
@ -185,11 +157,11 @@ FORCEINLINE uint64_t vkd3d_atomic_uint64_decrement(uint64_t *target, vkd3d_memor
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCEINLINE uint64_t vkd3d_atomic_uint64_compare_exchange(UINT64* target, uint64_t expected, uint64_t desired,
|
FORCEINLINE uint64_t vkd3d_atomic_uint64_compare_exchange(uint64_t* target, uint64_t expected, uint64_t desired,
|
||||||
vkd3d_memory_order success_order, vkd3d_memory_order fail_order)
|
vkd3d_memory_order success_order, vkd3d_memory_order fail_order)
|
||||||
{
|
{
|
||||||
uint64_t result;
|
uint64_t result;
|
||||||
/* InterlockedCompareExchange has desired (ExChange) first, then expected (Comperand). Use UINT64 to mark 8-byte alignment. */
|
/* InterlockedCompareExchange has desired (ExChange) first, then expected (Comperand) */
|
||||||
vkd3d_atomic_choose_intrinsic(success_order, result, InterlockedCompareExchange, 64, (LONG64*)target, desired, expected);
|
vkd3d_atomic_choose_intrinsic(success_order, result, InterlockedCompareExchange, 64, (LONG64*)target, desired, expected);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -211,20 +183,12 @@ typedef enum
|
||||||
# define vkd3d_atomic_generic_exchange_explicit(target, value, order) __atomic_exchange_n(target, value, order)
|
# define vkd3d_atomic_generic_exchange_explicit(target, value, order) __atomic_exchange_n(target, value, order)
|
||||||
# define vkd3d_atomic_generic_increment(target, order) __atomic_add_fetch(target, 1, order)
|
# define vkd3d_atomic_generic_increment(target, order) __atomic_add_fetch(target, 1, order)
|
||||||
# define vkd3d_atomic_generic_decrement(target, order) __atomic_sub_fetch(target, 1, order)
|
# define vkd3d_atomic_generic_decrement(target, order) __atomic_sub_fetch(target, 1, order)
|
||||||
# define vkd3d_atomic_generic_add(target, value, order) __atomic_add_fetch(target, value, order)
|
|
||||||
# define vkd3d_atomic_generic_sub(target, value, order) __atomic_sub_fetch(target, value, order)
|
|
||||||
# define vkd3d_atomic_generic_and(target, value, order) __atomic_and_fetch(target, value, order)
|
|
||||||
# define vkd3d_atomic_generic_or(target, value, order) __atomic_or_fetch(target, value, order)
|
|
||||||
|
|
||||||
# define vkd3d_atomic_uint32_load_explicit(target, order) vkd3d_atomic_generic_load_explicit(target, order)
|
# define vkd3d_atomic_uint32_load_explicit(target, order) vkd3d_atomic_generic_load_explicit(target, order)
|
||||||
# define vkd3d_atomic_uint32_store_explicit(target, value, order) vkd3d_atomic_generic_store_explicit(target, value, order)
|
# define vkd3d_atomic_uint32_store_explicit(target, value, order) vkd3d_atomic_generic_store_explicit(target, value, order)
|
||||||
# define vkd3d_atomic_uint32_exchange_explicit(target, value, order) vkd3d_atomic_generic_exchange_explicit(target, value, order)
|
# define vkd3d_atomic_uint32_exchange_explicit(target, value, order) vkd3d_atomic_generic_exchange_explicit(target, value, order)
|
||||||
# define vkd3d_atomic_uint32_increment(target, order) vkd3d_atomic_generic_increment(target, order)
|
# define vkd3d_atomic_uint32_increment(target, order) vkd3d_atomic_generic_increment(target, order)
|
||||||
# define vkd3d_atomic_uint32_decrement(target, order) vkd3d_atomic_generic_decrement(target, order)
|
# define vkd3d_atomic_uint32_decrement(target, order) vkd3d_atomic_generic_decrement(target, order)
|
||||||
# define vkd3d_atomic_uint32_add(target, value, order) vkd3d_atomic_generic_add(target, value, order)
|
|
||||||
# define vkd3d_atomic_uint32_sub(target, value, order) vkd3d_atomic_generic_sub(target, value, order)
|
|
||||||
# define vkd3d_atomic_uint32_and(target, value, order) vkd3d_atomic_generic_and(target, value, order)
|
|
||||||
# define vkd3d_atomic_uint32_or(target, value, order) vkd3d_atomic_generic_or(target, value, order)
|
|
||||||
static inline uint32_t vkd3d_atomic_uint32_compare_exchange(uint32_t* target, uint32_t expected, uint32_t desired,
|
static inline uint32_t vkd3d_atomic_uint32_compare_exchange(uint32_t* target, uint32_t expected, uint32_t desired,
|
||||||
vkd3d_memory_order success_order, vkd3d_memory_order fail_order)
|
vkd3d_memory_order success_order, vkd3d_memory_order fail_order)
|
||||||
{
|
{
|
||||||
|
@ -238,10 +202,10 @@ static inline uint32_t vkd3d_atomic_uint32_compare_exchange(uint32_t* target, ui
|
||||||
# define vkd3d_atomic_uint64_exchange_explicit(target, value, order) vkd3d_atomic_generic_exchange_explicit(target, value, order)
|
# define vkd3d_atomic_uint64_exchange_explicit(target, value, order) vkd3d_atomic_generic_exchange_explicit(target, value, order)
|
||||||
# define vkd3d_atomic_uint64_increment(target, order) vkd3d_atomic_generic_increment(target, order)
|
# define vkd3d_atomic_uint64_increment(target, order) vkd3d_atomic_generic_increment(target, order)
|
||||||
# define vkd3d_atomic_uint64_decrement(target, order) vkd3d_atomic_generic_decrement(target, order)
|
# define vkd3d_atomic_uint64_decrement(target, order) vkd3d_atomic_generic_decrement(target, order)
|
||||||
static inline uint64_t vkd3d_atomic_uint64_compare_exchange(UINT64* target, uint64_t expected, uint64_t desired,
|
static inline uint64_t vkd3d_atomic_uint64_compare_exchange(uint64_t* target, uint64_t expected, uint64_t desired,
|
||||||
vkd3d_memory_order success_order, vkd3d_memory_order fail_order)
|
vkd3d_memory_order success_order, vkd3d_memory_order fail_order)
|
||||||
{
|
{
|
||||||
/* Expected is written to with the old value in the case that *target != expected. Use UINT64 to mark 8-byte alignment. */
|
/* Expected is written to with the old value in the case that *target != expected */
|
||||||
__atomic_compare_exchange_n(target, &expected, desired, 0, success_order, fail_order);
|
__atomic_compare_exchange_n(target, &expected, desired, 0, success_order, fail_order);
|
||||||
return expected;
|
return expected;
|
||||||
}
|
}
|
||||||
|
@ -262,18 +226,18 @@ static inline uint64_t vkd3d_atomic_uint64_compare_exchange(UINT64* target, uint
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if INTPTR_MAX == INT64_MAX
|
#if defined(__x86_64__) || defined(_WIN64)
|
||||||
# define vkd3d_atomic_ptr_load_explicit(target, order) ((void *)vkd3d_atomic_uint64_load_explicit((uint64_t *)target, order))
|
# define vkd3d_atomic_ptr_load_explicit(target, order) ((void *)vkd3d_atomic_uint64_load_explicit((uint64_t *)target, order))
|
||||||
# define vkd3d_atomic_ptr_store_explicit(target, value, order) (vkd3d_atomic_uint64_store_explicit((uint64_t *)target, (uint64_t)value, order))
|
# define vkd3d_atomic_ptr_store_explicit(target, value, order) ((void *)vkd3d_atomic_uint64_store_explicit((uint64_t *)target, value, order))
|
||||||
# define vkd3d_atomic_ptr_exchange_explicit(target, value, order) ((void *)vkd3d_atomic_uint64_exchange_explicit((uint64_t *)target, (uint64_t)value, order))
|
# define vkd3d_atomic_ptr_exchange_explicit(target, value, order) ((void *)vkd3d_atomic_uint64_exchange_explicit((uint64_t *)target, value, order))
|
||||||
# define vkd3d_atomic_ptr_increment(target, order) ((void *)vkd3d_atomic_uint64_increment((uint64_t *)target, order))
|
# define vkd3d_atomic_ptr_increment(target, order) ((void *)vkd3d_atomic_uint64_increment((uint64_t *)target, order))
|
||||||
# define vkd3d_atomic_ptr_decrement(target, order) ((void *)vkd3d_atomic_uint64_decrement((uint64_t *)target, order))
|
# define vkd3d_atomic_ptr_decrement(target, order) ((void *)vkd3d_atomic_uint64_decrement((uint64_t *)target, order))
|
||||||
# define vkd3d_atomic_ptr_compare_exchange(target, expected, desired, success_order, fail_order) \
|
# define vkd3d_atomic_ptr_compare_exchange(target, expected, desired, success_order, fail_order) \
|
||||||
((void *)vkd3d_atomic_uint64_compare_exchange((UINT64 *)target, (uint64_t)expected, (uint64_t)desired, success_order, fail_order))
|
((void *)vkd3d_atomic_uint64_compare_exchange((uint64_t *)target, (uint64_t)expected, (uint64_t)desired, success_order, fail_order))
|
||||||
#else
|
#else
|
||||||
# define vkd3d_atomic_ptr_load_explicit(target, order) ((void *)vkd3d_atomic_uint32_load_explicit((uint32_t *)target, order))
|
# define vkd3d_atomic_ptr_load_explicit(target, order) ((void *)vkd3d_atomic_uint32_load_explicit((uint32_t *)target, order))
|
||||||
# define vkd3d_atomic_ptr_store_explicit(target, value, order) (vkd3d_atomic_uint32_store_explicit((uint32_t *)target, (uint32_t)value, order))
|
# define vkd3d_atomic_ptr_store_explicit(target, value, order) ((void *)vkd3d_atomic_uint32_store_explicit((uint32_t *)target, value, order))
|
||||||
# define vkd3d_atomic_ptr_exchange_explicit(target, value, order) ((void *)vkd3d_atomic_uint32_exchange_explicit((uint32_t *)target, (uint32_t)value, order))
|
# define vkd3d_atomic_ptr_exchange_explicit(target, value, order) ((void *)vkd3d_atomic_uint32_exchange_explicit((uint32_t *)target, value, order))
|
||||||
# define vkd3d_atomic_ptr_increment(target, order) ((void *)vkd3d_atomic_uint32_increment((uint32_t *)target, order))
|
# define vkd3d_atomic_ptr_increment(target, order) ((void *)vkd3d_atomic_uint32_increment((uint32_t *)target, order))
|
||||||
# define vkd3d_atomic_ptr_decrement(target, order) ((void *)vkd3d_atomic_uint32_decrement((uint32_t *)target, order))
|
# define vkd3d_atomic_ptr_decrement(target, order) ((void *)vkd3d_atomic_uint32_decrement((uint32_t *)target, order))
|
||||||
# define vkd3d_atomic_ptr_compare_exchange(target, expected, desired, success_order, fail_order) \
|
# define vkd3d_atomic_ptr_compare_exchange(target, expected, desired, success_order, fail_order) \
|
||||||
|
|
|
@ -27,12 +27,9 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#include <intrin.h>
|
#include <intrin.h>
|
||||||
#else
|
|
||||||
#include <time.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ARRAY_SIZE
|
#ifndef ARRAY_SIZE
|
||||||
|
@ -45,15 +42,8 @@
|
||||||
|
|
||||||
#define MEMBER_SIZE(t, m) sizeof(((t *)0)->m)
|
#define MEMBER_SIZE(t, m) sizeof(((t *)0)->m)
|
||||||
|
|
||||||
static inline uint64_t align64(uint64_t addr, uint64_t alignment)
|
|
||||||
{
|
|
||||||
assert(alignment > 0 && (alignment & (alignment - 1)) == 0);
|
|
||||||
return (addr + (alignment - 1)) & ~(alignment - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline size_t align(size_t addr, size_t alignment)
|
static inline size_t align(size_t addr, size_t alignment)
|
||||||
{
|
{
|
||||||
assert(alignment > 0 && (alignment & (alignment - 1)) == 0);
|
|
||||||
return (addr + (alignment - 1)) & ~(alignment - 1);
|
return (addr + (alignment - 1)) & ~(alignment - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,7 +113,8 @@ static inline unsigned int vkd3d_bitmask_tzcnt32(uint32_t mask)
|
||||||
{
|
{
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
unsigned long result;
|
unsigned long result;
|
||||||
return _BitScanForward(&result, mask) ? result : 32;
|
_BitScanForward(&result, mask) ? result : 32;
|
||||||
|
return result;
|
||||||
#elif defined(__GNUC__) || defined(__clang__)
|
#elif defined(__GNUC__) || defined(__clang__)
|
||||||
return mask ? __builtin_ctz(mask) : 32;
|
return mask ? __builtin_ctz(mask) : 32;
|
||||||
#else
|
#else
|
||||||
|
@ -212,14 +203,6 @@ static inline unsigned int vkd3d_log2i(unsigned int x)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned int vkd3d_log2i_ceil(unsigned int x)
|
|
||||||
{
|
|
||||||
if (x == 1)
|
|
||||||
return 0;
|
|
||||||
else
|
|
||||||
return vkd3d_log2i(x - 1) + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int ascii_isupper(int c)
|
static inline int ascii_isupper(int c)
|
||||||
{
|
{
|
||||||
return 'A' <= c && c <= 'Z';
|
return 'A' <= c && c <= 'Z';
|
||||||
|
@ -248,19 +231,16 @@ static inline bool is_power_of_two(unsigned int x)
|
||||||
return x && !(x & (x -1));
|
return x && !(x & (x -1));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void vkd3d_parse_version(const char *version, int *major, int *minor, int *patch)
|
static inline void vkd3d_parse_version(const char *version, int *major, int *minor)
|
||||||
{
|
{
|
||||||
char *end;
|
*major = atoi(version);
|
||||||
|
|
||||||
*major = strtol(version, &end, 10);
|
while (isdigit(*version))
|
||||||
version = end;
|
++version;
|
||||||
if (*version == '.')
|
if (*version == '.')
|
||||||
++version;
|
++version;
|
||||||
*minor = strtol(version, &end, 10);
|
|
||||||
version = end;
|
*minor = atoi(version);
|
||||||
if (*version == '.')
|
|
||||||
++version;
|
|
||||||
*patch = strtol(version, NULL, 10);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t float_bits_to_uint32(float f)
|
static inline uint32_t float_bits_to_uint32(float f)
|
||||||
|
@ -270,13 +250,21 @@ static inline uint32_t float_bits_to_uint32(float f)
|
||||||
return u;
|
return u;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline size_t vkd3d_wcslen(const WCHAR *wstr)
|
static inline size_t vkd3d_wcslen(const WCHAR *wstr, size_t wchar_size)
|
||||||
{
|
{
|
||||||
|
const uint16_t *data_16 = (const uint16_t*)wstr;
|
||||||
|
const uint32_t *data_32 = (const uint32_t*)wstr;
|
||||||
|
uint32_t curr_char;
|
||||||
size_t length = 0;
|
size_t length = 0;
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
if (!wstr[length])
|
if (wchar_size == sizeof(uint16_t))
|
||||||
|
curr_char = data_16[length];
|
||||||
|
else /* if (wchar_size == sizeof(uint32_t)) */
|
||||||
|
curr_char = data_32[length];
|
||||||
|
|
||||||
|
if (!curr_char)
|
||||||
return length;
|
return length;
|
||||||
|
|
||||||
length += 1;
|
length += 1;
|
||||||
|
@ -288,42 +276,4 @@ static inline void *void_ptr_offset(void *ptr, size_t offset)
|
||||||
return ((char*)ptr) + offset;
|
return ((char*)ptr) + offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#define VKD3D_THREAD_LOCAL __declspec(thread)
|
|
||||||
#else
|
|
||||||
#define VKD3D_THREAD_LOCAL __thread
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline uint64_t vkd3d_get_current_time_ns(void)
|
|
||||||
{
|
|
||||||
#ifdef _WIN32
|
|
||||||
LARGE_INTEGER li, lf;
|
|
||||||
uint64_t whole, part;
|
|
||||||
QueryPerformanceCounter(&li);
|
|
||||||
QueryPerformanceFrequency(&lf);
|
|
||||||
whole = (li.QuadPart / lf.QuadPart) * 1000000000;
|
|
||||||
part = ((li.QuadPart % lf.QuadPart) * 1000000000) / lf.QuadPart;
|
|
||||||
return whole + part;
|
|
||||||
#else
|
|
||||||
struct timespec ts;
|
|
||||||
clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
|
|
||||||
return ts.tv_sec * 1000000000ll + ts.tv_nsec;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma intrinsic(__rdtsc)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline uint64_t vkd3d_get_current_time_ticks(void)
|
|
||||||
{
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
return __rdtsc();
|
|
||||||
#elif defined(__i386__) || defined(__x86_64__)
|
|
||||||
return __builtin_ia32_rdtsc();
|
|
||||||
#else
|
|
||||||
return vkd3d_get_current_time_ns();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* __VKD3D_COMMON_H */
|
#endif /* __VKD3D_COMMON_H */
|
||||||
|
|
|
@ -26,13 +26,13 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#ifdef VKD3D_NO_TRACE_MESSAGES
|
#ifdef VKD3D_NO_TRACE_MESSAGES
|
||||||
#define TRACE(...) do { } while (0)
|
#define TRACE(args...) do { } while (0)
|
||||||
#define TRACE_ON() (false)
|
#define TRACE_ON() (false)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef VKD3D_NO_DEBUG_MESSAGES
|
#ifdef VKD3D_NO_DEBUG_MESSAGES
|
||||||
#define WARN(...) do { } while (0)
|
#define WARN(args...) do { } while (0)
|
||||||
#define FIXME(...) do { } while (0)
|
#define FIXME(args...) do { } while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
enum vkd3d_dbg_level
|
enum vkd3d_dbg_level
|
||||||
|
@ -65,7 +65,7 @@ void vkd3d_dbg_printf(enum vkd3d_dbg_channel channel, enum vkd3d_dbg_level level
|
||||||
const char *vkd3d_dbg_sprintf(const char *fmt, ...) VKD3D_PRINTF_FUNC(1, 2);
|
const char *vkd3d_dbg_sprintf(const char *fmt, ...) VKD3D_PRINTF_FUNC(1, 2);
|
||||||
const char *vkd3d_dbg_vsprintf(const char *fmt, va_list args);
|
const char *vkd3d_dbg_vsprintf(const char *fmt, va_list args);
|
||||||
const char *debugstr_a(const char *str);
|
const char *debugstr_a(const char *str);
|
||||||
const char *debugstr_w(const WCHAR *wstr);
|
const char *debugstr_w(const WCHAR *wstr, size_t wchar_size);
|
||||||
|
|
||||||
#define VKD3D_DBG_LOG(level) \
|
#define VKD3D_DBG_LOG(level) \
|
||||||
do { \
|
do { \
|
||||||
|
|
|
@ -1,119 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2021 Hans-Kristian Arntzen for Valve Corporation
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __VKD3D_DESCRIPTOR_QA_DATA_H
|
|
||||||
#define __VKD3D_DESCRIPTOR_QA_DATA_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
/* Data types which are used by shader backends when emitting code. */
|
|
||||||
|
|
||||||
enum vkd3d_descriptor_qa_flag_bits
|
|
||||||
{
|
|
||||||
VKD3D_DESCRIPTOR_QA_TYPE_NONE_BIT = 0,
|
|
||||||
VKD3D_DESCRIPTOR_QA_TYPE_SAMPLED_IMAGE_BIT = 1 << 0,
|
|
||||||
VKD3D_DESCRIPTOR_QA_TYPE_STORAGE_IMAGE_BIT = 1 << 1,
|
|
||||||
VKD3D_DESCRIPTOR_QA_TYPE_UNIFORM_BUFFER_BIT = 1 << 2,
|
|
||||||
VKD3D_DESCRIPTOR_QA_TYPE_STORAGE_BUFFER_BIT = 1 << 3,
|
|
||||||
VKD3D_DESCRIPTOR_QA_TYPE_UNIFORM_TEXEL_BUFFER_BIT = 1 << 4,
|
|
||||||
VKD3D_DESCRIPTOR_QA_TYPE_STORAGE_TEXEL_BUFFER_BIT = 1 << 5,
|
|
||||||
VKD3D_DESCRIPTOR_QA_TYPE_RT_ACCELERATION_STRUCTURE_BIT = 1 << 6,
|
|
||||||
VKD3D_DESCRIPTOR_QA_TYPE_SAMPLER_BIT = 1 << 7,
|
|
||||||
VKD3D_DESCRIPTOR_QA_TYPE_RAW_VA_BIT = 1 << 8
|
|
||||||
};
|
|
||||||
typedef uint32_t vkd3d_descriptor_qa_flags;
|
|
||||||
|
|
||||||
struct vkd3d_descriptor_qa_cookie_descriptor
|
|
||||||
{
|
|
||||||
uint32_t cookie;
|
|
||||||
uint32_t descriptor_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum vkd3d_descriptor_debug_fault_type
|
|
||||||
{
|
|
||||||
VKD3D_DESCRIPTOR_FAULT_TYPE_HEAP_OF_OF_RANGE = 1 << 0,
|
|
||||||
VKD3D_DESCRIPTOR_FAULT_TYPE_MISMATCH_DESCRIPTOR_TYPE = 1 << 1,
|
|
||||||
VKD3D_DESCRIPTOR_FAULT_TYPE_DESTROYED_RESOURCE = 1 << 2
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Physical layout of QA buffer. */
|
|
||||||
struct vkd3d_descriptor_qa_global_buffer_data
|
|
||||||
{
|
|
||||||
uint64_t failed_hash;
|
|
||||||
uint32_t failed_offset;
|
|
||||||
uint32_t failed_heap;
|
|
||||||
uint32_t failed_cookie;
|
|
||||||
uint32_t fault_atomic;
|
|
||||||
uint32_t failed_instruction;
|
|
||||||
uint32_t failed_descriptor_type_mask;
|
|
||||||
uint32_t actual_descriptor_type_mask;
|
|
||||||
uint32_t fault_type;
|
|
||||||
uint32_t live_status_table[];
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Physical layout of QA heap buffer. */
|
|
||||||
struct vkd3d_descriptor_qa_heap_buffer_data
|
|
||||||
{
|
|
||||||
uint32_t num_descriptors;
|
|
||||||
uint32_t heap_index;
|
|
||||||
struct vkd3d_descriptor_qa_cookie_descriptor desc[];
|
|
||||||
};
|
|
||||||
|
|
||||||
enum vkd3d_descriptor_qa_heap_buffer_data_member
|
|
||||||
{
|
|
||||||
VKD3D_DESCRIPTOR_QA_HEAP_MEMBER_NUM_DESCRIPTORS = 0,
|
|
||||||
VKD3D_DESCRIPTOR_QA_HEAP_MEMBER_HEAP_INDEX,
|
|
||||||
VKD3D_DESCRIPTOR_QA_HEAP_MEMBER_DESC,
|
|
||||||
VKD3D_DESCRIPTOR_QA_HEAP_MEMBER_COUNT
|
|
||||||
};
|
|
||||||
|
|
||||||
VKD3D_UNUSED static const char *vkd3d_descriptor_qa_heap_data_names[VKD3D_DESCRIPTOR_QA_HEAP_MEMBER_COUNT] = {
|
|
||||||
"num_descriptors",
|
|
||||||
"heap_index",
|
|
||||||
"desc",
|
|
||||||
};
|
|
||||||
|
|
||||||
enum vkd3d_descriptor_qa_global_buffer_data_member
|
|
||||||
{
|
|
||||||
VKD3D_DESCRIPTOR_QA_GLOBAL_BUFFER_DATA_MEMBER_FAILED_HASH = 0,
|
|
||||||
VKD3D_DESCRIPTOR_QA_GLOBAL_BUFFER_DATA_MEMBER_FAILED_OFFSET,
|
|
||||||
VKD3D_DESCRIPTOR_QA_GLOBAL_BUFFER_DATA_MEMBER_FAILED_HEAP,
|
|
||||||
VKD3D_DESCRIPTOR_QA_GLOBAL_BUFFER_DATA_MEMBER_FAILED_COOKIE,
|
|
||||||
VKD3D_DESCRIPTOR_QA_GLOBAL_BUFFER_DATA_MEMBER_FAULT_ATOMIC,
|
|
||||||
VKD3D_DESCRIPTOR_QA_GLOBAL_BUFFER_DATA_MEMBER_FAILED_INSTRUCTION,
|
|
||||||
VKD3D_DESCRIPTOR_QA_GLOBAL_BUFFER_DATA_MEMBER_FAILED_DESCRIPTOR_TYPE_MASK,
|
|
||||||
VKD3D_DESCRIPTOR_QA_GLOBAL_BUFFER_DATA_MEMBER_ACTUAL_DESCRIPTOR_TYPE_MASK,
|
|
||||||
VKD3D_DESCRIPTOR_QA_GLOBAL_BUFFER_DATA_MEMBER_FAULT_TYPE,
|
|
||||||
VKD3D_DESCRIPTOR_QA_GLOBAL_BUFFER_DATA_MEMBER_LIVE_STATUS_TABLE,
|
|
||||||
VKD3D_DESCRIPTOR_QA_GLOBAL_BUFFER_DATA_MEMBER_COUNT
|
|
||||||
};
|
|
||||||
|
|
||||||
VKD3D_UNUSED static const char *vkd3d_descriptor_qa_global_buffer_data_names[VKD3D_DESCRIPTOR_QA_GLOBAL_BUFFER_DATA_MEMBER_COUNT] = {
|
|
||||||
"failed_hash",
|
|
||||||
"failed_offset",
|
|
||||||
"failed_heap",
|
|
||||||
"failed_cookie",
|
|
||||||
"fault_atomic",
|
|
||||||
"failed_instruction",
|
|
||||||
"failed_descriptor_type_mask",
|
|
||||||
"actual_descriptor_type_mask",
|
|
||||||
"fault_type",
|
|
||||||
"live_status_table",
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,42 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2022 Hans-Kristian Arntzen for Valve Corporation
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __VKD3D_FILE_UTILS_H
|
|
||||||
#define __VKD3D_FILE_UTILS_H
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
struct vkd3d_memory_mapped_file
|
|
||||||
{
|
|
||||||
void *mapped;
|
|
||||||
size_t mapped_size;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* On failure, ensures the struct is cleared to zero.
|
|
||||||
* A reference to the file is kept through the memory mapping. */
|
|
||||||
bool vkd3d_file_map_read_only(const char *path, struct vkd3d_memory_mapped_file *file);
|
|
||||||
/* Clears out file on unmap. */
|
|
||||||
void vkd3d_file_unmap(struct vkd3d_memory_mapped_file *file);
|
|
||||||
bool vkd3d_file_rename_overwrite(const char *from_path, const char *to_path);
|
|
||||||
bool vkd3d_file_rename_no_replace(const char *from_path, const char *to_path);
|
|
||||||
bool vkd3d_file_delete(const char *path);
|
|
||||||
FILE *vkd3d_file_open_exclusive_write(const char *path);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -23,7 +23,6 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "vkd3d_common.h"
|
|
||||||
#include "vkd3d_debug.h"
|
#include "vkd3d_debug.h"
|
||||||
|
|
||||||
static inline void *vkd3d_malloc(size_t size)
|
static inline void *vkd3d_malloc(size_t size)
|
||||||
|
@ -58,22 +57,4 @@ static inline void vkd3d_free(void *ptr)
|
||||||
bool vkd3d_array_reserve(void **elements, size_t *capacity,
|
bool vkd3d_array_reserve(void **elements, size_t *capacity,
|
||||||
size_t element_count, size_t element_size);
|
size_t element_count, size_t element_size);
|
||||||
|
|
||||||
static inline void *vkd3d_malloc_aligned(size_t size, size_t alignment)
|
|
||||||
{
|
|
||||||
#ifdef _WIN32
|
|
||||||
return _aligned_malloc(size, alignment);
|
|
||||||
#else
|
|
||||||
return aligned_alloc(alignment, align(size, alignment));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void vkd3d_free_aligned(void *ptr)
|
|
||||||
{
|
|
||||||
#ifdef _WIN32
|
|
||||||
_aligned_free(ptr);
|
|
||||||
#else
|
|
||||||
free(ptr);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* __VKD3D_MEMORY_H */
|
#endif /* __VKD3D_MEMORY_H */
|
||||||
|
|
|
@ -37,8 +37,6 @@ int vkd3d_dlclose(vkd3d_module_t handle);
|
||||||
|
|
||||||
const char *vkd3d_dlerror(void);
|
const char *vkd3d_dlerror(void);
|
||||||
|
|
||||||
bool vkd3d_get_env_var(const char *name, char *value, size_t value_size);
|
|
||||||
|
|
||||||
bool vkd3d_get_program_name(char program_name[VKD3D_PATH_MAX]);
|
bool vkd3d_get_program_name(char program_name[VKD3D_PATH_MAX]);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -21,15 +21,39 @@
|
||||||
|
|
||||||
#include "vkd3d_windows.h"
|
#include "vkd3d_windows.h"
|
||||||
#include "vkd3d_spinlock.h"
|
#include "vkd3d_spinlock.h"
|
||||||
#include "vkd3d_common.h"
|
#include <stdint.h>
|
||||||
|
|
||||||
#ifdef VKD3D_ENABLE_PROFILING
|
#ifdef VKD3D_ENABLE_PROFILING
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <windows.h>
|
||||||
|
#else
|
||||||
|
#include <time.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
void vkd3d_init_profiling(void);
|
void vkd3d_init_profiling(void);
|
||||||
bool vkd3d_uses_profiling(void);
|
bool vkd3d_uses_profiling(void);
|
||||||
unsigned int vkd3d_profiling_register_region(const char *name, spinlock_t *lock, uint32_t *latch);
|
unsigned int vkd3d_profiling_register_region(const char *name, spinlock_t *lock, uint32_t *latch);
|
||||||
void vkd3d_profiling_notify_work(unsigned int index, uint64_t start_ticks, uint64_t end_ticks, unsigned int iteration_count);
|
void vkd3d_profiling_notify_work(unsigned int index, uint64_t start_ticks, uint64_t end_ticks, unsigned int iteration_count);
|
||||||
|
|
||||||
|
static inline uint64_t vkd3d_profiling_get_tick_count(void)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
LARGE_INTEGER li, lf;
|
||||||
|
uint64_t whole, part;
|
||||||
|
QueryPerformanceCounter(&li);
|
||||||
|
QueryPerformanceFrequency(&lf);
|
||||||
|
whole = (li.QuadPart / lf.QuadPart) * 1000000000;
|
||||||
|
part = ((li.QuadPart % lf.QuadPart) * 1000000000) / lf.QuadPart;
|
||||||
|
return whole + part;
|
||||||
|
#else
|
||||||
|
struct timespec ts;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
|
||||||
|
return ts.tv_sec * 1000000000ll + ts.tv_nsec;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#define VKD3D_REGION_DECL(name) \
|
#define VKD3D_REGION_DECL(name) \
|
||||||
static uint32_t _vkd3d_region_latch_##name; \
|
static uint32_t _vkd3d_region_latch_##name; \
|
||||||
static spinlock_t _vkd3d_region_lock_##name; \
|
static spinlock_t _vkd3d_region_lock_##name; \
|
||||||
|
@ -41,12 +65,12 @@ void vkd3d_profiling_notify_work(unsigned int index, uint64_t start_ticks, uint6
|
||||||
do { \
|
do { \
|
||||||
if (!(_vkd3d_region_index_##name = vkd3d_atomic_uint32_load_explicit(&_vkd3d_region_latch_##name, vkd3d_memory_order_acquire))) \
|
if (!(_vkd3d_region_index_##name = vkd3d_atomic_uint32_load_explicit(&_vkd3d_region_latch_##name, vkd3d_memory_order_acquire))) \
|
||||||
_vkd3d_region_index_##name = vkd3d_profiling_register_region(#name, &_vkd3d_region_lock_##name, &_vkd3d_region_latch_##name); \
|
_vkd3d_region_index_##name = vkd3d_profiling_register_region(#name, &_vkd3d_region_lock_##name, &_vkd3d_region_latch_##name); \
|
||||||
_vkd3d_region_begin_tick_##name = vkd3d_get_current_time_ticks(); \
|
_vkd3d_region_begin_tick_##name = vkd3d_profiling_get_tick_count(); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define VKD3D_REGION_END_ITERATIONS(name, iter) \
|
#define VKD3D_REGION_END_ITERATIONS(name, iter) \
|
||||||
do { \
|
do { \
|
||||||
_vkd3d_region_end_tick_##name = vkd3d_get_current_time_ticks(); \
|
_vkd3d_region_end_tick_##name = vkd3d_profiling_get_tick_count(); \
|
||||||
vkd3d_profiling_notify_work(_vkd3d_region_index_##name, _vkd3d_region_begin_tick_##name, _vkd3d_region_end_tick_##name, iter); \
|
vkd3d_profiling_notify_work(_vkd3d_region_index_##name, _vkd3d_region_begin_tick_##name, _vkd3d_region_end_tick_##name, iter); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
|
|
@ -1,59 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2020 Hans-Kristian Arntzen for Valve Corporation
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __VKD3D_RW_SPINLOCK_H
|
|
||||||
#define __VKD3D_RW_SPINLOCK_H
|
|
||||||
|
|
||||||
#include "vkd3d_spinlock.h"
|
|
||||||
|
|
||||||
#define VKD3D_RW_SPINLOCK_WRITE 1u
|
|
||||||
#define VKD3D_RW_SPINLOCK_READ 2u
|
|
||||||
#define VKD3D_RW_SPINLOCK_IDLE 0u
|
|
||||||
|
|
||||||
static inline void rw_spinlock_acquire_read(spinlock_t *spinlock)
|
|
||||||
{
|
|
||||||
uint32_t count = vkd3d_atomic_uint32_add(spinlock, VKD3D_RW_SPINLOCK_READ, vkd3d_memory_order_acquire);
|
|
||||||
while (count & VKD3D_RW_SPINLOCK_WRITE)
|
|
||||||
{
|
|
||||||
vkd3d_pause();
|
|
||||||
count = vkd3d_atomic_uint32_load_explicit(spinlock, vkd3d_memory_order_acquire);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void rw_spinlock_release_read(spinlock_t *spinlock)
|
|
||||||
{
|
|
||||||
vkd3d_atomic_uint32_sub(spinlock, VKD3D_RW_SPINLOCK_READ, vkd3d_memory_order_release);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void rw_spinlock_acquire_write(spinlock_t *spinlock)
|
|
||||||
{
|
|
||||||
while (vkd3d_atomic_uint32_load_explicit(spinlock, vkd3d_memory_order_relaxed) != VKD3D_RW_SPINLOCK_IDLE ||
|
|
||||||
vkd3d_atomic_uint32_compare_exchange(spinlock,
|
|
||||||
VKD3D_RW_SPINLOCK_IDLE, VKD3D_RW_SPINLOCK_WRITE,
|
|
||||||
vkd3d_memory_order_acquire, vkd3d_memory_order_relaxed) != VKD3D_RW_SPINLOCK_IDLE)
|
|
||||||
{
|
|
||||||
vkd3d_pause();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void rw_spinlock_release_write(spinlock_t *spinlock)
|
|
||||||
{
|
|
||||||
vkd3d_atomic_uint32_and(spinlock, ~VKD3D_RW_SPINLOCK_WRITE, vkd3d_memory_order_release);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -28,13 +28,6 @@
|
||||||
#include <emmintrin.h>
|
#include <emmintrin.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static inline void vkd3d_pause(void)
|
|
||||||
{
|
|
||||||
#ifdef __SSE2__
|
|
||||||
_mm_pause();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#define vkd3d_spinlock_try_lock(lock) \
|
#define vkd3d_spinlock_try_lock(lock) \
|
||||||
(!vkd3d_atomic_uint32_load_explicit(lock, vkd3d_memory_order_relaxed) && \
|
(!vkd3d_atomic_uint32_load_explicit(lock, vkd3d_memory_order_relaxed) && \
|
||||||
!vkd3d_atomic_uint32_exchange_explicit(lock, 1u, vkd3d_memory_order_acquire))
|
!vkd3d_atomic_uint32_exchange_explicit(lock, 1u, vkd3d_memory_order_acquire))
|
||||||
|
@ -56,7 +49,11 @@ static inline bool spinlock_try_acquire(spinlock_t *lock)
|
||||||
static inline void spinlock_acquire(spinlock_t *lock)
|
static inline void spinlock_acquire(spinlock_t *lock)
|
||||||
{
|
{
|
||||||
while (!spinlock_try_acquire(lock))
|
while (!spinlock_try_acquire(lock))
|
||||||
vkd3d_pause();
|
#ifdef __SSE2__
|
||||||
|
_mm_pause();
|
||||||
|
#else
|
||||||
|
continue;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void spinlock_release(spinlock_t *lock)
|
static inline void spinlock_release(spinlock_t *lock)
|
||||||
|
|
|
@ -1,82 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2021 Hans-Kristian Arntzen for Valve Corporation
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __VKD3D_STRING_H
|
|
||||||
#define __VKD3D_STRING_H
|
|
||||||
|
|
||||||
#include "vkd3d_common.h"
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
/* Various string utilities. */
|
|
||||||
|
|
||||||
WCHAR *vkd3d_dup_entry_point(const char *str);
|
|
||||||
WCHAR *vkd3d_dup_entry_point_n(const char *str, size_t len);
|
|
||||||
WCHAR *vkd3d_dup_demangled_entry_point(const char *str);
|
|
||||||
char *vkd3d_dup_demangled_entry_point_ascii(const char *str);
|
|
||||||
|
|
||||||
bool vkd3d_export_strequal(const WCHAR *a, const WCHAR *b);
|
|
||||||
bool vkd3d_export_strequal_mixed(const WCHAR *a, const char *b);
|
|
||||||
bool vkd3d_export_strequal_substr(const WCHAR *a, size_t n, const WCHAR *b);
|
|
||||||
|
|
||||||
char *vkd3d_strdup(const char *str);
|
|
||||||
char *vkd3d_strdup_n(const char *str, size_t n);
|
|
||||||
WCHAR *vkd3d_wstrdup(const WCHAR *str);
|
|
||||||
WCHAR *vkd3d_wstrdup_n(const WCHAR *str, size_t n);
|
|
||||||
|
|
||||||
static inline bool vkd3d_string_ends_with_n(const char *str, size_t str_len, const char *ending, size_t ending_len)
|
|
||||||
{
|
|
||||||
return str_len >= ending_len && !strncmp(str + (str_len - ending_len), ending, ending_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool vkd3d_string_ends_with(const char *str, const char *ending)
|
|
||||||
{
|
|
||||||
return vkd3d_string_ends_with_n(str, strlen(str), ending, strlen(ending));
|
|
||||||
}
|
|
||||||
|
|
||||||
enum vkd3d_string_compare_mode
|
|
||||||
{
|
|
||||||
VKD3D_STRING_COMPARE_NEVER,
|
|
||||||
VKD3D_STRING_COMPARE_ALWAYS,
|
|
||||||
VKD3D_STRING_COMPARE_EXACT,
|
|
||||||
VKD3D_STRING_COMPARE_STARTS_WITH,
|
|
||||||
VKD3D_STRING_COMPARE_ENDS_WITH,
|
|
||||||
VKD3D_STRING_COMPARE_CONTAINS,
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline bool vkd3d_string_compare(enum vkd3d_string_compare_mode mode, const char *string, const char *comparator)
|
|
||||||
{
|
|
||||||
switch (mode)
|
|
||||||
{
|
|
||||||
default:
|
|
||||||
case VKD3D_STRING_COMPARE_NEVER:
|
|
||||||
return false;
|
|
||||||
case VKD3D_STRING_COMPARE_ALWAYS:
|
|
||||||
return true;
|
|
||||||
case VKD3D_STRING_COMPARE_EXACT:
|
|
||||||
return !strcmp(string, comparator);
|
|
||||||
case VKD3D_STRING_COMPARE_STARTS_WITH:
|
|
||||||
return !strncmp(string, comparator, strlen(comparator));
|
|
||||||
case VKD3D_STRING_COMPARE_ENDS_WITH:
|
|
||||||
return vkd3d_string_ends_with(string, comparator);
|
|
||||||
case VKD3D_STRING_COMPARE_CONTAINS:
|
|
||||||
return strstr(string, comparator) != NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* __VKD3D_STRING_H */
|
|
|
@ -20,7 +20,6 @@
|
||||||
#define __VKD3D_TEST_H
|
#define __VKD3D_TEST_H
|
||||||
|
|
||||||
#include "vkd3d_common.h"
|
#include "vkd3d_common.h"
|
||||||
#include "vkd3d_debug.h"
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
@ -29,19 +28,16 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#ifdef VKD3D_TEST_DECLARE_MAIN
|
|
||||||
static void vkd3d_test_main(int argc, char **argv);
|
static void vkd3d_test_main(int argc, char **argv);
|
||||||
#endif
|
static const char *vkd3d_test_name;
|
||||||
|
static const char *vkd3d_test_platform = "other";
|
||||||
extern const char *vkd3d_test_name;
|
|
||||||
extern const char *vkd3d_test_platform;
|
|
||||||
|
|
||||||
static void vkd3d_test_start_todo(bool is_todo);
|
static void vkd3d_test_start_todo(bool is_todo);
|
||||||
static int vkd3d_test_loop_todo(void);
|
static int vkd3d_test_loop_todo(void);
|
||||||
static void vkd3d_test_end_todo(void);
|
static void vkd3d_test_end_todo(void);
|
||||||
|
|
||||||
#define START_TEST(name) \
|
#define START_TEST(name) \
|
||||||
const char *vkd3d_test_name = #name; \
|
static const char *vkd3d_test_name = #name; \
|
||||||
static void vkd3d_test_main(int argc, char **argv)
|
static void vkd3d_test_main(int argc, char **argv)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -104,7 +100,7 @@ static void vkd3d_test_end_todo(void);
|
||||||
|
|
||||||
#define todo todo_if(true)
|
#define todo todo_if(true)
|
||||||
|
|
||||||
struct vkd3d_test_state_context
|
static struct
|
||||||
{
|
{
|
||||||
LONG success_count;
|
LONG success_count;
|
||||||
LONG failure_count;
|
LONG failure_count;
|
||||||
|
@ -123,10 +119,8 @@ struct vkd3d_test_state_context
|
||||||
bool bug_enabled;
|
bool bug_enabled;
|
||||||
|
|
||||||
const char *test_name_filter;
|
const char *test_name_filter;
|
||||||
const char *test_exclude_list;
|
|
||||||
char context[1024];
|
char context[1024];
|
||||||
};
|
} vkd3d_test_state;
|
||||||
extern struct vkd3d_test_state_context vkd3d_test_state;
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
vkd3d_test_platform_is_windows(void)
|
vkd3d_test_platform_is_windows(void)
|
||||||
|
@ -251,7 +245,7 @@ vkd3d_test_debug(const char *fmt, ...)
|
||||||
int size;
|
int size;
|
||||||
|
|
||||||
size = snprintf(buffer, sizeof(buffer), "%s: ", vkd3d_test_name);
|
size = snprintf(buffer, sizeof(buffer), "%s: ", vkd3d_test_name);
|
||||||
if (0 < size && size < (int)sizeof(buffer))
|
if (0 < size && size < sizeof(buffer))
|
||||||
{
|
{
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
vsnprintf(buffer + size, sizeof(buffer) - size, fmt, args);
|
vsnprintf(buffer + size, sizeof(buffer) - size, fmt, args);
|
||||||
|
@ -270,20 +264,17 @@ vkd3d_test_debug(const char *fmt, ...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef VKD3D_TEST_DECLARE_MAIN
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
const char *exclude_list = getenv("VKD3D_TEST_EXCLUDE");
|
|
||||||
const char *test_filter = getenv("VKD3D_TEST_FILTER");
|
const char *test_filter = getenv("VKD3D_TEST_FILTER");
|
||||||
const char *debug_level = getenv("VKD3D_TEST_DEBUG");
|
const char *debug_level = getenv("VKD3D_TEST_DEBUG");
|
||||||
char *test_platform = getenv("VKD3D_TEST_PLATFORM");
|
char *test_platform = getenv("VKD3D_TEST_PLATFORM");
|
||||||
const char *bug = getenv("VKD3D_TEST_BUG");
|
const char *bug = getenv("VKD3D_TEST_BUG");
|
||||||
|
|
||||||
memset(&vkd3d_test_state, 0, sizeof(vkd3d_test_state));
|
memset(&vkd3d_test_state, 0, sizeof(vkd3d_test_state));
|
||||||
vkd3d_test_state.debug_level = debug_level ? atoi(debug_level) : 1;
|
vkd3d_test_state.debug_level = debug_level ? atoi(debug_level) : 0;
|
||||||
vkd3d_test_state.bug_enabled = bug ? atoi(bug) : true;
|
vkd3d_test_state.bug_enabled = bug ? atoi(bug) : true;
|
||||||
vkd3d_test_state.test_name_filter = test_filter;
|
vkd3d_test_state.test_name_filter = test_filter;
|
||||||
vkd3d_test_state.test_exclude_list = exclude_list;
|
|
||||||
|
|
||||||
if (test_platform)
|
if (test_platform)
|
||||||
{
|
{
|
||||||
|
@ -360,27 +351,16 @@ int wmain(int argc, WCHAR **wargv)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
#endif /* VKD3D_TEST_DECLARE_MAIN */
|
|
||||||
|
|
||||||
typedef void (*vkd3d_test_pfn)(void);
|
typedef void (*vkd3d_test_pfn)(void);
|
||||||
|
|
||||||
static inline void vkd3d_run_test(const char *name, vkd3d_test_pfn test_pfn)
|
static inline void vkd3d_run_test(const char *name, vkd3d_test_pfn test_pfn)
|
||||||
{
|
{
|
||||||
const char *old_test_name;
|
|
||||||
|
|
||||||
if (vkd3d_test_state.test_name_filter && !strstr(name, vkd3d_test_state.test_name_filter))
|
if (vkd3d_test_state.test_name_filter && !strstr(name, vkd3d_test_state.test_name_filter))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (vkd3d_test_state.test_exclude_list
|
vkd3d_test_debug("%s", name);
|
||||||
&& vkd3d_debug_list_has_member(vkd3d_test_state.test_exclude_list, name))
|
|
||||||
return;
|
|
||||||
|
|
||||||
old_test_name = vkd3d_test_name;
|
|
||||||
vkd3d_test_debug("======== %s begin ========", name);
|
|
||||||
vkd3d_test_name = name;
|
|
||||||
test_pfn();
|
test_pfn();
|
||||||
vkd3d_test_name = old_test_name;
|
|
||||||
vkd3d_test_debug("======== %s end ==========", name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void vkd3d_test_start_todo(bool is_todo)
|
static inline void vkd3d_test_start_todo(bool is_todo)
|
||||||
|
|
|
@ -51,8 +51,6 @@ typedef struct pthread_cond
|
||||||
CONDITION_VARIABLE cond;
|
CONDITION_VARIABLE cond;
|
||||||
} pthread_cond_t;
|
} pthread_cond_t;
|
||||||
|
|
||||||
typedef pthread_cond_t condvar_reltime_t;
|
|
||||||
|
|
||||||
static DWORD WINAPI win32_thread_wrapper_routine(void *arg)
|
static DWORD WINAPI win32_thread_wrapper_routine(void *arg)
|
||||||
{
|
{
|
||||||
pthread_t thread = arg;
|
pthread_t thread = arg;
|
||||||
|
@ -116,48 +114,6 @@ static inline int pthread_mutex_destroy(pthread_mutex_t *lock)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* SRWLocks distinguish between write and read unlocks, but pthread interface does not,
|
|
||||||
* so make a trivial wrapper type instead to avoid any possible API conflicts. */
|
|
||||||
typedef struct rwlock
|
|
||||||
{
|
|
||||||
SRWLOCK rwlock;
|
|
||||||
} rwlock_t;
|
|
||||||
|
|
||||||
static inline int rwlock_init(rwlock_t *lock)
|
|
||||||
{
|
|
||||||
InitializeSRWLock(&lock->rwlock);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int rwlock_lock_write(rwlock_t *lock)
|
|
||||||
{
|
|
||||||
AcquireSRWLockExclusive(&lock->rwlock);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int rwlock_lock_read(rwlock_t *lock)
|
|
||||||
{
|
|
||||||
AcquireSRWLockShared(&lock->rwlock);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int rwlock_unlock_write(rwlock_t *lock)
|
|
||||||
{
|
|
||||||
ReleaseSRWLockExclusive(&lock->rwlock);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int rwlock_unlock_read(rwlock_t *lock)
|
|
||||||
{
|
|
||||||
ReleaseSRWLockShared(&lock->rwlock);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int rwlock_destroy(rwlock_t *lock)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int pthread_cond_init(pthread_cond_t *cond, void *attr)
|
static inline int pthread_cond_init(pthread_cond_t *cond, void *attr)
|
||||||
{
|
{
|
||||||
(void)attr;
|
(void)attr;
|
||||||
|
@ -189,32 +145,6 @@ static inline int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *lock)
|
||||||
return ret ? 0 : -1;
|
return ret ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int condvar_reltime_init(condvar_reltime_t *cond)
|
|
||||||
{
|
|
||||||
return pthread_cond_init(cond, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int condvar_reltime_destroy(condvar_reltime_t *cond)
|
|
||||||
{
|
|
||||||
return pthread_cond_destroy(cond);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int condvar_reltime_signal(condvar_reltime_t *cond)
|
|
||||||
{
|
|
||||||
return pthread_cond_signal(cond);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int condvar_reltime_wait_timeout_seconds(condvar_reltime_t *cond, pthread_mutex_t *lock, unsigned int seconds)
|
|
||||||
{
|
|
||||||
BOOL ret = SleepConditionVariableSRW(&cond->cond, &lock->lock, seconds * 1000, 0);
|
|
||||||
if (ret)
|
|
||||||
return 0;
|
|
||||||
else if (GetLastError() == ERROR_TIMEOUT)
|
|
||||||
return 1;
|
|
||||||
else
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void vkd3d_set_thread_name(const char *name)
|
static inline void vkd3d_set_thread_name(const char *name)
|
||||||
{
|
{
|
||||||
(void)name;
|
(void)name;
|
||||||
|
@ -238,96 +168,10 @@ static inline void pthread_once(pthread_once_t *once, void (*func)(void))
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <errno.h>
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
static inline void vkd3d_set_thread_name(const char *name)
|
static inline void vkd3d_set_thread_name(const char *name)
|
||||||
{
|
{
|
||||||
pthread_setname_np(pthread_self(), name);
|
pthread_setname_np(pthread_self(), name);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct rwlock
|
|
||||||
{
|
|
||||||
pthread_rwlock_t rwlock;
|
|
||||||
} rwlock_t;
|
|
||||||
|
|
||||||
static inline int rwlock_init(rwlock_t *lock)
|
|
||||||
{
|
|
||||||
return pthread_rwlock_init(&lock->rwlock, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int rwlock_lock_write(rwlock_t *lock)
|
|
||||||
{
|
|
||||||
return pthread_rwlock_wrlock(&lock->rwlock);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int rwlock_lock_read(rwlock_t *lock)
|
|
||||||
{
|
|
||||||
return pthread_rwlock_rdlock(&lock->rwlock);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int rwlock_unlock_write(rwlock_t *lock)
|
|
||||||
{
|
|
||||||
return pthread_rwlock_unlock(&lock->rwlock);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int rwlock_unlock_read(rwlock_t *lock)
|
|
||||||
{
|
|
||||||
return pthread_rwlock_unlock(&lock->rwlock);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int rwlock_destroy(rwlock_t *lock)
|
|
||||||
{
|
|
||||||
return pthread_rwlock_destroy(&lock->rwlock);
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct condvar_reltime
|
|
||||||
{
|
|
||||||
pthread_cond_t cond;
|
|
||||||
} condvar_reltime_t;
|
|
||||||
|
|
||||||
static inline int condvar_reltime_init(condvar_reltime_t *cond)
|
|
||||||
{
|
|
||||||
pthread_condattr_t attr;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
pthread_condattr_init(&attr);
|
|
||||||
pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
|
|
||||||
rc = pthread_cond_init(&cond->cond, &attr);
|
|
||||||
pthread_condattr_destroy(&attr);
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void condvar_reltime_destroy(condvar_reltime_t *cond)
|
|
||||||
{
|
|
||||||
pthread_cond_destroy(&cond->cond);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int condvar_reltime_signal(condvar_reltime_t *cond)
|
|
||||||
{
|
|
||||||
return pthread_cond_signal(&cond->cond);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int condvar_reltime_wait_timeout_seconds(condvar_reltime_t *cond, pthread_mutex_t *lock, unsigned int seconds)
|
|
||||||
{
|
|
||||||
struct timespec ts;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
|
||||||
ts.tv_sec += seconds;
|
|
||||||
|
|
||||||
/* This is absolute time. */
|
|
||||||
rc = pthread_cond_timedwait(&cond->cond, lock, &ts);
|
|
||||||
|
|
||||||
if (rc == ETIMEDOUT)
|
|
||||||
return 1;
|
|
||||||
else if (rc == 0)
|
|
||||||
return 0;
|
|
||||||
else
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define PTHREAD_ONCE_CALLBACK
|
#define PTHREAD_ONCE_CALLBACK
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,6 @@
|
||||||
|
|
||||||
/* max_elements is 0 if only nul-terminator should be used.
|
/* max_elements is 0 if only nul-terminator should be used.
|
||||||
* Otherwise, terminate the string after either a nul-termination byte or max_elements. */
|
* Otherwise, terminate the string after either a nul-termination byte or max_elements. */
|
||||||
char *vkd3d_strdup_w_utf8(const WCHAR *wstr, size_t max_elements);
|
char *vkd3d_strdup_w_utf8(const WCHAR *wstr, size_t wchar_size, size_t max_elements);
|
||||||
|
|
||||||
#endif /* __VKD3D_UTF8_H */
|
#endif /* __VKD3D_UTF8_H */
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
#ifndef __VULKAN_PRIVATE_EXTENSIONS_H__
|
|
||||||
#define __VULKAN_PRIVATE_EXTENSIONS_H__
|
|
||||||
|
|
||||||
/* Nothing here at the moment. Add hacks here! */
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,71 +0,0 @@
|
||||||
INCLUDE_DIR := $(CURDIR)
|
|
||||||
|
|
||||||
VERT_SOURCES := $(wildcard $(M)/*.vert)
|
|
||||||
FRAG_SOURCES := $(wildcard $(M)/*.frag)
|
|
||||||
COMP_SOURCES := $(wildcard $(M)/*.comp)
|
|
||||||
TESC_SOURCES := $(wildcard $(M)/*.tesc)
|
|
||||||
TESE_SOURCES := $(wildcard $(M)/*.tese)
|
|
||||||
GEOM_SOURCES := $(wildcard $(M)/*.geom)
|
|
||||||
RGEN_SOURCES := $(wildcard $(M)/*.rgen)
|
|
||||||
RINT_SOURCES := $(wildcard $(M)/*.rint)
|
|
||||||
RAHIT_SOURCES := $(wildcard $(M)/*.rahit)
|
|
||||||
RCHIT_SOURCES := $(wildcard $(M)/*.rchit)
|
|
||||||
RMISS_SOURCES := $(wildcard $(M)/*.rmiss)
|
|
||||||
RCALL_SOURCES := $(wildcard $(M)/*.rcall)
|
|
||||||
|
|
||||||
SPV_OBJECTS := \
|
|
||||||
$(VERT_SOURCES:.vert=.spv) \
|
|
||||||
$(FRAG_SOURCES:.frag=.spv) \
|
|
||||||
$(COMP_SOURCES:.comp=.spv) \
|
|
||||||
$(TESC_SOURCES:.tesc=.spv) \
|
|
||||||
$(TESE_SOURCES:.tese=.spv) \
|
|
||||||
$(GEOM_SOURCES:.geom=.spv) \
|
|
||||||
$(RGEN_SOURCES:.rgen=.spv) \
|
|
||||||
$(RINT_SOURCES:.rint=.spv) \
|
|
||||||
$(RAHIT_SOURCES:.rahit=.spv) \
|
|
||||||
$(RCHIT_SOURCES:.rchit=.spv) \
|
|
||||||
$(RMISS_SOURCES:.rmiss=.spv) \
|
|
||||||
$(RCALL_SOURCES:.rcall=.spv)
|
|
||||||
|
|
||||||
%.spv: %.vert
|
|
||||||
glslc -o $@ $< -I$(INCLUDE_DIR) --target-env=vulkan1.1 $(GLSLC_FLAGS)
|
|
||||||
|
|
||||||
%.spv: %.frag
|
|
||||||
glslc -o $@ $< -I$(INCLUDE_DIR) --target-env=vulkan1.1 -DDEBUG_CHANNEL_HELPER_LANES $(GLSLC_FLAGS)
|
|
||||||
|
|
||||||
%.spv: %.comp
|
|
||||||
glslc -o $@ $< -I$(INCLUDE_DIR) --target-env=vulkan1.1 $(GLSLC_FLAGS)
|
|
||||||
|
|
||||||
%.spv: %.geom
|
|
||||||
glslc -o $@ $< -I$(INCLUDE_DIR) --target-env=vulkan1.1 $(GLSLC_FLAGS)
|
|
||||||
|
|
||||||
%.spv: %.tesc
|
|
||||||
glslc -o $@ $< -I$(INCLUDE_DIR) --target-env=vulkan1.1 $(GLSLC_FLAGS)
|
|
||||||
|
|
||||||
%.spv: %.tese
|
|
||||||
glslc -o $@ $< -I$(INCLUDE_DIR) --target-env=vulkan1.1 $(GLSLC_FLAGS)
|
|
||||||
|
|
||||||
%.spv: %.rgen
|
|
||||||
glslc -o $@ $< -I$(INCLUDE_DIR) --target-env=vulkan1.1 --target-spv=spv1.4 $(GLSLC_FLAGS)
|
|
||||||
|
|
||||||
%.spv: %.rint
|
|
||||||
glslc -o $@ $< -I$(INCLUDE_DIR) --target-env=vulkan1.1 --target-spv=spv1.4 $(GLSLC_FLAGS)
|
|
||||||
|
|
||||||
%.spv: %.rahit
|
|
||||||
glslc -o $@ $< -I$(INCLUDE_DIR) --target-env=vulkan1.1 --target-spv=spv1.4 $(GLSLC_FLAGS)
|
|
||||||
|
|
||||||
%.spv: %.rchit
|
|
||||||
glslc -o $@ $< -I$(INCLUDE_DIR) --target-env=vulkan1.1 --target-spv=spv1.4 $(GLSLC_FLAGS)
|
|
||||||
|
|
||||||
%.spv: %.rmiss
|
|
||||||
glslc -o $@ $< -I$(INCLUDE_DIR) --target-env=vulkan1.1 --target-spv=spv1.4 $(GLSLC_FLAGS)
|
|
||||||
|
|
||||||
%.spv: %.rcall
|
|
||||||
glslc -o $@ $< -I$(INCLUDE_DIR) --target-env=vulkan1.1 --target-spv=spv1.4 $(GLSLC_FLAGS)
|
|
||||||
|
|
||||||
all: $(SPV_OBJECTS)
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f $(SPV_OBJECTS)
|
|
||||||
|
|
||||||
.PHONY: clean
|
|
|
@ -23,17 +23,14 @@
|
||||||
#extension GL_ARB_gpu_shader_int64 : require
|
#extension GL_ARB_gpu_shader_int64 : require
|
||||||
#extension GL_KHR_shader_subgroup_basic : require
|
#extension GL_KHR_shader_subgroup_basic : require
|
||||||
#extension GL_KHR_shader_subgroup_ballot : require
|
#extension GL_KHR_shader_subgroup_ballot : require
|
||||||
#ifdef DEBUG_CHANNEL_HELPER_LANES
|
|
||||||
#extension GL_EXT_demote_to_helper_invocation : require
|
|
||||||
#endif
|
|
||||||
|
|
||||||
layout(buffer_reference, std430, buffer_reference_align = 4) coherent buffer ControlBlock
|
layout(buffer_reference, std430, buffer_reference_align = 4) buffer ControlBlock
|
||||||
{
|
{
|
||||||
uint message_counter;
|
uint message_counter;
|
||||||
uint instance_counter;
|
uint instance_counter;
|
||||||
};
|
};
|
||||||
|
|
||||||
layout(buffer_reference, std430, buffer_reference_align = 4) coherent buffer RingBuffer
|
layout(buffer_reference, std430, buffer_reference_align = 4) buffer RingBuffer
|
||||||
{
|
{
|
||||||
uint data[];
|
uint data[];
|
||||||
};
|
};
|
||||||
|
@ -51,73 +48,24 @@ const uint DEBUG_CHANNEL_FMT_F32 = 2;
|
||||||
const uint DEBUG_CHANNEL_FMT_HEX_ALL = DEBUG_CHANNEL_FMT_HEX * 0x55555555u;
|
const uint DEBUG_CHANNEL_FMT_HEX_ALL = DEBUG_CHANNEL_FMT_HEX * 0x55555555u;
|
||||||
const uint DEBUG_CHANNEL_FMT_I32_ALL = DEBUG_CHANNEL_FMT_I32 * 0x55555555u;
|
const uint DEBUG_CHANNEL_FMT_I32_ALL = DEBUG_CHANNEL_FMT_I32 * 0x55555555u;
|
||||||
const uint DEBUG_CHANNEL_FMT_F32_ALL = DEBUG_CHANNEL_FMT_F32 * 0x55555555u;
|
const uint DEBUG_CHANNEL_FMT_F32_ALL = DEBUG_CHANNEL_FMT_F32 * 0x55555555u;
|
||||||
const uint DEBUG_CHANNEL_WORD_COOKIE = 0xdeadca70u; /* Let host fish for this cookie in device lost scenarios. */
|
|
||||||
|
|
||||||
uint DEBUG_CHANNEL_INSTANCE_COUNTER;
|
uint DEBUG_CHANNEL_INSTANCE_COUNTER;
|
||||||
uvec3 DEBUG_CHANNEL_ID;
|
uvec3 DEBUG_CHANNEL_ID;
|
||||||
|
|
||||||
/* Need to make sure the elected subgroup can have side effects. */
|
|
||||||
#ifdef DEBUG_CHANNEL_HELPER_LANES
|
|
||||||
bool DEBUG_CHANNEL_ELECT()
|
|
||||||
{
|
|
||||||
bool elected = false;
|
|
||||||
if (!helperInvocationEXT())
|
|
||||||
elected = subgroupElect();
|
|
||||||
return elected;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
bool DEBUG_CHANNEL_ELECT()
|
|
||||||
{
|
|
||||||
return subgroupElect();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void DEBUG_CHANNEL_INIT(uvec3 id)
|
void DEBUG_CHANNEL_INIT(uvec3 id)
|
||||||
{
|
{
|
||||||
if (!DEBUG_SHADER_RING_ACTIVE)
|
if (!DEBUG_SHADER_RING_ACTIVE)
|
||||||
return;
|
return;
|
||||||
DEBUG_CHANNEL_ID = id;
|
DEBUG_CHANNEL_ID = id;
|
||||||
uint inst;
|
uint inst;
|
||||||
#ifdef DEBUG_CHANNEL_HELPER_LANES
|
|
||||||
if (!helperInvocationEXT())
|
|
||||||
{
|
|
||||||
/* Elect and broadcast must happen without helper lanes here.
|
|
||||||
* We must perform the instance increment with side effects,
|
|
||||||
* and broadcast first must pick the elected lane. */
|
|
||||||
if (subgroupElect())
|
if (subgroupElect())
|
||||||
inst = atomicAdd(ControlBlock(DEBUG_SHADER_ATOMIC_BDA).instance_counter, 1u);
|
inst = atomicAdd(ControlBlock(DEBUG_SHADER_ATOMIC_BDA).instance_counter, 1u);
|
||||||
DEBUG_CHANNEL_INSTANCE_COUNTER = subgroupBroadcastFirst(inst);
|
DEBUG_CHANNEL_INSTANCE_COUNTER = subgroupBroadcastFirst(inst);
|
||||||
}
|
|
||||||
/* Helper lanes cannot write debug messages, since they cannot have side effects.
|
|
||||||
* Leave it undefined, and we should ensure SGPR propagation either way ... */
|
|
||||||
#else
|
|
||||||
if (DEBUG_CHANNEL_ELECT())
|
|
||||||
inst = atomicAdd(ControlBlock(DEBUG_SHADER_ATOMIC_BDA).instance_counter, 1u);
|
|
||||||
DEBUG_CHANNEL_INSTANCE_COUNTER = subgroupBroadcastFirst(inst);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DEBUG_CHANNEL_INIT_IMPLICIT_INSTANCE(uvec3 id, uint inst)
|
void DEBUG_CHANNEL_WRITE_HEADER(RingBuffer buf, uint offset, uint num_words, uint fmt)
|
||||||
{
|
|
||||||
if (!DEBUG_SHADER_RING_ACTIVE)
|
|
||||||
return;
|
|
||||||
DEBUG_CHANNEL_ID = id;
|
|
||||||
DEBUG_CHANNEL_INSTANCE_COUNTER = inst;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DEBUG_CHANNEL_UNLOCK_MESSAGE(RingBuffer buf, uint offset, uint num_words)
|
|
||||||
{
|
|
||||||
memoryBarrierBuffer();
|
|
||||||
/* Make sure this word is made visible last. This way the ring thread can avoid reading bogus messages.
|
|
||||||
* If the host thread observed a num_word of 0, we know a message was allocated, but we don't necessarily
|
|
||||||
* have a complete write yet.
|
|
||||||
* In a device lost scenario, we can try to fish for valid messages. */
|
|
||||||
buf.data[(offset + 0) & DEBUG_SHADER_RING_MASK] = num_words | DEBUG_CHANNEL_WORD_COOKIE;
|
|
||||||
memoryBarrierBuffer();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DEBUG_CHANNEL_WRITE_HEADER(RingBuffer buf, uint offset, uint fmt)
|
|
||||||
{
|
{
|
||||||
|
buf.data[(offset + 0) & DEBUG_SHADER_RING_MASK] = num_words;
|
||||||
buf.data[(offset + 1) & DEBUG_SHADER_RING_MASK] = uint(DEBUG_SHADER_HASH);
|
buf.data[(offset + 1) & DEBUG_SHADER_RING_MASK] = uint(DEBUG_SHADER_HASH);
|
||||||
buf.data[(offset + 2) & DEBUG_SHADER_RING_MASK] = uint(DEBUG_SHADER_HASH >> 32);
|
buf.data[(offset + 2) & DEBUG_SHADER_RING_MASK] = uint(DEBUG_SHADER_HASH >> 32);
|
||||||
buf.data[(offset + 3) & DEBUG_SHADER_RING_MASK] = DEBUG_CHANNEL_INSTANCE_COUNTER;
|
buf.data[(offset + 3) & DEBUG_SHADER_RING_MASK] = DEBUG_CHANNEL_INSTANCE_COUNTER;
|
||||||
|
@ -139,9 +87,7 @@ void DEBUG_CHANNEL_MSG_()
|
||||||
return;
|
return;
|
||||||
uint words = 8;
|
uint words = 8;
|
||||||
uint offset = DEBUG_CHANNEL_ALLOCATE(words);
|
uint offset = DEBUG_CHANNEL_ALLOCATE(words);
|
||||||
RingBuffer buf = RingBuffer(DEBUG_SHADER_RING_BDA);
|
DEBUG_CHANNEL_WRITE_HEADER(RingBuffer(DEBUG_SHADER_RING_BDA), offset, words, 0);
|
||||||
DEBUG_CHANNEL_WRITE_HEADER(buf, offset, 0);
|
|
||||||
DEBUG_CHANNEL_UNLOCK_MESSAGE(buf, offset, words);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DEBUG_CHANNEL_MSG_(uint fmt, uint v0)
|
void DEBUG_CHANNEL_MSG_(uint fmt, uint v0)
|
||||||
|
@ -151,9 +97,8 @@ void DEBUG_CHANNEL_MSG_(uint fmt, uint v0)
|
||||||
RingBuffer buf = RingBuffer(DEBUG_SHADER_RING_BDA);
|
RingBuffer buf = RingBuffer(DEBUG_SHADER_RING_BDA);
|
||||||
uint words = 9;
|
uint words = 9;
|
||||||
uint offset = DEBUG_CHANNEL_ALLOCATE(words);
|
uint offset = DEBUG_CHANNEL_ALLOCATE(words);
|
||||||
DEBUG_CHANNEL_WRITE_HEADER(buf, offset, fmt);
|
DEBUG_CHANNEL_WRITE_HEADER(buf, offset, words, fmt);
|
||||||
buf.data[(offset + 8) & DEBUG_SHADER_RING_MASK] = v0;
|
buf.data[(offset + 8) & DEBUG_SHADER_RING_MASK] = v0;
|
||||||
DEBUG_CHANNEL_UNLOCK_MESSAGE(buf, offset, words);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DEBUG_CHANNEL_MSG_(uint fmt, uint v0, uint v1)
|
void DEBUG_CHANNEL_MSG_(uint fmt, uint v0, uint v1)
|
||||||
|
@ -163,10 +108,9 @@ void DEBUG_CHANNEL_MSG_(uint fmt, uint v0, uint v1)
|
||||||
RingBuffer buf = RingBuffer(DEBUG_SHADER_RING_BDA);
|
RingBuffer buf = RingBuffer(DEBUG_SHADER_RING_BDA);
|
||||||
uint words = 10;
|
uint words = 10;
|
||||||
uint offset = DEBUG_CHANNEL_ALLOCATE(words);
|
uint offset = DEBUG_CHANNEL_ALLOCATE(words);
|
||||||
DEBUG_CHANNEL_WRITE_HEADER(buf, offset, fmt);
|
DEBUG_CHANNEL_WRITE_HEADER(buf, offset, words, fmt);
|
||||||
buf.data[(offset + 8) & DEBUG_SHADER_RING_MASK] = v0;
|
buf.data[(offset + 8) & DEBUG_SHADER_RING_MASK] = v0;
|
||||||
buf.data[(offset + 9) & DEBUG_SHADER_RING_MASK] = v1;
|
buf.data[(offset + 9) & DEBUG_SHADER_RING_MASK] = v1;
|
||||||
DEBUG_CHANNEL_UNLOCK_MESSAGE(buf, offset, words);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DEBUG_CHANNEL_MSG_(uint fmt, uint v0, uint v1, uint v2)
|
void DEBUG_CHANNEL_MSG_(uint fmt, uint v0, uint v1, uint v2)
|
||||||
|
@ -176,11 +120,10 @@ void DEBUG_CHANNEL_MSG_(uint fmt, uint v0, uint v1, uint v2)
|
||||||
RingBuffer buf = RingBuffer(DEBUG_SHADER_RING_BDA);
|
RingBuffer buf = RingBuffer(DEBUG_SHADER_RING_BDA);
|
||||||
uint words = 11;
|
uint words = 11;
|
||||||
uint offset = DEBUG_CHANNEL_ALLOCATE(words);
|
uint offset = DEBUG_CHANNEL_ALLOCATE(words);
|
||||||
DEBUG_CHANNEL_WRITE_HEADER(buf, offset, fmt);
|
DEBUG_CHANNEL_WRITE_HEADER(buf, offset, words, fmt);
|
||||||
buf.data[(offset + 8) & DEBUG_SHADER_RING_MASK] = v0;
|
buf.data[(offset + 8) & DEBUG_SHADER_RING_MASK] = v0;
|
||||||
buf.data[(offset + 9) & DEBUG_SHADER_RING_MASK] = v1;
|
buf.data[(offset + 9) & DEBUG_SHADER_RING_MASK] = v1;
|
||||||
buf.data[(offset + 10) & DEBUG_SHADER_RING_MASK] = v2;
|
buf.data[(offset + 10) & DEBUG_SHADER_RING_MASK] = v2;
|
||||||
DEBUG_CHANNEL_UNLOCK_MESSAGE(buf, offset, words);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DEBUG_CHANNEL_MSG_(uint fmt, uint v0, uint v1, uint v2, uint v3)
|
void DEBUG_CHANNEL_MSG_(uint fmt, uint v0, uint v1, uint v2, uint v3)
|
||||||
|
@ -190,12 +133,11 @@ void DEBUG_CHANNEL_MSG_(uint fmt, uint v0, uint v1, uint v2, uint v3)
|
||||||
RingBuffer buf = RingBuffer(DEBUG_SHADER_RING_BDA);
|
RingBuffer buf = RingBuffer(DEBUG_SHADER_RING_BDA);
|
||||||
uint words = 12;
|
uint words = 12;
|
||||||
uint offset = DEBUG_CHANNEL_ALLOCATE(words);
|
uint offset = DEBUG_CHANNEL_ALLOCATE(words);
|
||||||
DEBUG_CHANNEL_WRITE_HEADER(buf, offset, fmt);
|
DEBUG_CHANNEL_WRITE_HEADER(buf, offset, words, fmt);
|
||||||
buf.data[(offset + 8) & DEBUG_SHADER_RING_MASK] = v0;
|
buf.data[(offset + 8) & DEBUG_SHADER_RING_MASK] = v0;
|
||||||
buf.data[(offset + 9) & DEBUG_SHADER_RING_MASK] = v1;
|
buf.data[(offset + 9) & DEBUG_SHADER_RING_MASK] = v1;
|
||||||
buf.data[(offset + 10) & DEBUG_SHADER_RING_MASK] = v2;
|
buf.data[(offset + 10) & DEBUG_SHADER_RING_MASK] = v2;
|
||||||
buf.data[(offset + 11) & DEBUG_SHADER_RING_MASK] = v3;
|
buf.data[(offset + 11) & DEBUG_SHADER_RING_MASK] = v3;
|
||||||
DEBUG_CHANNEL_UNLOCK_MESSAGE(buf, offset, words);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DEBUG_CHANNEL_MSG()
|
void DEBUG_CHANNEL_MSG()
|
||||||
|
@ -263,76 +205,4 @@ void DEBUG_CHANNEL_MSG(float v0, float v1, float v2, float v3)
|
||||||
DEBUG_CHANNEL_MSG_(DEBUG_CHANNEL_FMT_F32_ALL, floatBitsToUint(v0), floatBitsToUint(v1), floatBitsToUint(v2), floatBitsToUint(v3));
|
DEBUG_CHANNEL_MSG_(DEBUG_CHANNEL_FMT_F32_ALL, floatBitsToUint(v0), floatBitsToUint(v1), floatBitsToUint(v2), floatBitsToUint(v3));
|
||||||
}
|
}
|
||||||
|
|
||||||
void DEBUG_CHANNEL_MSG_UNIFORM(uint v0)
|
|
||||||
{
|
|
||||||
if (DEBUG_CHANNEL_ELECT())
|
|
||||||
DEBUG_CHANNEL_MSG(v0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DEBUG_CHANNEL_MSG_UNIFORM(uint v0, uint v1)
|
|
||||||
{
|
|
||||||
if (DEBUG_CHANNEL_ELECT())
|
|
||||||
DEBUG_CHANNEL_MSG(v0, v1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DEBUG_CHANNEL_MSG_UNIFORM(uint v0, uint v1, uint v2)
|
|
||||||
{
|
|
||||||
if (DEBUG_CHANNEL_ELECT())
|
|
||||||
DEBUG_CHANNEL_MSG(v0, v1, v2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DEBUG_CHANNEL_MSG_UNIFORM(uint v0, uint v1, uint v2, uint v3)
|
|
||||||
{
|
|
||||||
if (DEBUG_CHANNEL_ELECT())
|
|
||||||
DEBUG_CHANNEL_MSG(v0, v1, v2, v3);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DEBUG_CHANNEL_MSG_UNIFORM(int v0)
|
|
||||||
{
|
|
||||||
if (DEBUG_CHANNEL_ELECT())
|
|
||||||
DEBUG_CHANNEL_MSG(v0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DEBUG_CHANNEL_MSG_UNIFORM(int v0, int v1)
|
|
||||||
{
|
|
||||||
if (DEBUG_CHANNEL_ELECT())
|
|
||||||
DEBUG_CHANNEL_MSG(v0, v1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DEBUG_CHANNEL_MSG_UNIFORM(int v0, int v1, int v2)
|
|
||||||
{
|
|
||||||
if (DEBUG_CHANNEL_ELECT())
|
|
||||||
DEBUG_CHANNEL_MSG(v0, v1, v2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DEBUG_CHANNEL_MSG_UNIFORM(int v0, int v1, int v2, int v3)
|
|
||||||
{
|
|
||||||
if (DEBUG_CHANNEL_ELECT())
|
|
||||||
DEBUG_CHANNEL_MSG(v0, v1, v2, v3);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DEBUG_CHANNEL_MSG_UNIFORM(float v0)
|
|
||||||
{
|
|
||||||
if (DEBUG_CHANNEL_ELECT())
|
|
||||||
DEBUG_CHANNEL_MSG(v0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DEBUG_CHANNEL_MSG_UNIFORM(float v0, float v1)
|
|
||||||
{
|
|
||||||
if (DEBUG_CHANNEL_ELECT())
|
|
||||||
DEBUG_CHANNEL_MSG(v0, v1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DEBUG_CHANNEL_MSG_UNIFORM(float v0, float v1, float v2)
|
|
||||||
{
|
|
||||||
if (DEBUG_CHANNEL_ELECT())
|
|
||||||
DEBUG_CHANNEL_MSG(v0, v1, v2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DEBUG_CHANNEL_MSG_UNIFORM(float v0, float v1, float v2, float v3)
|
|
||||||
{
|
|
||||||
if (DEBUG_CHANNEL_ELECT())
|
|
||||||
DEBUG_CHANNEL_MSG(v0, v1, v2, v3);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
100
include/vkd3d.h
100
include/vkd3d.h
|
@ -31,12 +31,8 @@
|
||||||
# define VK_USE_PLATFORM_WIN32_KHR
|
# define VK_USE_PLATFORM_WIN32_KHR
|
||||||
# endif
|
# endif
|
||||||
# include <vulkan/vulkan.h>
|
# include <vulkan/vulkan.h>
|
||||||
# include "private/vulkan_private_extensions.h"
|
|
||||||
#endif /* VKD3D_NO_VULKAN_H */
|
#endif /* VKD3D_NO_VULKAN_H */
|
||||||
|
|
||||||
#define VKD3D_MIN_API_VERSION VK_API_VERSION_1_1
|
|
||||||
#define VKD3D_MAX_API_VERSION VK_API_VERSION_1_1
|
|
||||||
|
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
# define DECLSPEC_VISIBLE __attribute__((visibility("default")))
|
# define DECLSPEC_VISIBLE __attribute__((visibility("default")))
|
||||||
#else
|
#else
|
||||||
|
@ -59,39 +55,22 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
#define VKD3D_CONFIG_FLAG_VULKAN_DEBUG (1ull << 0)
|
enum vkd3d_structure_type
|
||||||
#define VKD3D_CONFIG_FLAG_SKIP_APPLICATION_WORKAROUNDS (1ull << 1)
|
{
|
||||||
#define VKD3D_CONFIG_FLAG_DEBUG_UTILS (1ull << 2)
|
/* 1.0 */
|
||||||
#define VKD3D_CONFIG_FLAG_FORCE_STATIC_CBV (1ull << 3)
|
VKD3D_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
|
||||||
#define VKD3D_CONFIG_FLAG_DXR (1ull << 4)
|
VKD3D_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
|
||||||
#define VKD3D_CONFIG_FLAG_SINGLE_QUEUE (1ull << 5)
|
VKD3D_STRUCTURE_TYPE_IMAGE_RESOURCE_CREATE_INFO,
|
||||||
#define VKD3D_CONFIG_FLAG_DESCRIPTOR_QA_CHECKS (1ull << 6)
|
|
||||||
#define VKD3D_CONFIG_FLAG_FORCE_RTV_EXCLUSIVE_QUEUE (1ull << 7)
|
/* 1.1 */
|
||||||
#define VKD3D_CONFIG_FLAG_FORCE_DSV_EXCLUSIVE_QUEUE (1ull << 8)
|
VKD3D_STRUCTURE_TYPE_OPTIONAL_INSTANCE_EXTENSIONS_INFO,
|
||||||
#define VKD3D_CONFIG_FLAG_FORCE_MINIMUM_SUBGROUP_SIZE (1ull << 9)
|
|
||||||
#define VKD3D_CONFIG_FLAG_NO_UPLOAD_HVV (1ull << 10)
|
/* 1.2 */
|
||||||
#define VKD3D_CONFIG_FLAG_LOG_MEMORY_BUDGET (1ull << 11)
|
VKD3D_STRUCTURE_TYPE_OPTIONAL_DEVICE_EXTENSIONS_INFO,
|
||||||
#define VKD3D_CONFIG_FLAG_IGNORE_RTV_HOST_VISIBLE (1ull << 12)
|
VKD3D_STRUCTURE_TYPE_APPLICATION_INFO,
|
||||||
#define VKD3D_CONFIG_FLAG_FORCE_HOST_CACHED (1ull << 13)
|
|
||||||
#define VKD3D_CONFIG_FLAG_DXR11 (1ull << 14)
|
VKD3D_FORCE_32_BIT_ENUM(VKD3D_STRUCTURE_TYPE),
|
||||||
#define VKD3D_CONFIG_FLAG_FORCE_NO_INVARIANT_POSITION (1ull << 15)
|
};
|
||||||
#define VKD3D_CONFIG_FLAG_GLOBAL_PIPELINE_CACHE (1ull << 16)
|
|
||||||
#define VKD3D_CONFIG_FLAG_PIPELINE_LIBRARY_NO_SERIALIZE_SPIRV (1ull << 17)
|
|
||||||
#define VKD3D_CONFIG_FLAG_PIPELINE_LIBRARY_SANITIZE_SPIRV (1ull << 18)
|
|
||||||
#define VKD3D_CONFIG_FLAG_PIPELINE_LIBRARY_LOG (1ull << 19)
|
|
||||||
#define VKD3D_CONFIG_FLAG_PIPELINE_LIBRARY_IGNORE_SPIRV (1ull << 20)
|
|
||||||
#define VKD3D_CONFIG_FLAG_MUTABLE_SINGLE_SET (1ull << 21)
|
|
||||||
#define VKD3D_CONFIG_FLAG_MEMORY_ALLOCATOR_SKIP_CLEAR (1ull << 22)
|
|
||||||
#define VKD3D_CONFIG_FLAG_RECYCLE_COMMAND_POOLS (1ull << 23)
|
|
||||||
#define VKD3D_CONFIG_FLAG_PIPELINE_LIBRARY_IGNORE_MISMATCH_DRIVER (1ull << 24)
|
|
||||||
#define VKD3D_CONFIG_FLAG_BREADCRUMBS (1ull << 25)
|
|
||||||
#define VKD3D_CONFIG_FLAG_PIPELINE_LIBRARY_APP_CACHE_ONLY (1ull << 26)
|
|
||||||
#define VKD3D_CONFIG_FLAG_SHADER_CACHE_SYNC (1ull << 27)
|
|
||||||
#define VKD3D_CONFIG_FLAG_FORCE_RAW_VA_CBV (1ull << 28)
|
|
||||||
#define VKD3D_CONFIG_FLAG_ZERO_MEMORY_WORKAROUNDS_COMMITTED_BUFFER_UAV (1ull << 29)
|
|
||||||
#define VKD3D_CONFIG_FLAG_ALLOW_SBT_COLLECTION (1ull << 30)
|
|
||||||
#define VKD3D_CONFIG_FLAG_FORCE_NATIVE_FP16 (1ull << 31)
|
|
||||||
#define VKD3D_CONFIG_FLAG_USE_HOST_IMPORT_FALLBACK (1ull << 32)
|
|
||||||
|
|
||||||
typedef HRESULT (*PFN_vkd3d_signal_event)(HANDLE event);
|
typedef HRESULT (*PFN_vkd3d_signal_event)(HANDLE event);
|
||||||
|
|
||||||
|
@ -104,22 +83,49 @@ struct vkd3d_instance;
|
||||||
|
|
||||||
struct vkd3d_instance_create_info
|
struct vkd3d_instance_create_info
|
||||||
{
|
{
|
||||||
|
enum vkd3d_structure_type type;
|
||||||
|
const void *next;
|
||||||
|
|
||||||
PFN_vkd3d_signal_event pfn_signal_event;
|
PFN_vkd3d_signal_event pfn_signal_event;
|
||||||
PFN_vkd3d_create_thread pfn_create_thread;
|
PFN_vkd3d_create_thread pfn_create_thread;
|
||||||
PFN_vkd3d_join_thread pfn_join_thread;
|
PFN_vkd3d_join_thread pfn_join_thread;
|
||||||
|
size_t wchar_size;
|
||||||
|
|
||||||
/* If set to NULL, libvkd3d loads libvulkan. */
|
/* If set to NULL, libvkd3d loads libvulkan. */
|
||||||
PFN_vkGetInstanceProcAddr pfn_vkGetInstanceProcAddr;
|
PFN_vkGetInstanceProcAddr pfn_vkGetInstanceProcAddr;
|
||||||
|
|
||||||
const char * const *instance_extensions;
|
const char * const *instance_extensions;
|
||||||
uint32_t instance_extension_count;
|
uint32_t instance_extension_count;
|
||||||
|
};
|
||||||
|
|
||||||
const char * const *optional_instance_extensions;
|
/* Extends vkd3d_instance_create_info. Available since 1.1. */
|
||||||
uint32_t optional_instance_extension_count;
|
struct vkd3d_optional_instance_extensions_info
|
||||||
|
{
|
||||||
|
enum vkd3d_structure_type type;
|
||||||
|
const void *next;
|
||||||
|
|
||||||
|
const char * const *extensions;
|
||||||
|
uint32_t extension_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Extends vkd3d_instance_create_info. Available since 1.2. */
|
||||||
|
struct vkd3d_application_info
|
||||||
|
{
|
||||||
|
enum vkd3d_structure_type type;
|
||||||
|
const void *next;
|
||||||
|
|
||||||
|
const char *application_name;
|
||||||
|
uint32_t application_version;
|
||||||
|
|
||||||
|
const char *engine_name; /* "vkd3d" if NULL */
|
||||||
|
uint32_t engine_version; /* vkd3d version if engine_name is NULL */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct vkd3d_device_create_info
|
struct vkd3d_device_create_info
|
||||||
{
|
{
|
||||||
|
enum vkd3d_structure_type type;
|
||||||
|
const void *next;
|
||||||
|
|
||||||
D3D_FEATURE_LEVEL minimum_feature_level;
|
D3D_FEATURE_LEVEL minimum_feature_level;
|
||||||
|
|
||||||
struct vkd3d_instance *instance;
|
struct vkd3d_instance *instance;
|
||||||
|
@ -130,15 +136,25 @@ struct vkd3d_device_create_info
|
||||||
const char * const *device_extensions;
|
const char * const *device_extensions;
|
||||||
uint32_t device_extension_count;
|
uint32_t device_extension_count;
|
||||||
|
|
||||||
const char * const *optional_device_extensions;
|
|
||||||
uint32_t optional_device_extension_count;
|
|
||||||
|
|
||||||
IUnknown *parent;
|
IUnknown *parent;
|
||||||
LUID adapter_luid;
|
LUID adapter_luid;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Extends vkd3d_device_create_info. Available since 1.2. */
|
||||||
|
struct vkd3d_optional_device_extensions_info
|
||||||
|
{
|
||||||
|
enum vkd3d_structure_type type;
|
||||||
|
const void *next;
|
||||||
|
|
||||||
|
const char * const *extensions;
|
||||||
|
uint32_t extension_count;
|
||||||
|
};
|
||||||
|
|
||||||
struct vkd3d_image_resource_create_info
|
struct vkd3d_image_resource_create_info
|
||||||
{
|
{
|
||||||
|
enum vkd3d_structure_type type;
|
||||||
|
const void *next;
|
||||||
|
|
||||||
VkImage vk_image;
|
VkImage vk_image;
|
||||||
D3D12_RESOURCE_DESC desc;
|
D3D12_RESOURCE_DESC desc;
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
/*
|
|
||||||
* * Copyright 2021 NVIDIA Corporation
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
||||||
*/
|
|
||||||
import "vkd3d_d3d12.idl";
|
|
||||||
import "vkd3d_vk_includes.h";
|
|
||||||
|
|
||||||
[
|
|
||||||
uuid(77a86b09-2bea-4801-b89a-37648e104af1),
|
|
||||||
object,
|
|
||||||
local,
|
|
||||||
pointer_default(unique)
|
|
||||||
]
|
|
||||||
interface ID3D12GraphicsCommandListExt : IUnknown
|
|
||||||
{
|
|
||||||
HRESULT GetVulkanHandle(VkCommandBuffer *pVkCommandBuffer);
|
|
||||||
HRESULT LaunchCubinShader(D3D12_CUBIN_DATA_HANDLE *handle, UINT32 block_x, UINT32 block_y, UINT32 block_z, const void *params, UINT32 param_size);
|
|
||||||
}
|
|
||||||
|
|
|
@ -26,11 +26,11 @@ cpp_quote("#ifndef _D3D12_CONSTANTS")
|
||||||
cpp_quote("#define _D3D12_CONSTANTS")
|
cpp_quote("#define _D3D12_CONSTANTS")
|
||||||
|
|
||||||
cpp_quote("#ifndef D3D12_ERROR_ADAPTER_NOT_FOUND")
|
cpp_quote("#ifndef D3D12_ERROR_ADAPTER_NOT_FOUND")
|
||||||
cpp_quote("#define D3D12_ERROR_ADAPTER_NOT_FOUND ((HRESULT)0x887e0001)")
|
cpp_quote("#define D3D12_ERROR_ADAPTER_NOT_FOUND 0x887e0001")
|
||||||
cpp_quote("#endif")
|
cpp_quote("#endif")
|
||||||
|
|
||||||
cpp_quote("#ifndef D3D12_ERROR_DRIVER_VERSION_MISMATCH")
|
cpp_quote("#ifndef D3D12_ERROR_DRIVER_VERSION_MISMATCH")
|
||||||
cpp_quote("#define D3D12_ERROR_DRIVER_VERSION_MISMATCH ((HRESULT)0x887e0002)")
|
cpp_quote("#define D3D12_ERROR_DRIVER_VERSION_MISMATCH 0x887e0002")
|
||||||
cpp_quote("#endif")
|
cpp_quote("#endif")
|
||||||
|
|
||||||
const UINT D3D12_CS_TGSM_REGISTER_COUNT = 8192;
|
const UINT D3D12_CS_TGSM_REGISTER_COUNT = 8192;
|
||||||
|
@ -109,7 +109,6 @@ typedef enum D3D12_SHADER_MIN_PRECISION_SUPPORT
|
||||||
D3D12_SHADER_MIN_PRECISION_SUPPORT_10_BIT = 0x1,
|
D3D12_SHADER_MIN_PRECISION_SUPPORT_10_BIT = 0x1,
|
||||||
D3D12_SHADER_MIN_PRECISION_SUPPORT_16_BIT = 0x2,
|
D3D12_SHADER_MIN_PRECISION_SUPPORT_16_BIT = 0x2,
|
||||||
} D3D12_SHADER_MIN_PRECISION_SUPPORT;
|
} D3D12_SHADER_MIN_PRECISION_SUPPORT;
|
||||||
cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_SHADER_MIN_PRECISION_SUPPORT);")
|
|
||||||
|
|
||||||
typedef enum D3D12_TILED_RESOURCES_TIER
|
typedef enum D3D12_TILED_RESOURCES_TIER
|
||||||
{
|
{
|
||||||
|
@ -169,7 +168,6 @@ typedef enum D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER
|
||||||
{
|
{
|
||||||
D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER_0 = 0,
|
D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER_0 = 0,
|
||||||
D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER_1 = 1,
|
D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER_1 = 1,
|
||||||
D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER_2 = 2,
|
|
||||||
} D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER;
|
} D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER;
|
||||||
|
|
||||||
typedef enum D3D12_HEAP_SERIALIZATION_TIER
|
typedef enum D3D12_HEAP_SERIALIZATION_TIER
|
||||||
|
@ -189,7 +187,6 @@ typedef enum D3D12_RAYTRACING_TIER
|
||||||
{
|
{
|
||||||
D3D12_RAYTRACING_TIER_NOT_SUPPORTED = 0,
|
D3D12_RAYTRACING_TIER_NOT_SUPPORTED = 0,
|
||||||
D3D12_RAYTRACING_TIER_1_0 = 10,
|
D3D12_RAYTRACING_TIER_1_0 = 10,
|
||||||
D3D12_RAYTRACING_TIER_1_1 = 11,
|
|
||||||
} D3D12_RAYTRACING_TIER;
|
} D3D12_RAYTRACING_TIER;
|
||||||
|
|
||||||
typedef enum D3D12_VARIABLE_SHADING_RATE_TIER
|
typedef enum D3D12_VARIABLE_SHADING_RATE_TIER
|
||||||
|
@ -199,19 +196,6 @@ typedef enum D3D12_VARIABLE_SHADING_RATE_TIER
|
||||||
D3D12_VARIABLE_SHADING_RATE_TIER_2 = 2,
|
D3D12_VARIABLE_SHADING_RATE_TIER_2 = 2,
|
||||||
} D3D12_VARIABLE_SHADING_RATE_TIER;
|
} D3D12_VARIABLE_SHADING_RATE_TIER;
|
||||||
|
|
||||||
typedef enum D3D12_MESH_SHADER_TIER
|
|
||||||
{
|
|
||||||
D3D12_MESH_SHADER_TIER_NOT_SUPPORTED = 0,
|
|
||||||
D3D12_MESH_SHADER_TIER_1 = 10,
|
|
||||||
} D3D12_MESH_SHADER_TIER;
|
|
||||||
|
|
||||||
typedef enum D3D12_SAMPLER_FEEDBACK_TIER
|
|
||||||
{
|
|
||||||
D3D12_SAMPLER_FEEDBACK_TIER_NOT_SUPPORTED = 0,
|
|
||||||
D3D12_SAMPLER_FEEDBACK_TIER_0_9 = 90,
|
|
||||||
D3D12_SAMPLER_FEEDBACK_TIER_1_0 = 100,
|
|
||||||
} D3D12_SAMPLER_FEEDBACK_TIER;
|
|
||||||
|
|
||||||
typedef enum D3D12_COMMAND_LIST_SUPPORT_FLAGS
|
typedef enum D3D12_COMMAND_LIST_SUPPORT_FLAGS
|
||||||
{
|
{
|
||||||
D3D12_COMMAND_LIST_SUPPORT_FLAG_NONE = 0x0,
|
D3D12_COMMAND_LIST_SUPPORT_FLAG_NONE = 0x0,
|
||||||
|
@ -221,9 +205,7 @@ typedef enum D3D12_COMMAND_LIST_SUPPORT_FLAGS
|
||||||
D3D12_COMMAND_LIST_SUPPORT_FLAG_COPY = 0x8,
|
D3D12_COMMAND_LIST_SUPPORT_FLAG_COPY = 0x8,
|
||||||
D3D12_COMMAND_LIST_SUPPORT_FLAG_VIDEO_DECODE = 0x10,
|
D3D12_COMMAND_LIST_SUPPORT_FLAG_VIDEO_DECODE = 0x10,
|
||||||
D3D12_COMMAND_LIST_SUPPORT_FLAG_VIDEO_PROCESS = 0x20,
|
D3D12_COMMAND_LIST_SUPPORT_FLAG_VIDEO_PROCESS = 0x20,
|
||||||
D3D12_COMMAND_LIST_SUPPORT_FLAG_VIDEO_ENCODE = 0x40,
|
|
||||||
} D3D12_COMMAND_LIST_SUPPORT_FLAGS;
|
} D3D12_COMMAND_LIST_SUPPORT_FLAGS;
|
||||||
cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_COMMAND_LIST_SUPPORT_FLAGS);")
|
|
||||||
|
|
||||||
typedef enum D3D12_FORMAT_SUPPORT1
|
typedef enum D3D12_FORMAT_SUPPORT1
|
||||||
{
|
{
|
||||||
|
@ -258,7 +240,6 @@ typedef enum D3D12_FORMAT_SUPPORT1
|
||||||
D3D12_FORMAT_SUPPORT1_VIDEO_PROCESSOR_INPUT = 0x20000000,
|
D3D12_FORMAT_SUPPORT1_VIDEO_PROCESSOR_INPUT = 0x20000000,
|
||||||
D3D12_FORMAT_SUPPORT1_VIDEO_ENCODER = 0x40000000,
|
D3D12_FORMAT_SUPPORT1_VIDEO_ENCODER = 0x40000000,
|
||||||
} D3D12_FORMAT_SUPPORT1;
|
} D3D12_FORMAT_SUPPORT1;
|
||||||
cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_FORMAT_SUPPORT1);")
|
|
||||||
|
|
||||||
typedef enum D3D12_FORMAT_SUPPORT2
|
typedef enum D3D12_FORMAT_SUPPORT2
|
||||||
{
|
{
|
||||||
|
@ -274,9 +255,7 @@ typedef enum D3D12_FORMAT_SUPPORT2
|
||||||
D3D12_FORMAT_SUPPORT2_OUTPUT_MERGER_LOGIC_OP = 0x00000100,
|
D3D12_FORMAT_SUPPORT2_OUTPUT_MERGER_LOGIC_OP = 0x00000100,
|
||||||
D3D12_FORMAT_SUPPORT2_TILED = 0x00000200,
|
D3D12_FORMAT_SUPPORT2_TILED = 0x00000200,
|
||||||
D3D12_FORMAT_SUPPORT2_MULTIPLANE_OVERLAY = 0x00004000,
|
D3D12_FORMAT_SUPPORT2_MULTIPLANE_OVERLAY = 0x00004000,
|
||||||
D3D12_FORMAT_SUPPORT2_SAMPLER_FEEDBACK = 0x00008000,
|
|
||||||
} D3D12_FORMAT_SUPPORT2;
|
} D3D12_FORMAT_SUPPORT2;
|
||||||
cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_FORMAT_SUPPORT2);")
|
|
||||||
|
|
||||||
typedef enum D3D12_WRITEBUFFERIMMEDIATE_MODE
|
typedef enum D3D12_WRITEBUFFERIMMEDIATE_MODE
|
||||||
{
|
{
|
||||||
|
@ -285,12 +264,6 @@ typedef enum D3D12_WRITEBUFFERIMMEDIATE_MODE
|
||||||
D3D12_WRITEBUFFERIMMEDIATE_MODE_MARKER_OUT = 0x2,
|
D3D12_WRITEBUFFERIMMEDIATE_MODE_MARKER_OUT = 0x2,
|
||||||
} D3D12_WRITEBUFFERIMMEDIATE_MODE;
|
} D3D12_WRITEBUFFERIMMEDIATE_MODE;
|
||||||
|
|
||||||
typedef enum D3D12_WAVE_MMA_TIER
|
|
||||||
{
|
|
||||||
D3D12_WAVE_MMA_TIER_NOT_SUPPORTED = 0,
|
|
||||||
D3D12_WAVE_MMA_TIER_1_0 = 10,
|
|
||||||
} D3D12_WAVE_MMA_TIER;
|
|
||||||
|
|
||||||
interface ID3D12Fence;
|
interface ID3D12Fence;
|
||||||
interface ID3D12RootSignature;
|
interface ID3D12RootSignature;
|
||||||
interface ID3D12Heap;
|
interface ID3D12Heap;
|
||||||
|
@ -342,13 +315,6 @@ typedef struct D3D12_SUBRESOURCE_RANGE_UINT64
|
||||||
D3D12_RANGE_UINT64 Range;
|
D3D12_RANGE_UINT64 Range;
|
||||||
} D3D12_SUBRESOURCE_RANGE_UINT64;
|
} D3D12_SUBRESOURCE_RANGE_UINT64;
|
||||||
|
|
||||||
typedef struct D3D12_SUBRESOURCE_INFO
|
|
||||||
{
|
|
||||||
UINT64 Offset;
|
|
||||||
UINT RowPitch;
|
|
||||||
UINT DepthPitch;
|
|
||||||
} D3D12_SUBRESOURCE_INFO;
|
|
||||||
|
|
||||||
typedef struct D3D12_RESOURCE_ALLOCATION_INFO
|
typedef struct D3D12_RESOURCE_ALLOCATION_INFO
|
||||||
{
|
{
|
||||||
UINT64 SizeInBytes;
|
UINT64 SizeInBytes;
|
||||||
|
@ -453,38 +419,6 @@ typedef struct D3D12_FEATURE_DATA_D3D12_OPTIONS6
|
||||||
BOOL BackgroundProcessingSupported;
|
BOOL BackgroundProcessingSupported;
|
||||||
} D3D12_FEATURE_DATA_D3D12_OPTIONS6;
|
} D3D12_FEATURE_DATA_D3D12_OPTIONS6;
|
||||||
|
|
||||||
typedef struct D3D12_FEATURE_DATA_D3D12_OPTIONS7
|
|
||||||
{
|
|
||||||
D3D12_MESH_SHADER_TIER MeshShaderTier;
|
|
||||||
D3D12_SAMPLER_FEEDBACK_TIER SamplerFeedbackTier;
|
|
||||||
} D3D12_FEATURE_DATA_D3D12_OPTIONS7;
|
|
||||||
|
|
||||||
typedef struct D3D12_FEATURE_DATA_D3D12_OPTIONS8
|
|
||||||
{
|
|
||||||
BOOL UnalignedBlockTexturesSupported;
|
|
||||||
} D3D12_FEATURE_DATA_D3D12_OPTIONS8;
|
|
||||||
|
|
||||||
typedef struct D3D12_FEATURE_DATA_D3D12_OPTIONS9
|
|
||||||
{
|
|
||||||
BOOL MeshShaderPipelineStatsSupported;
|
|
||||||
BOOL MeshShaderSupportsFullRangeRenderTargetArrayIndex;
|
|
||||||
BOOL AtomicInt64OnTypedResourceSupported;
|
|
||||||
BOOL AtomicInt64OnGroupSharedSupported;
|
|
||||||
BOOL DerivativesInMeshAndAmplificationShadersSupported;
|
|
||||||
D3D12_WAVE_MMA_TIER WaveMMATier;
|
|
||||||
} D3D12_FEATURE_DATA_D3D12_OPTIONS9;
|
|
||||||
|
|
||||||
typedef struct D3D12_FEATURE_DATA_D3D12_OPTIONS10
|
|
||||||
{
|
|
||||||
BOOL VariableRateShadingSumCombinerSupported;
|
|
||||||
BOOL MeshShaderPerPrimitiveShadingRateSupported;
|
|
||||||
} D3D12_FEATURE_DATA_D3D12_OPTIONS10;
|
|
||||||
|
|
||||||
typedef struct D3D12_FEATURE_DATA_D3D12_OPTIONS11
|
|
||||||
{
|
|
||||||
BOOL AtomicInt64OnDescriptorHeapResourceSupported;
|
|
||||||
} D3D12_FEATURE_DATA_D3D12_OPTIONS11;
|
|
||||||
|
|
||||||
typedef struct D3D12_FEATURE_DATA_FORMAT_SUPPORT
|
typedef struct D3D12_FEATURE_DATA_FORMAT_SUPPORT
|
||||||
{
|
{
|
||||||
DXGI_FORMAT Format;
|
DXGI_FORMAT Format;
|
||||||
|
@ -497,7 +431,6 @@ typedef enum D3D12_MULTISAMPLE_QUALITY_LEVEL_FLAGS
|
||||||
D3D12_MULTISAMPLE_QUALITY_LEVELS_FLAG_NONE = 0x00000000,
|
D3D12_MULTISAMPLE_QUALITY_LEVELS_FLAG_NONE = 0x00000000,
|
||||||
D3D12_MULTISAMPLE_QUALITY_LEVELS_FLAG_TILED_RESOURCE = 0x00000001,
|
D3D12_MULTISAMPLE_QUALITY_LEVELS_FLAG_TILED_RESOURCE = 0x00000001,
|
||||||
} D3D12_MULTISAMPLE_QUALITY_LEVEL_FLAGS;
|
} D3D12_MULTISAMPLE_QUALITY_LEVEL_FLAGS;
|
||||||
cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_MULTISAMPLE_QUALITY_LEVEL_FLAGS);")
|
|
||||||
|
|
||||||
typedef struct D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS
|
typedef struct D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS
|
||||||
{
|
{
|
||||||
|
@ -575,17 +508,11 @@ typedef enum D3D12_HEAP_FLAGS
|
||||||
D3D12_HEAP_FLAG_SHARED_CROSS_ADAPTER = 0x20,
|
D3D12_HEAP_FLAG_SHARED_CROSS_ADAPTER = 0x20,
|
||||||
D3D12_HEAP_FLAG_DENY_RT_DS_TEXTURES = 0x40,
|
D3D12_HEAP_FLAG_DENY_RT_DS_TEXTURES = 0x40,
|
||||||
D3D12_HEAP_FLAG_DENY_NON_RT_DS_TEXTURES = 0x80,
|
D3D12_HEAP_FLAG_DENY_NON_RT_DS_TEXTURES = 0x80,
|
||||||
D3D12_HEAP_FLAG_HARDWARE_PROTECTED = 0x100,
|
|
||||||
D3D12_HEAP_FLAG_ALLOW_WRITE_WATCH = 0x200,
|
|
||||||
D3D12_HEAP_FLAG_ALLOW_SHADER_ATOMICS = 0x400,
|
|
||||||
D3D12_HEAP_FLAG_CREATE_NOT_RESIDENT = 0x800,
|
|
||||||
D3D12_HEAP_FLAG_CREATE_NOT_ZEROED = 0x1000,
|
|
||||||
D3D12_HEAP_FLAG_ALLOW_ALL_BUFFERS_AND_TEXTURES = 0x00,
|
D3D12_HEAP_FLAG_ALLOW_ALL_BUFFERS_AND_TEXTURES = 0x00,
|
||||||
D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS = 0xc0,
|
D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS = 0xc0,
|
||||||
D3D12_HEAP_FLAG_ALLOW_ONLY_NON_RT_DS_TEXTURES = 0x44,
|
D3D12_HEAP_FLAG_ALLOW_ONLY_NON_RT_DS_TEXTURES = 0x44,
|
||||||
D3D12_HEAP_FLAG_ALLOW_ONLY_RT_DS_TEXTURES = 0x84,
|
D3D12_HEAP_FLAG_ALLOW_ONLY_RT_DS_TEXTURES = 0x84,
|
||||||
} D3D12_HEAP_FLAGS;
|
} D3D12_HEAP_FLAGS;
|
||||||
cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_HEAP_FLAGS);")
|
|
||||||
|
|
||||||
typedef struct D3D12_HEAP_DESC
|
typedef struct D3D12_HEAP_DESC
|
||||||
{
|
{
|
||||||
|
@ -701,7 +628,6 @@ typedef enum D3D12_RESOURCE_BARRIER_FLAGS
|
||||||
D3D12_RESOURCE_BARRIER_FLAG_BEGIN_ONLY = 0x1,
|
D3D12_RESOURCE_BARRIER_FLAG_BEGIN_ONLY = 0x1,
|
||||||
D3D12_RESOURCE_BARRIER_FLAG_END_ONLY = 0x2,
|
D3D12_RESOURCE_BARRIER_FLAG_END_ONLY = 0x2,
|
||||||
} D3D12_RESOURCE_BARRIER_FLAGS;
|
} D3D12_RESOURCE_BARRIER_FLAGS;
|
||||||
cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_RESOURCE_BARRIER_FLAGS);")
|
|
||||||
|
|
||||||
typedef struct D3D12_RESOURCE_TRANSITION_BARRIER
|
typedef struct D3D12_RESOURCE_TRANSITION_BARRIER
|
||||||
{
|
{
|
||||||
|
@ -711,7 +637,7 @@ typedef struct D3D12_RESOURCE_TRANSITION_BARRIER
|
||||||
D3D12_RESOURCE_STATES StateAfter;
|
D3D12_RESOURCE_STATES StateAfter;
|
||||||
} D3D12_RESOURCE_TRANSITION_BARRIER;
|
} D3D12_RESOURCE_TRANSITION_BARRIER;
|
||||||
|
|
||||||
typedef struct D3D12_RESOURCE_ALIASING_BARRIER
|
typedef struct D3D12_RESOURCE_ALIASING_BARRIER_ALIASING
|
||||||
{
|
{
|
||||||
ID3D12Resource *pResourceBefore;
|
ID3D12Resource *pResourceBefore;
|
||||||
ID3D12Resource *pResourceAfter;
|
ID3D12Resource *pResourceAfter;
|
||||||
|
@ -778,36 +704,12 @@ typedef struct D3D12_RESOURCE_DESC
|
||||||
D3D12_RESOURCE_FLAGS Flags;
|
D3D12_RESOURCE_FLAGS Flags;
|
||||||
} D3D12_RESOURCE_DESC;
|
} D3D12_RESOURCE_DESC;
|
||||||
|
|
||||||
typedef struct D3D12_MIP_REGION
|
|
||||||
{
|
|
||||||
UINT Width;
|
|
||||||
UINT Height;
|
|
||||||
UINT Depth;
|
|
||||||
} D3D12_MIP_REGION;
|
|
||||||
|
|
||||||
typedef struct D3D12_RESOURCE_DESC1
|
|
||||||
{
|
|
||||||
D3D12_RESOURCE_DIMENSION Dimension;
|
|
||||||
UINT64 Alignment;
|
|
||||||
UINT64 Width;
|
|
||||||
UINT Height;
|
|
||||||
UINT16 DepthOrArraySize;
|
|
||||||
UINT16 MipLevels;
|
|
||||||
DXGI_FORMAT Format;
|
|
||||||
DXGI_SAMPLE_DESC SampleDesc;
|
|
||||||
D3D12_TEXTURE_LAYOUT Layout;
|
|
||||||
D3D12_RESOURCE_FLAGS Flags;
|
|
||||||
D3D12_MIP_REGION SamplerFeedbackMipRegion;
|
|
||||||
} D3D12_RESOURCE_DESC1;
|
|
||||||
|
|
||||||
typedef enum D3D12_RESOLVE_MODE
|
typedef enum D3D12_RESOLVE_MODE
|
||||||
{
|
{
|
||||||
D3D12_RESOLVE_MODE_DECOMPRESS = 0,
|
D3D12_RESOLVE_MODE_DECOMPRESS = 0,
|
||||||
D3D12_RESOLVE_MODE_MIN = 1,
|
D3D12_RESOLVE_MODE_MIN = 1,
|
||||||
D3D12_RESOLVE_MODE_MAX = 2,
|
D3D12_RESOLVE_MODE_MAX = 2,
|
||||||
D3D12_RESOLVE_MODE_AVERAGE = 3,
|
D3D12_RESOLVE_MODE_AVERAGE = 3,
|
||||||
D3D12_RESOLVE_MODE_ENCODE_SAMPLER_FEEDBACK = 4,
|
|
||||||
D3D12_RESOLVE_MODE_DECODE_SAMPLER_FEEDBACK = 5,
|
|
||||||
} D3D12_RESOLVE_MODE;
|
} D3D12_RESOLVE_MODE;
|
||||||
|
|
||||||
typedef struct D3D12_SAMPLE_POSITION
|
typedef struct D3D12_SAMPLE_POSITION
|
||||||
|
@ -821,7 +723,6 @@ typedef enum D3D12_VIEW_INSTANCING_FLAGS
|
||||||
D3D12_VIEW_INSTANCING_FLAG_NONE = 0,
|
D3D12_VIEW_INSTANCING_FLAG_NONE = 0,
|
||||||
D3D12_VIEW_INSTANCING_FLAG_ENABLE_VIEW_INSTANCE_MASKING = 0x1,
|
D3D12_VIEW_INSTANCING_FLAG_ENABLE_VIEW_INSTANCE_MASKING = 0x1,
|
||||||
} D3D12_VIEW_INSTANCING_FLAGS;
|
} D3D12_VIEW_INSTANCING_FLAGS;
|
||||||
cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_VIEW_INSTANCING_FLAGS);")
|
|
||||||
|
|
||||||
typedef struct D3D12_VIEW_INSTANCE_LOCATION
|
typedef struct D3D12_VIEW_INSTANCE_LOCATION
|
||||||
{
|
{
|
||||||
|
@ -894,7 +795,6 @@ typedef enum D3D12_DESCRIPTOR_RANGE_FLAGS
|
||||||
D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC = 0x8,
|
D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC = 0x8,
|
||||||
D3D12_DESCRIPTOR_RANGE_FLAG_DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS = 0x10000,
|
D3D12_DESCRIPTOR_RANGE_FLAG_DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS = 0x10000,
|
||||||
} D3D12_DESCRIPTOR_RANGE_FLAGS;
|
} D3D12_DESCRIPTOR_RANGE_FLAGS;
|
||||||
cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_DESCRIPTOR_RANGE_FLAGS);")
|
|
||||||
|
|
||||||
typedef struct D3D12_DESCRIPTOR_RANGE1
|
typedef struct D3D12_DESCRIPTOR_RANGE1
|
||||||
{
|
{
|
||||||
|
@ -938,7 +838,6 @@ typedef enum D3D12_ROOT_DESCRIPTOR_FLAGS
|
||||||
D3D12_ROOT_DESCRIPTOR_FLAG_DATA_STATIC_WHILE_SET_AT_EXECUTE = 0x4,
|
D3D12_ROOT_DESCRIPTOR_FLAG_DATA_STATIC_WHILE_SET_AT_EXECUTE = 0x4,
|
||||||
D3D12_ROOT_DESCRIPTOR_FLAG_DATA_STATIC = 0x8,
|
D3D12_ROOT_DESCRIPTOR_FLAG_DATA_STATIC = 0x8,
|
||||||
} D3D12_ROOT_DESCRIPTOR_FLAGS;
|
} D3D12_ROOT_DESCRIPTOR_FLAGS;
|
||||||
cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_ROOT_DESCRIPTOR_FLAGS);")
|
|
||||||
|
|
||||||
typedef struct D3D12_ROOT_DESCRIPTOR1
|
typedef struct D3D12_ROOT_DESCRIPTOR1
|
||||||
{
|
{
|
||||||
|
@ -964,8 +863,6 @@ typedef enum D3D12_SHADER_VISIBILITY
|
||||||
D3D12_SHADER_VISIBILITY_DOMAIN = 3,
|
D3D12_SHADER_VISIBILITY_DOMAIN = 3,
|
||||||
D3D12_SHADER_VISIBILITY_GEOMETRY = 4,
|
D3D12_SHADER_VISIBILITY_GEOMETRY = 4,
|
||||||
D3D12_SHADER_VISIBILITY_PIXEL = 5,
|
D3D12_SHADER_VISIBILITY_PIXEL = 5,
|
||||||
D3D12_SHADER_VISIBILITY_AMPLIFICATION = 6,
|
|
||||||
D3D12_SHADER_VISIBILITY_MESH = 7,
|
|
||||||
} D3D12_SHADER_VISIBILITY;
|
} D3D12_SHADER_VISIBILITY;
|
||||||
|
|
||||||
typedef struct D3D12_ROOT_PARAMETER
|
typedef struct D3D12_ROOT_PARAMETER
|
||||||
|
@ -1134,12 +1031,7 @@ typedef enum D3D12_ROOT_SIGNATURE_FLAGS
|
||||||
D3D12_ROOT_SIGNATURE_FLAG_DENY_PIXEL_SHADER_ROOT_ACCESS = 0x20,
|
D3D12_ROOT_SIGNATURE_FLAG_DENY_PIXEL_SHADER_ROOT_ACCESS = 0x20,
|
||||||
D3D12_ROOT_SIGNATURE_FLAG_ALLOW_STREAM_OUTPUT = 0x40,
|
D3D12_ROOT_SIGNATURE_FLAG_ALLOW_STREAM_OUTPUT = 0x40,
|
||||||
D3D12_ROOT_SIGNATURE_FLAG_LOCAL_ROOT_SIGNATURE = 0x80,
|
D3D12_ROOT_SIGNATURE_FLAG_LOCAL_ROOT_SIGNATURE = 0x80,
|
||||||
D3D12_ROOT_SIGNATURE_FLAG_DENY_AMPLIFICATION_SHADER_ROOT_ACCESS = 0x100,
|
|
||||||
D3D12_ROOT_SIGNATURE_FLAG_DENY_MESH_SHADER_ROOT_ACCESS = 0x200,
|
|
||||||
D3D12_ROOT_SIGNATURE_FLAG_CBV_SRV_UAV_HEAP_DIRECTLY_INDEXED = 0x400,
|
|
||||||
D3D12_ROOT_SIGNATURE_FLAG_SAMPLER_HEAP_DIRECTLY_INDEXED = 0x800,
|
|
||||||
} D3D12_ROOT_SIGNATURE_FLAGS;
|
} D3D12_ROOT_SIGNATURE_FLAGS;
|
||||||
cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_ROOT_SIGNATURE_FLAGS);")
|
|
||||||
|
|
||||||
typedef struct D3D12_ROOT_SIGNATURE_DESC
|
typedef struct D3D12_ROOT_SIGNATURE_DESC
|
||||||
{
|
{
|
||||||
|
@ -1190,7 +1082,6 @@ typedef enum D3D12_DESCRIPTOR_HEAP_FLAGS
|
||||||
D3D12_DESCRIPTOR_HEAP_FLAG_NONE = 0x0,
|
D3D12_DESCRIPTOR_HEAP_FLAG_NONE = 0x0,
|
||||||
D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE = 0x1,
|
D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE = 0x1,
|
||||||
} D3D12_DESCRIPTOR_HEAP_FLAGS;
|
} D3D12_DESCRIPTOR_HEAP_FLAGS;
|
||||||
cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_DESCRIPTOR_HEAP_FLAGS);")
|
|
||||||
|
|
||||||
typedef struct D3D12_DESCRIPTOR_HEAP_DESC
|
typedef struct D3D12_DESCRIPTOR_HEAP_DESC
|
||||||
{
|
{
|
||||||
|
@ -1229,7 +1120,6 @@ typedef enum D3D12_BUFFER_SRV_FLAGS
|
||||||
D3D12_BUFFER_SRV_FLAG_NONE = 0x0,
|
D3D12_BUFFER_SRV_FLAG_NONE = 0x0,
|
||||||
D3D12_BUFFER_SRV_FLAG_RAW = 0x1,
|
D3D12_BUFFER_SRV_FLAG_RAW = 0x1,
|
||||||
} D3D12_BUFFER_SRV_FLAGS;
|
} D3D12_BUFFER_SRV_FLAGS;
|
||||||
cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_BUFFER_SRV_FLAGS);")
|
|
||||||
|
|
||||||
typedef enum D3D12_SHADER_COMPONENT_MAPPING
|
typedef enum D3D12_SHADER_COMPONENT_MAPPING
|
||||||
{
|
{
|
||||||
|
@ -1371,7 +1261,6 @@ typedef enum D3D12_BUFFER_UAV_FLAGS
|
||||||
D3D12_BUFFER_UAV_FLAG_NONE = 0x0,
|
D3D12_BUFFER_UAV_FLAG_NONE = 0x0,
|
||||||
D3D12_BUFFER_UAV_FLAG_RAW = 0x1,
|
D3D12_BUFFER_UAV_FLAG_RAW = 0x1,
|
||||||
} D3D12_BUFFER_UAV_FLAGS;
|
} D3D12_BUFFER_UAV_FLAGS;
|
||||||
cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_BUFFER_UAV_FLAGS);")
|
|
||||||
|
|
||||||
typedef struct D3D12_BUFFER_UAV
|
typedef struct D3D12_BUFFER_UAV
|
||||||
{
|
{
|
||||||
|
@ -1842,7 +1731,6 @@ typedef enum D3D12_PIPELINE_STATE_FLAGS
|
||||||
D3D12_PIPELINE_STATE_FLAG_NONE = 0x0,
|
D3D12_PIPELINE_STATE_FLAG_NONE = 0x0,
|
||||||
D3D12_PIPELINE_STATE_FLAG_DEBUG = 0x1,
|
D3D12_PIPELINE_STATE_FLAG_DEBUG = 0x1,
|
||||||
} D3D12_PIPELINE_STATE_FLAGS;
|
} D3D12_PIPELINE_STATE_FLAGS;
|
||||||
cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_PIPELINE_STATE_FLAGS);")
|
|
||||||
|
|
||||||
typedef struct D3D12_GRAPHICS_PIPELINE_STATE_DESC
|
typedef struct D3D12_GRAPHICS_PIPELINE_STATE_DESC
|
||||||
{
|
{
|
||||||
|
@ -1891,8 +1779,7 @@ typedef enum D3D12_COMMAND_LIST_TYPE
|
||||||
D3D12_COMMAND_LIST_TYPE_COMPUTE = 2,
|
D3D12_COMMAND_LIST_TYPE_COMPUTE = 2,
|
||||||
D3D12_COMMAND_LIST_TYPE_COPY = 3,
|
D3D12_COMMAND_LIST_TYPE_COPY = 3,
|
||||||
D3D12_COMMAND_LIST_TYPE_VIDEO_DECODE = 4,
|
D3D12_COMMAND_LIST_TYPE_VIDEO_DECODE = 4,
|
||||||
D3D12_COMMAND_LIST_TYPE_VIDEO_PROCESS = 5,
|
D3D12_COMMAND_LIST_TYPE_VIDEO_PROVESS = 5,
|
||||||
D3D12_COMMAND_LIST_TYPE_VIDEO_ENCODE = 6,
|
|
||||||
} D3D12_COMMAND_LIST_TYPE;
|
} D3D12_COMMAND_LIST_TYPE;
|
||||||
|
|
||||||
typedef enum D3D12_COMMAND_QUEUE_PRIORITY
|
typedef enum D3D12_COMMAND_QUEUE_PRIORITY
|
||||||
|
@ -1907,7 +1794,6 @@ typedef enum D3D12_COMMAND_QUEUE_FLAGS
|
||||||
D3D12_COMMAND_QUEUE_FLAG_NONE = 0x0,
|
D3D12_COMMAND_QUEUE_FLAG_NONE = 0x0,
|
||||||
D3D12_COMMAND_QUEUE_FLAG_DISABLE_GPU_TIMEOUT = 0x1,
|
D3D12_COMMAND_QUEUE_FLAG_DISABLE_GPU_TIMEOUT = 0x1,
|
||||||
} D3D12_COMMAND_QUEUE_FLAGS;
|
} D3D12_COMMAND_QUEUE_FLAGS;
|
||||||
cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_COMMAND_QUEUE_FLAGS);")
|
|
||||||
|
|
||||||
typedef enum D3D12_SHADER_CACHE_SUPPORT_FLAGS
|
typedef enum D3D12_SHADER_CACHE_SUPPORT_FLAGS
|
||||||
{
|
{
|
||||||
|
@ -1917,7 +1803,6 @@ typedef enum D3D12_SHADER_CACHE_SUPPORT_FLAGS
|
||||||
D3D12_SHADER_CACHE_SUPPORT_AUTOMATIC_INPROC_CACHE = 0x4,
|
D3D12_SHADER_CACHE_SUPPORT_AUTOMATIC_INPROC_CACHE = 0x4,
|
||||||
D3D12_SHADER_CACHE_SUPPORT_AUTOMATIC_DISK_CACHE = 0x8,
|
D3D12_SHADER_CACHE_SUPPORT_AUTOMATIC_DISK_CACHE = 0x8,
|
||||||
} D3D12_SHADER_CACHE_SUPPORT_FLAGS;
|
} D3D12_SHADER_CACHE_SUPPORT_FLAGS;
|
||||||
cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_SHADER_CACHE_SUPPORT_FLAGS);")
|
|
||||||
|
|
||||||
typedef struct D3D12_COMMAND_QUEUE_DESC
|
typedef struct D3D12_COMMAND_QUEUE_DESC
|
||||||
{
|
{
|
||||||
|
@ -1988,8 +1873,6 @@ typedef enum D3D_SHADER_MODEL
|
||||||
D3D_SHADER_MODEL_6_2 = 0x62,
|
D3D_SHADER_MODEL_6_2 = 0x62,
|
||||||
D3D_SHADER_MODEL_6_3 = 0x63,
|
D3D_SHADER_MODEL_6_3 = 0x63,
|
||||||
D3D_SHADER_MODEL_6_4 = 0x64,
|
D3D_SHADER_MODEL_6_4 = 0x64,
|
||||||
D3D_SHADER_MODEL_6_5 = 0x65,
|
|
||||||
D3D_SHADER_MODEL_6_6 = 0x66,
|
|
||||||
} D3D_SHADER_MODEL;
|
} D3D_SHADER_MODEL;
|
||||||
|
|
||||||
typedef struct D3D12_FEATURE_DATA_SHADER_MODEL
|
typedef struct D3D12_FEATURE_DATA_SHADER_MODEL
|
||||||
|
@ -2022,13 +1905,6 @@ typedef enum D3D12_FEATURE
|
||||||
D3D12_FEATURE_D3D12_OPTIONS5 = 27,
|
D3D12_FEATURE_D3D12_OPTIONS5 = 27,
|
||||||
D3D12_FEATURE_D3D12_OPTIONS6 = 30,
|
D3D12_FEATURE_D3D12_OPTIONS6 = 30,
|
||||||
D3D12_FEATURE_QUERY_META_COMMAND = 31,
|
D3D12_FEATURE_QUERY_META_COMMAND = 31,
|
||||||
D3D12_FEATURE_D3D12_OPTIONS7 = 32,
|
|
||||||
D3D12_FEATURE_PROTECTED_RESOURCE_SESSION_TYPE_COUNT = 33,
|
|
||||||
D3D12_FEATURE_PROTECTED_RESOURCE_SESSION_TYPES = 34,
|
|
||||||
D3D12_FEATURE_D3D12_OPTIONS8 = 36,
|
|
||||||
D3D12_FEATURE_D3D12_OPTIONS9 = 37,
|
|
||||||
D3D12_FEATURE_D3D12_OPTIONS10 = 39,
|
|
||||||
D3D12_FEATURE_D3D12_OPTIONS11 = 40,
|
|
||||||
} D3D12_FEATURE;
|
} D3D12_FEATURE;
|
||||||
|
|
||||||
typedef struct D3D12_MEMCPY_DEST
|
typedef struct D3D12_MEMCPY_DEST
|
||||||
|
@ -2158,15 +2034,6 @@ interface ID3D12Resource1 : ID3D12Resource
|
||||||
{
|
{
|
||||||
HRESULT GetProtectedResourceSession(REFIID riid, void **protected_session);
|
HRESULT GetProtectedResourceSession(REFIID riid, void **protected_session);
|
||||||
}
|
}
|
||||||
[
|
|
||||||
uuid(be36ec3b-ea85-4aeb-a45a-e9d76404a495),
|
|
||||||
object,
|
|
||||||
local,
|
|
||||||
pointer_default(unique)
|
|
||||||
]
|
|
||||||
interface ID3D12Resource2 : ID3D12Resource1 {
|
|
||||||
D3D12_RESOURCE_DESC1 GetDesc1();
|
|
||||||
}
|
|
||||||
|
|
||||||
[
|
[
|
||||||
uuid(7116d91c-e7e4-47ce-b8c6-ec8168f437e5),
|
uuid(7116d91c-e7e4-47ce-b8c6-ec8168f437e5),
|
||||||
|
@ -2186,7 +2053,6 @@ typedef enum D3D12_TILE_COPY_FLAGS
|
||||||
D3D12_TILE_COPY_FLAG_LINEAR_BUFFER_TO_SWIZZLED_TILED_RESOURCE = 0x2,
|
D3D12_TILE_COPY_FLAG_LINEAR_BUFFER_TO_SWIZZLED_TILED_RESOURCE = 0x2,
|
||||||
D3D12_TILE_COPY_FLAG_SWIZZLED_TILED_RESOURCE_TO_LINEAR_BUFFER = 0x4,
|
D3D12_TILE_COPY_FLAG_SWIZZLED_TILED_RESOURCE_TO_LINEAR_BUFFER = 0x4,
|
||||||
} D3D12_TILE_COPY_FLAGS;
|
} D3D12_TILE_COPY_FLAGS;
|
||||||
cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_TILE_COPY_FLAGS);")
|
|
||||||
|
|
||||||
typedef struct D3D12_INDEX_BUFFER_VIEW
|
typedef struct D3D12_INDEX_BUFFER_VIEW
|
||||||
{
|
{
|
||||||
|
@ -2303,13 +2169,11 @@ typedef enum D3D12_PROTECTED_RESOURCE_SESSION_SUPPORT_FLAGS
|
||||||
D3D12_PROTECTED_RESOURCE_SESSION_SUPPORT_FLAG_NONE = 0,
|
D3D12_PROTECTED_RESOURCE_SESSION_SUPPORT_FLAG_NONE = 0,
|
||||||
D3D12_PROTECTED_RESOURCE_SESSION_SUPPORT_FLAG_SUPPORTED = 0x1,
|
D3D12_PROTECTED_RESOURCE_SESSION_SUPPORT_FLAG_SUPPORTED = 0x1,
|
||||||
} D3D12_PROTECTED_RESOURCE_SESSION_SUPPORT_FLAGS;
|
} D3D12_PROTECTED_RESOURCE_SESSION_SUPPORT_FLAGS;
|
||||||
cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_PROTECTED_RESOURCE_SESSION_SUPPORT_FLAGS);")
|
|
||||||
|
|
||||||
typedef enum D3D12_PROTECTED_RESOURCE_SESSION_FLAGS
|
typedef enum D3D12_PROTECTED_RESOURCE_SESSION_FLAGS
|
||||||
{
|
{
|
||||||
D3D12_PROTECTED_RESOURCE_SESSION_FLAG_NONE = 0,
|
D3D12_PROTECTED_RESOURCE_SESSION_FLAG_NONE = 0,
|
||||||
} D3D12_PROTECTED_RESOURCE_SESSION_FLAGS;
|
} D3D12_PROTECTED_RESOURCE_SESSION_FLAGS;
|
||||||
cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_PROTECTED_RESOURCE_SESSION_FLAGS);")
|
|
||||||
|
|
||||||
typedef enum D3D12_PROTECTED_SESSION_STATUS
|
typedef enum D3D12_PROTECTED_SESSION_STATUS
|
||||||
{
|
{
|
||||||
|
@ -2353,37 +2217,6 @@ interface ID3D12ProtectedResourceSession : ID3D12ProtectedSession
|
||||||
D3D12_PROTECTED_RESOURCE_SESSION_DESC GetDesc();
|
D3D12_PROTECTED_RESOURCE_SESSION_DESC GetDesc();
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct D3D12_FEATURE_DATA_PROTECTED_RESOURCE_SESSION_TYPE_COUNT
|
|
||||||
{
|
|
||||||
UINT NodeIndex;
|
|
||||||
UINT Count;
|
|
||||||
} D3D12_FEATURE_DATA_PROTECTED_RESOURCE_SESSION_TYPE_COUNT;
|
|
||||||
|
|
||||||
typedef struct D3D12_FEATURE_DATA_PROTECTED_RESOURCE_SESSION_TYPES
|
|
||||||
{
|
|
||||||
UINT NodeIndex;
|
|
||||||
UINT Count;
|
|
||||||
GUID *pTypes;
|
|
||||||
} D3D12_FEATURE_DATA_PROTECTED_RESOURCE_SESSION_TYPES;
|
|
||||||
|
|
||||||
typedef struct D3D12_PROTECTED_RESOURCE_SESSION_DESC1
|
|
||||||
{
|
|
||||||
UINT NodeMask;
|
|
||||||
D3D12_PROTECTED_RESOURCE_SESSION_FLAGS Flags;
|
|
||||||
GUID ProtectionType;
|
|
||||||
} D3D12_PROTECTED_RESOURCE_SESSION_DESC1;
|
|
||||||
|
|
||||||
[
|
|
||||||
uuid(D6F12DD6-76FB-406E-8961-4296EEFC0409),
|
|
||||||
object,
|
|
||||||
local,
|
|
||||||
pointer_default(unique)
|
|
||||||
]
|
|
||||||
interface ID3D12ProtectedResourceSession1 : ID3D12ProtectedResourceSession
|
|
||||||
{
|
|
||||||
D3D12_PROTECTED_RESOURCE_SESSION_DESC1 GetDesc1();
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef enum D3D12_PIPELINE_STATE_SUBOBJECT_TYPE
|
typedef enum D3D12_PIPELINE_STATE_SUBOBJECT_TYPE
|
||||||
{
|
{
|
||||||
D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_ROOT_SIGNATURE = 0,
|
D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_ROOT_SIGNATURE = 0,
|
||||||
|
@ -2409,9 +2242,7 @@ typedef enum D3D12_PIPELINE_STATE_SUBOBJECT_TYPE
|
||||||
D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_FLAGS = 20,
|
D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_FLAGS = 20,
|
||||||
D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL1 = 21,
|
D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL1 = 21,
|
||||||
D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_VIEW_INSTANCING = 22,
|
D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_VIEW_INSTANCING = 22,
|
||||||
D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_AS = 24,
|
D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_MAX_VALID = 23,
|
||||||
D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_MS = 25,
|
|
||||||
D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_MAX_VALID = 26,
|
|
||||||
} D3D12_PIPELINE_STATE_SUBOBJECT_TYPE;
|
} D3D12_PIPELINE_STATE_SUBOBJECT_TYPE;
|
||||||
|
|
||||||
typedef struct D3D12_PIPELINE_STATE_STREAM_DESC
|
typedef struct D3D12_PIPELINE_STATE_STREAM_DESC
|
||||||
|
@ -2480,7 +2311,6 @@ typedef enum D3D12_META_COMMAND_PARAMETER_FLAGS
|
||||||
D3D12_META_COMMAND_PARAMETER_FLAG_INPUT = 0x1,
|
D3D12_META_COMMAND_PARAMETER_FLAG_INPUT = 0x1,
|
||||||
D3D12_META_COMMAND_PARAMETER_FLAG_OUTPUT = 0x2,
|
D3D12_META_COMMAND_PARAMETER_FLAG_OUTPUT = 0x2,
|
||||||
} D3D12_META_COMMAND_PARAMETER_FLAGS;
|
} D3D12_META_COMMAND_PARAMETER_FLAGS;
|
||||||
cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_META_COMMAND_PARAMETER_FLAGS);")
|
|
||||||
|
|
||||||
typedef enum D3D12_META_COMMAND_PARAMETER_STAGE
|
typedef enum D3D12_META_COMMAND_PARAMETER_STAGE
|
||||||
{
|
{
|
||||||
|
@ -2519,7 +2349,6 @@ typedef enum D3D12_GRAPHICS_STATES
|
||||||
D3D12_GRAPHICS_STATE_SAMPLE_POSITIONS = 0x8000,
|
D3D12_GRAPHICS_STATE_SAMPLE_POSITIONS = 0x8000,
|
||||||
D3D12_GRAPHICS_STATE_VIEW_INSTANCE_MASK = 0x10000,
|
D3D12_GRAPHICS_STATE_VIEW_INSTANCE_MASK = 0x10000,
|
||||||
} D3D12_GRAPHICS_STATES;
|
} D3D12_GRAPHICS_STATES;
|
||||||
cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_GRAPHICS_STATES);")
|
|
||||||
|
|
||||||
typedef struct D3D12_META_COMMAND_DESC
|
typedef struct D3D12_META_COMMAND_DESC
|
||||||
{
|
{
|
||||||
|
@ -2570,8 +2399,6 @@ typedef enum D3D12_STATE_SUBOBJECT_TYPE
|
||||||
D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_SHADER_CONFIG = 9,
|
D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_SHADER_CONFIG = 9,
|
||||||
D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_PIPELINE_CONFIG = 10,
|
D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_PIPELINE_CONFIG = 10,
|
||||||
D3D12_STATE_SUBOBJECT_TYPE_HIT_GROUP = 11,
|
D3D12_STATE_SUBOBJECT_TYPE_HIT_GROUP = 11,
|
||||||
D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_PIPELINE_CONFIG1 = 12,
|
|
||||||
D3D12_STATE_SUBOBJECT_TYPE_MAX_VALID = 13,
|
|
||||||
} D3D12_STATE_SUBOBJECT_TYPE;
|
} D3D12_STATE_SUBOBJECT_TYPE;
|
||||||
|
|
||||||
typedef struct D3D12_STATE_SUBOBJECT
|
typedef struct D3D12_STATE_SUBOBJECT
|
||||||
|
@ -2585,9 +2412,7 @@ typedef enum D3D12_STATE_OBJECT_FLAGS
|
||||||
D3D12_STATE_OBJECT_FLAG_NONE = 0,
|
D3D12_STATE_OBJECT_FLAG_NONE = 0,
|
||||||
D3D12_STATE_OBJECT_FLAG_ALLOW_LOCAL_DEPENDENCIES_ON_EXTERNAL_DEFINITIONS = 0x1,
|
D3D12_STATE_OBJECT_FLAG_ALLOW_LOCAL_DEPENDENCIES_ON_EXTERNAL_DEFINITIONS = 0x1,
|
||||||
D3D12_STATE_OBJECT_FLAG_ALLOW_EXTERNAL_DEPENDENCIES_ON_LOCAL_DEFINITIONS = 0x2,
|
D3D12_STATE_OBJECT_FLAG_ALLOW_EXTERNAL_DEPENDENCIES_ON_LOCAL_DEFINITIONS = 0x2,
|
||||||
D3D12_STATE_OBJECT_FLAG_ALLOW_STATE_OBJECT_ADDITIONS = 0x4,
|
|
||||||
} D3D12_STATE_OBJECT_FLAGS;
|
} D3D12_STATE_OBJECT_FLAGS;
|
||||||
cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_STATE_OBJECT_FLAGS);")
|
|
||||||
|
|
||||||
typedef struct D3D12_STATE_OBJECT_CONFIG
|
typedef struct D3D12_STATE_OBJECT_CONFIG
|
||||||
{
|
{
|
||||||
|
@ -2613,7 +2438,6 @@ typedef enum D3D12_EXPORT_FLAGS
|
||||||
{
|
{
|
||||||
D3D12_EXPORT_FLAG_NONE = 0,
|
D3D12_EXPORT_FLAG_NONE = 0,
|
||||||
} D3D12_EXPORT_FLAGS;
|
} D3D12_EXPORT_FLAGS;
|
||||||
cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_EXPORT_FLAGS);")
|
|
||||||
|
|
||||||
typedef struct D3D12_EXPORT_DESC
|
typedef struct D3D12_EXPORT_DESC
|
||||||
{
|
{
|
||||||
|
@ -2643,13 +2467,6 @@ typedef struct D3D12_SUBOBJECT_TO_EXPORTS_ASSOCIATION
|
||||||
LPCWSTR *pExports;
|
LPCWSTR *pExports;
|
||||||
} D3D12_SUBOBJECT_TO_EXPORTS_ASSOCIATION;
|
} D3D12_SUBOBJECT_TO_EXPORTS_ASSOCIATION;
|
||||||
|
|
||||||
typedef struct D3D12_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION
|
|
||||||
{
|
|
||||||
LPCWSTR SubobjectToAssociate;
|
|
||||||
UINT NumExports;
|
|
||||||
LPCWSTR *pExports;
|
|
||||||
} D3D12_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION;
|
|
||||||
|
|
||||||
typedef enum D3D12_HIT_GROUP_TYPE
|
typedef enum D3D12_HIT_GROUP_TYPE
|
||||||
{
|
{
|
||||||
D3D12_HIT_GROUP_TYPE_TRIANGLES = 0,
|
D3D12_HIT_GROUP_TYPE_TRIANGLES = 0,
|
||||||
|
@ -2671,20 +2488,6 @@ typedef struct D3D12_RAYTRACING_SHADER_CONFIG
|
||||||
UINT MaxAttributeSizeInBytes;
|
UINT MaxAttributeSizeInBytes;
|
||||||
} D3D12_RAYTRACING_SHADER_CONFIG;
|
} D3D12_RAYTRACING_SHADER_CONFIG;
|
||||||
|
|
||||||
typedef enum D3D12_RAYTRACING_PIPELINE_FLAGS
|
|
||||||
{
|
|
||||||
D3D12_RAYTRACING_PIPELINE_FLAG_NONE = 0x0,
|
|
||||||
D3D12_RAYTRACING_PIPELINE_FLAG_SKIP_TRIANGLES = 0x100,
|
|
||||||
D3D12_RAYTRACING_PIPELINE_FLAG_SKIP_PROCEDURAL_PRIMITIVES = 0x200,
|
|
||||||
} D3D12_RAYTRACING_PIPELINE_FLAGS;
|
|
||||||
cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_RAYTRACING_PIPELINE_FLAGS);")
|
|
||||||
|
|
||||||
typedef struct D3D12_RAYTRACING_PIPELINE_CONFIG1
|
|
||||||
{
|
|
||||||
UINT MaxTraceRecursionDepth;
|
|
||||||
D3D12_RAYTRACING_PIPELINE_FLAGS Flags;
|
|
||||||
} D3D12_RAYTRACING_PIPELINE_CONFIG1;
|
|
||||||
|
|
||||||
typedef struct D3D12_RAYTRACING_PIPELINE_CONFIG
|
typedef struct D3D12_RAYTRACING_PIPELINE_CONFIG
|
||||||
{
|
{
|
||||||
UINT MaxTraceRecursionDepth;
|
UINT MaxTraceRecursionDepth;
|
||||||
|
@ -2709,7 +2512,6 @@ typedef enum D3D12_RAYTRACING_GEOMETRY_FLAGS
|
||||||
D3D12_RAYTRACING_GEOMETRY_FLAG_OPAQUE = 0x1,
|
D3D12_RAYTRACING_GEOMETRY_FLAG_OPAQUE = 0x1,
|
||||||
D3D12_RAYTRACING_GEOMETRY_FLAG_NO_DUPLICATE_ANYHIT_INVOCATION = 0x2,
|
D3D12_RAYTRACING_GEOMETRY_FLAG_NO_DUPLICATE_ANYHIT_INVOCATION = 0x2,
|
||||||
} D3D12_RAYTRACING_GEOMETRY_FLAGS;
|
} D3D12_RAYTRACING_GEOMETRY_FLAGS;
|
||||||
cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_RAYTRACING_GEOMETRY_FLAGS);")
|
|
||||||
|
|
||||||
typedef enum D3D12_RAYTRACING_GEOMETRY_TYPE
|
typedef enum D3D12_RAYTRACING_GEOMETRY_TYPE
|
||||||
{
|
{
|
||||||
|
@ -2725,7 +2527,6 @@ typedef enum D3D12_RAYTRACING_INSTANCE_FLAGS
|
||||||
D3D12_RAYTRACING_INSTANCE_FLAG_FORCE_OPAQUE = 0x4,
|
D3D12_RAYTRACING_INSTANCE_FLAG_FORCE_OPAQUE = 0x4,
|
||||||
D3D12_RAYTRACING_INSTANCE_FLAG_FORCE_NON_OPAQUE = 0x8,
|
D3D12_RAYTRACING_INSTANCE_FLAG_FORCE_NON_OPAQUE = 0x8,
|
||||||
} D3D12_RAYTRACING_INSTANCE_FLAGS;
|
} D3D12_RAYTRACING_INSTANCE_FLAGS;
|
||||||
cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_RAYTRACING_INSTANCE_FLAGS);")
|
|
||||||
|
|
||||||
typedef struct D3D12_GPU_VIRTUAL_ADDRESS_AND_STRIDE
|
typedef struct D3D12_GPU_VIRTUAL_ADDRESS_AND_STRIDE
|
||||||
{
|
{
|
||||||
|
@ -2783,7 +2584,6 @@ typedef enum D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS
|
||||||
D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_MINIMIZE_MEMORY = 0x10,
|
D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_MINIMIZE_MEMORY = 0x10,
|
||||||
D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_PERFORM_UPDATE = 0x20,
|
D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_PERFORM_UPDATE = 0x20,
|
||||||
} D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS;
|
} D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS;
|
||||||
cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS);")
|
|
||||||
|
|
||||||
typedef enum D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE
|
typedef enum D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE
|
||||||
{
|
{
|
||||||
|
@ -2936,10 +2736,7 @@ typedef enum D3D12_RAY_FLAGS
|
||||||
D3D12_RAY_FLAG_CULL_FRONT_FACING_TRIANGLES = 0x20,
|
D3D12_RAY_FLAG_CULL_FRONT_FACING_TRIANGLES = 0x20,
|
||||||
D3D12_RAY_FLAG_CULL_OPAQUE = 0x40,
|
D3D12_RAY_FLAG_CULL_OPAQUE = 0x40,
|
||||||
D3D12_RAY_FLAG_CULL_NON_OPAQUE = 0x80,
|
D3D12_RAY_FLAG_CULL_NON_OPAQUE = 0x80,
|
||||||
D3D12_RAY_FLAG_SKIP_TRIANGLES = 0x100,
|
|
||||||
D3D12_RAY_FLAG_SKIP_PROCEDURAL_PRIMITIVES = 0x200,
|
|
||||||
} D3D12_RAY_FLAGS;
|
} D3D12_RAY_FLAGS;
|
||||||
cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_RAY_FLAGS);")
|
|
||||||
|
|
||||||
typedef enum D3D12_HIT_KIND
|
typedef enum D3D12_HIT_KIND
|
||||||
{
|
{
|
||||||
|
@ -2962,19 +2759,16 @@ typedef enum D3D12_COMMAND_LIST_FLAGS
|
||||||
{
|
{
|
||||||
D3D12_COMMAND_LIST_FLAG_NONE = 0,
|
D3D12_COMMAND_LIST_FLAG_NONE = 0,
|
||||||
} D3D12_COMMAND_LIST_FLAGS;
|
} D3D12_COMMAND_LIST_FLAGS;
|
||||||
cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_COMMAND_LIST_FLAGS);")
|
|
||||||
|
|
||||||
typedef enum D3D12_COMMAND_POOL_FLAGS
|
typedef enum D3D12_COMMAND_POOL_FLAGS
|
||||||
{
|
{
|
||||||
D3D12_COMMAND_POOL_FLAG_NONE = 0,
|
D3D12_COMMAND_POOL_FLAG_NONE = 0,
|
||||||
} D3D12_COMMAND_POOL_FLAGS;
|
} D3D12_COMMAND_POOL_FLAGS;
|
||||||
cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_COMMAND_POOL_FLAGS);")
|
|
||||||
|
|
||||||
typedef enum D3D12_COMMAND_RECORDER_FLAGS
|
typedef enum D3D12_COMMAND_RECORDER_FLAGS
|
||||||
{
|
{
|
||||||
D3D12_COMMAND_RECORDER_FLAG_NONE = 0,
|
D3D12_COMMAND_RECORDER_FLAG_NONE = 0,
|
||||||
} D3D12_COMMAND_RECORDER_FLAGS;
|
} D3D12_COMMAND_RECORDER_FLAGS;
|
||||||
cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_COMMAND_RECORDER_FLAGS);")
|
|
||||||
|
|
||||||
typedef enum D3D12_AUTO_BREADCRUMB_OP
|
typedef enum D3D12_AUTO_BREADCRUMB_OP
|
||||||
{
|
{
|
||||||
|
@ -3018,17 +2812,14 @@ typedef enum D3D12_AUTO_BREADCRUMB_OP
|
||||||
D3D12_AUTO_BREADCRUMB_OP_ESTIMATEMOTION = 37,
|
D3D12_AUTO_BREADCRUMB_OP_ESTIMATEMOTION = 37,
|
||||||
D3D12_AUTO_BREADCRUMB_OP_RESOLVEMOTIONVECTORHEAP = 38,
|
D3D12_AUTO_BREADCRUMB_OP_RESOLVEMOTIONVECTORHEAP = 38,
|
||||||
D3D12_AUTO_BREADCRUMB_OP_SETPIPELINESTATE1 = 39,
|
D3D12_AUTO_BREADCRUMB_OP_SETPIPELINESTATE1 = 39,
|
||||||
D3D12_AUTO_BREADCRUMB_OP_INITIALIZEEXTENSIONCOMMAND = 40,
|
|
||||||
D3D12_AUTO_BREADCRUMB_OP_EXECUTEEXTENSIONCOMMAND = 41,
|
|
||||||
D3D12_AUTO_BREADCRUMB_OP_DISPATCHMESH = 42,
|
|
||||||
} D3D12_AUTO_BREADCRUMB_OP;
|
} D3D12_AUTO_BREADCRUMB_OP;
|
||||||
|
|
||||||
typedef struct D3D12_AUTO_BREADCRUMB_NODE
|
typedef struct D3D12_AUTO_BREADCRUMB_NODE
|
||||||
{
|
{
|
||||||
const char *pCommandListDebugNameA;
|
const char *pCommandListDebugNameA;
|
||||||
const WCHAR *pCommandListDebugNameW;
|
const wchar_t *pCommandListDebugNameW;
|
||||||
const char *pCommandQueueDebugNameA;
|
const char *pCommandQueueDebugNameA;
|
||||||
const WCHAR *pCommandQueueDebugNameW;
|
const wchar_t *pCommandQueueDebugNameW;
|
||||||
ID3D12GraphicsCommandList *pCommandList;
|
ID3D12GraphicsCommandList *pCommandList;
|
||||||
ID3D12CommandQueue *pCommandQueue;
|
ID3D12CommandQueue *pCommandQueue;
|
||||||
UINT32 BreadcrumbCount;
|
UINT32 BreadcrumbCount;
|
||||||
|
@ -3037,33 +2828,9 @@ typedef struct D3D12_AUTO_BREADCRUMB_NODE
|
||||||
struct D3D12_AUTO_BREADCRUMB_NODE *pNext;
|
struct D3D12_AUTO_BREADCRUMB_NODE *pNext;
|
||||||
} D3D12_AUTO_BREADCRUMB_NODE;
|
} D3D12_AUTO_BREADCRUMB_NODE;
|
||||||
|
|
||||||
typedef struct D3D12_DRED_BREADCRUMB_CONTEXT
|
|
||||||
{
|
|
||||||
UINT BreadcrumbIndex;
|
|
||||||
const WCHAR *pContextString;
|
|
||||||
} D3D12_DRED_BREADCRUMB_CONTEXT;
|
|
||||||
|
|
||||||
typedef struct D3D12_AUTO_BREADCRUMB_NODE1
|
|
||||||
{
|
|
||||||
const char *pCommandListDebugNameA;
|
|
||||||
const WCHAR *pCommandListDebugNameW;
|
|
||||||
const char *pCommandQueueDebugNameA;
|
|
||||||
const WCHAR *pCommandQueueDebugNameW;
|
|
||||||
ID3D12GraphicsCommandList *pCommandList;
|
|
||||||
ID3D12CommandQueue *pCommandQueue;
|
|
||||||
UINT BreadcrumbCount;
|
|
||||||
const UINT *pLastBreadcrumbValue;
|
|
||||||
const D3D12_AUTO_BREADCRUMB_OP *pCommandHistory;
|
|
||||||
const struct D3D12_AUTO_BREADCRUMB_NODE1 *pNext;
|
|
||||||
UINT BreadcrumbContextsCount;
|
|
||||||
D3D12_DRED_BREADCRUMB_CONTEXT *pBreadcrumbContexts;
|
|
||||||
} D3D12_AUTO_BREADCRUMB_NODE1;
|
|
||||||
|
|
||||||
typedef enum D3D12_DRED_VERSION
|
typedef enum D3D12_DRED_VERSION
|
||||||
{
|
{
|
||||||
D3D12_DRED_VERSION_1_0 = 1,
|
D3D12_DRED_VERSION_1_0 = 1,
|
||||||
D3D12_DRED_VERSION_1_1 = 2,
|
|
||||||
D3D12_DRED_VERSION_1_2 = 3,
|
|
||||||
} D3D12_DRED_VERSION;
|
} D3D12_DRED_VERSION;
|
||||||
|
|
||||||
typedef enum D3D12_DRED_FLAGS
|
typedef enum D3D12_DRED_FLAGS
|
||||||
|
@ -3072,14 +2839,6 @@ typedef enum D3D12_DRED_FLAGS
|
||||||
D3D12_DRED_FLAG_FORCE_ENABLE = 0x1,
|
D3D12_DRED_FLAG_FORCE_ENABLE = 0x1,
|
||||||
D3D12_DRED_FLAG_AUTOBREADCRUMBS = 0x2,
|
D3D12_DRED_FLAG_AUTOBREADCRUMBS = 0x2,
|
||||||
} D3D12_DRED_FLAGS;
|
} D3D12_DRED_FLAGS;
|
||||||
cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_DRED_FLAGS);")
|
|
||||||
|
|
||||||
typedef enum D3D12_DRED_ENABLEMENT
|
|
||||||
{
|
|
||||||
D3D12_DRED_ENABLEMENT_SYSTEM_CONTROLLED = 0,
|
|
||||||
D3D12_DRED_ENABLEMENT_FORCED_OFF = 1,
|
|
||||||
D3D12_DRED_ENABLEMENT_FORCED_ON = 2,
|
|
||||||
} D3D12_DRED_ENABLEMENT;
|
|
||||||
|
|
||||||
typedef struct D3D12_DEVICE_REMOVED_EXTENDED_DATA
|
typedef struct D3D12_DEVICE_REMOVED_EXTENDED_DATA
|
||||||
{
|
{
|
||||||
|
@ -3087,92 +2846,6 @@ typedef struct D3D12_DEVICE_REMOVED_EXTENDED_DATA
|
||||||
D3D12_AUTO_BREADCRUMB_NODE *pHeadAutoBreadcrumbNode;
|
D3D12_AUTO_BREADCRUMB_NODE *pHeadAutoBreadcrumbNode;
|
||||||
} D3D12_DEVICE_REMOVED_EXTENDED_DATA;
|
} D3D12_DEVICE_REMOVED_EXTENDED_DATA;
|
||||||
|
|
||||||
typedef enum D3D12_DRED_ALLOCATION_TYPE
|
|
||||||
{
|
|
||||||
D3D12_DRED_ALLOCATION_TYPE_COMMAND_QUEUE = 19,
|
|
||||||
D3D12_DRED_ALLOCATION_TYPE_COMMAND_ALLOCATOR = 20,
|
|
||||||
D3D12_DRED_ALLOCATION_TYPE_PIPELINE_STATE = 21,
|
|
||||||
D3D12_DRED_ALLOCATION_TYPE_COMMAND_LIST = 22,
|
|
||||||
D3D12_DRED_ALLOCATION_TYPE_FENCE = 23,
|
|
||||||
D3D12_DRED_ALLOCATION_TYPE_DESCRIPTOR_HEAP = 24,
|
|
||||||
D3D12_DRED_ALLOCATION_TYPE_HEAP = 25,
|
|
||||||
D3D12_DRED_ALLOCATION_TYPE_QUERY_HEAP = 27,
|
|
||||||
D3D12_DRED_ALLOCATION_TYPE_COMMAND_SIGNATURE = 28,
|
|
||||||
D3D12_DRED_ALLOCATION_TYPE_PIPELINE_LIBRARY = 29,
|
|
||||||
D3D12_DRED_ALLOCATION_TYPE_VIDEO_DECODER = 30,
|
|
||||||
D3D12_DRED_ALLOCATION_TYPE_VIDEO_PROCESSOR = 32,
|
|
||||||
D3D12_DRED_ALLOCATION_TYPE_RESOURCE = 34,
|
|
||||||
D3D12_DRED_ALLOCATION_TYPE_PASS = 35,
|
|
||||||
D3D12_DRED_ALLOCATION_TYPE_CRYPTOSESSION = 36,
|
|
||||||
D3D12_DRED_ALLOCATION_TYPE_CRYPTOSESSIONPOLICY = 37,
|
|
||||||
D3D12_DRED_ALLOCATION_TYPE_PROTECTEDRESOURCESESSION = 38,
|
|
||||||
D3D12_DRED_ALLOCATION_TYPE_VIDEO_DECODER_HEAP = 39,
|
|
||||||
D3D12_DRED_ALLOCATION_TYPE_COMMAND_POOL = 40,
|
|
||||||
D3D12_DRED_ALLOCATION_TYPE_COMMAND_RECORDER = 41,
|
|
||||||
D3D12_DRED_ALLOCATION_TYPE_STATE_OBJECT = 42,
|
|
||||||
D3D12_DRED_ALLOCATION_TYPE_METACOMMAND = 43,
|
|
||||||
D3D12_DRED_ALLOCATION_TYPE_SCHEDULINGGROUP = 44,
|
|
||||||
D3D12_DRED_ALLOCATION_TYPE_VIDEO_MOTION_ESTIMATOR = 45,
|
|
||||||
D3D12_DRED_ALLOCATION_TYPE_VIDEO_MOTION_VECTOR_HEAP = 46,
|
|
||||||
D3D12_DRED_ALLOCATION_TYPE_VIDEO_EXTENSION_COMMAND = 47,
|
|
||||||
D3D12_DRED_ALLOCATION_TYPE_INVALID = 0xffffffff,
|
|
||||||
} D3D12_DRED_ALLOCATION_TYPE;
|
|
||||||
|
|
||||||
typedef struct D3D12_DRED_ALLOCATION_NODE
|
|
||||||
{
|
|
||||||
const char *ObjectNameA;
|
|
||||||
const WCHAR *ObjectNameW;
|
|
||||||
D3D12_DRED_ALLOCATION_TYPE AllocationType;
|
|
||||||
const struct D3D12_DRED_ALLOCATION_NODE *pNext;
|
|
||||||
} D3D12_DRED_ALLOCATION_NODE;
|
|
||||||
|
|
||||||
typedef struct D3D12_DRED_ALLOCATION_NODE1
|
|
||||||
{
|
|
||||||
const char *ObjectNameA;
|
|
||||||
const WCHAR *ObjectNameW;
|
|
||||||
D3D12_DRED_ALLOCATION_TYPE AllocationType;
|
|
||||||
const struct D3D12_DRED_ALLOCATION_NODE1 *pNext;
|
|
||||||
const IUnknown *pObject;
|
|
||||||
} D3D12_DRED_ALLOCATION_NODE1;
|
|
||||||
|
|
||||||
typedef struct D3D12_DRED_AUTO_BREADCRUMBS_OUTPUT
|
|
||||||
{
|
|
||||||
const D3D12_AUTO_BREADCRUMB_NODE *pHeadAutoBreadcrumbNode;
|
|
||||||
} D3D12_DRED_AUTO_BREADCRUMBS_OUTPUT;
|
|
||||||
|
|
||||||
typedef struct D3D12_DRED_AUTO_BREADCRUMBS_OUTPUT1
|
|
||||||
{
|
|
||||||
const D3D12_AUTO_BREADCRUMB_NODE1 *pHeadAutoBreadcrumbNode;
|
|
||||||
} D3D12_DRED_AUTO_BREADCRUMBS_OUTPUT1;
|
|
||||||
|
|
||||||
typedef struct D3D12_DRED_PAGE_FAULT_OUTPUT
|
|
||||||
{
|
|
||||||
D3D12_GPU_VIRTUAL_ADDRESS PageFaultVA;
|
|
||||||
const D3D12_DRED_ALLOCATION_NODE *pHeadExistingAllocationNode;
|
|
||||||
const D3D12_DRED_ALLOCATION_NODE *pHeadRecentFreedAllocationNode;
|
|
||||||
} D3D12_DRED_PAGE_FAULT_OUTPUT;
|
|
||||||
|
|
||||||
typedef struct D3D12_DRED_PAGE_FAULT_OUTPUT1
|
|
||||||
{
|
|
||||||
D3D12_GPU_VIRTUAL_ADDRESS PageFaultVA;
|
|
||||||
const D3D12_DRED_ALLOCATION_NODE1 *pHeadExistingAllocationNode;
|
|
||||||
const D3D12_DRED_ALLOCATION_NODE1 *pHeadRecentFreedAllocationNode;
|
|
||||||
} D3D12_DRED_PAGE_FAULT_OUTPUT1;
|
|
||||||
|
|
||||||
typedef struct D3D12_DEVICE_REMOVED_EXTENDED_DATA1
|
|
||||||
{
|
|
||||||
HRESULT DeviceRemovedReason;
|
|
||||||
D3D12_DRED_AUTO_BREADCRUMBS_OUTPUT AutoBreadcrumbsOutput;
|
|
||||||
D3D12_DRED_PAGE_FAULT_OUTPUT PageFaultOutput;
|
|
||||||
} D3D12_DEVICE_REMOVED_EXTENDED_DATA1;
|
|
||||||
|
|
||||||
typedef struct D3D12_DEVICE_REMOVED_EXTENDED_DATA2
|
|
||||||
{
|
|
||||||
HRESULT DeviceRemovedReason;
|
|
||||||
D3D12_DRED_AUTO_BREADCRUMBS_OUTPUT1 AutoBreadcrumbsOutput;
|
|
||||||
D3D12_DRED_PAGE_FAULT_OUTPUT1 PageFaultOutput;
|
|
||||||
} D3D12_DEVICE_REMOVED_EXTENDED_DATA2;
|
|
||||||
|
|
||||||
typedef struct D3D12_VERSIONED_DEVICE_REMOVED_EXTENDED_DATA
|
typedef struct D3D12_VERSIONED_DEVICE_REMOVED_EXTENDED_DATA
|
||||||
{
|
{
|
||||||
D3D12_DRED_VERSION Version;
|
D3D12_DRED_VERSION Version;
|
||||||
|
@ -3205,7 +2878,6 @@ typedef enum D3D12_RENDER_PASS_FLAGS
|
||||||
D3D12_RENDER_PASS_FLAG_SUSPENDING_PASS = 0x2,
|
D3D12_RENDER_PASS_FLAG_SUSPENDING_PASS = 0x2,
|
||||||
D3D12_RENDER_PASS_FLAG_RESUMING_PASS = 0x4,
|
D3D12_RENDER_PASS_FLAG_RESUMING_PASS = 0x4,
|
||||||
} D3D12_RENDER_PASS_FLAGS;
|
} D3D12_RENDER_PASS_FLAGS;
|
||||||
cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_RENDER_PASS_FLAGS);")
|
|
||||||
|
|
||||||
typedef enum D3D12_AXIS_SHADING_RATE
|
typedef enum D3D12_AXIS_SHADING_RATE
|
||||||
{
|
{
|
||||||
|
@ -3315,52 +2987,6 @@ typedef struct D3D12_RENDER_PASS_DEPTH_STENCIL_DESC
|
||||||
D3D12_RENDER_PASS_ENDING_ACCESS StencilEndingAccess;
|
D3D12_RENDER_PASS_ENDING_ACCESS StencilEndingAccess;
|
||||||
} D3D12_RENDER_PASS_DEPTH_STENCIL_DESC;
|
} D3D12_RENDER_PASS_DEPTH_STENCIL_DESC;
|
||||||
|
|
||||||
typedef struct D3D12_DISPATCH_MESH_ARGUMENTS
|
|
||||||
{
|
|
||||||
UINT ThreadGroupCountX;
|
|
||||||
UINT ThreadGroupCountY;
|
|
||||||
UINT ThreadGroupCountZ;
|
|
||||||
} D3D12_DISPATCH_MESH_ARGUMENTS;
|
|
||||||
|
|
||||||
typedef enum D3D12_SHADER_CACHE_MODE
|
|
||||||
{
|
|
||||||
D3D12_SHADER_CACHE_MODE_MEMORY = 0,
|
|
||||||
D3D12_SHADER_CACHE_MODE_DISK = 1,
|
|
||||||
} D3D12_SHADER_CACHE_MODE;
|
|
||||||
|
|
||||||
typedef enum D3D12_SHADER_CACHE_FLAGS
|
|
||||||
{
|
|
||||||
D3D12_SHADER_CACHE_FLAG_NONE = 0,
|
|
||||||
D3D12_SHADER_CACHE_FLAG_DRIVER_VERSIONED = 0x1,
|
|
||||||
D3D12_SHADER_CACHE_FLAG_USE_WORKING_DIR = 0x2,
|
|
||||||
} D3D12_SHADER_CACHE_FLAGS;
|
|
||||||
|
|
||||||
typedef struct D3D12_SHADER_CACHE_SESSION_DESC
|
|
||||||
{
|
|
||||||
GUID Identifier;
|
|
||||||
D3D12_SHADER_CACHE_MODE Mode;
|
|
||||||
D3D12_SHADER_CACHE_FLAGS Flags;
|
|
||||||
UINT MaximumInMemoryCacheSizeBytes;
|
|
||||||
UINT MaximumInMemoryCacheEntries;
|
|
||||||
UINT MaximumValueFileSizeBytes;
|
|
||||||
UINT64 Version;
|
|
||||||
} D3D12_SHADER_CACHE_SESSION_DESC;
|
|
||||||
|
|
||||||
typedef enum D3D12_SHADER_CACHE_KIND_FLAGS
|
|
||||||
{
|
|
||||||
D3D12_SHADER_CACHE_KIND_FLAG_IMPLICIT_D3D_CACHE_FOR_DRIVER = 0x1,
|
|
||||||
D3D12_SHADER_CACHE_KIND_FLAG_IMPLICIT_D3D_CONVERSIONS = 0x2,
|
|
||||||
D3D12_SHADER_CACHE_KIND_FLAG_IMPLICIT_DRIVER_MANAGED = 0x4,
|
|
||||||
D3D12_SHADER_CACHE_KIND_FLAG_APPLICATION_MANAGED = 0x8,
|
|
||||||
} D3D12_SHADER_CACHE_KIND_FLAGS;
|
|
||||||
|
|
||||||
typedef enum D3D12_SHADER_CACHE_CONTROL_FLAGS
|
|
||||||
{
|
|
||||||
D3D12_SHADER_CACHE_CONTROL_FLAG_DISABLE = 0x1,
|
|
||||||
D3D12_SHADER_CACHE_CONTROL_FLAG_ENABLE = 0x2,
|
|
||||||
D3D12_SHADER_CACHE_CONTROL_FLAG_CLEAR = 0x4,
|
|
||||||
} D3D12_SHADER_CACHE_CONTROL_FLAGS;
|
|
||||||
|
|
||||||
[
|
[
|
||||||
uuid(dbb84c27-36ce-4fc9-b801-f048c46ac570),
|
uuid(dbb84c27-36ce-4fc9-b801-f048c46ac570),
|
||||||
object,
|
object,
|
||||||
|
@ -3398,7 +3024,7 @@ interface ID3D12GraphicsCommandList : ID3D12CommandList
|
||||||
|
|
||||||
HRESULT Reset(ID3D12CommandAllocator *allocator, ID3D12PipelineState *initial_state);
|
HRESULT Reset(ID3D12CommandAllocator *allocator, ID3D12PipelineState *initial_state);
|
||||||
|
|
||||||
void ClearState(ID3D12PipelineState *pipeline_state);
|
HRESULT ClearState(ID3D12PipelineState *pipeline_state);
|
||||||
|
|
||||||
void DrawInstanced(UINT vertex_count_per_instance, UINT instance_count,
|
void DrawInstanced(UINT vertex_count_per_instance, UINT instance_count,
|
||||||
UINT start_vertex_location, UINT start_instance_location);
|
UINT start_vertex_location, UINT start_instance_location);
|
||||||
|
@ -3604,17 +3230,6 @@ interface ID3D12GraphicsCommandList5 : ID3D12GraphicsCommandList4
|
||||||
void RSSetShadingRateImage(ID3D12Resource *image);
|
void RSSetShadingRateImage(ID3D12Resource *image);
|
||||||
}
|
}
|
||||||
|
|
||||||
[
|
|
||||||
uuid(c3827890-e548-4cfa-96cf-5689a9370f80),
|
|
||||||
object,
|
|
||||||
local,
|
|
||||||
pointer_default(unique)
|
|
||||||
]
|
|
||||||
interface ID3D12GraphicsCommandList6 : ID3D12GraphicsCommandList5
|
|
||||||
{
|
|
||||||
void DispatchMesh(UINT x, UINT y, UINT z);
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef enum D3D12_TILE_RANGE_FLAGS
|
typedef enum D3D12_TILE_RANGE_FLAGS
|
||||||
{
|
{
|
||||||
D3D12_TILE_RANGE_FLAG_NONE = 0x0,
|
D3D12_TILE_RANGE_FLAG_NONE = 0x0,
|
||||||
|
@ -3628,7 +3243,6 @@ typedef enum D3D12_TILE_MAPPING_FLAGS
|
||||||
D3D12_TILE_MAPPING_FLAG_NONE = 0x0,
|
D3D12_TILE_MAPPING_FLAG_NONE = 0x0,
|
||||||
D3D12_TILE_MAPPING_FLAG_NO_HAZARD = 0x1,
|
D3D12_TILE_MAPPING_FLAG_NO_HAZARD = 0x1,
|
||||||
} D3D12_TILE_MAPPING_FLAGS;
|
} D3D12_TILE_MAPPING_FLAGS;
|
||||||
cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_TILE_MAPPING_FLAGS);")
|
|
||||||
|
|
||||||
[
|
[
|
||||||
uuid(0ec870a6-5d7e-4c22-8cfc-5baae07616ed),
|
uuid(0ec870a6-5d7e-4c22-8cfc-5baae07616ed),
|
||||||
|
@ -3644,8 +3258,8 @@ interface ID3D12CommandQueue : ID3D12Pageable
|
||||||
ID3D12Heap *heap,
|
ID3D12Heap *heap,
|
||||||
UINT range_count,
|
UINT range_count,
|
||||||
const D3D12_TILE_RANGE_FLAGS *range_flags,
|
const D3D12_TILE_RANGE_FLAGS *range_flags,
|
||||||
const UINT *heap_range_offsets,
|
UINT *heap_range_offsets,
|
||||||
const UINT *range_tile_counts,
|
UINT *range_tile_counts,
|
||||||
D3D12_TILE_MAPPING_FLAGS flags);
|
D3D12_TILE_MAPPING_FLAGS flags);
|
||||||
|
|
||||||
void CopyTileMappings(ID3D12Resource *dst_resource,
|
void CopyTileMappings(ID3D12Resource *dst_resource,
|
||||||
|
@ -3676,9 +3290,7 @@ typedef enum D3D12_FENCE_FLAGS
|
||||||
D3D12_FENCE_FLAG_NONE = 0x0,
|
D3D12_FENCE_FLAG_NONE = 0x0,
|
||||||
D3D12_FENCE_FLAG_SHARED = 0x1,
|
D3D12_FENCE_FLAG_SHARED = 0x1,
|
||||||
D3D12_FENCE_FLAG_SHARED_CROSS_ADAPTER = 0x2,
|
D3D12_FENCE_FLAG_SHARED_CROSS_ADAPTER = 0x2,
|
||||||
D3D12_FENCE_FLAG_NON_MONITORED = 0x4,
|
|
||||||
} D3D12_FENCE_FLAGS;
|
} D3D12_FENCE_FLAGS;
|
||||||
cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_FENCE_FLAGS);")
|
|
||||||
|
|
||||||
typedef enum D3D12_QUERY_HEAP_TYPE
|
typedef enum D3D12_QUERY_HEAP_TYPE
|
||||||
{
|
{
|
||||||
|
@ -3695,7 +3307,6 @@ typedef enum D3D12_RESIDENCY_FLAGS
|
||||||
D3D12_RESIDENCY_FLAG_NONE = 0,
|
D3D12_RESIDENCY_FLAG_NONE = 0,
|
||||||
D3D12_RESIDENCY_FLAG_DENY_OVERBUDGET = 0,
|
D3D12_RESIDENCY_FLAG_DENY_OVERBUDGET = 0,
|
||||||
} D3D12_RESIDENCY_FLAGS;
|
} D3D12_RESIDENCY_FLAGS;
|
||||||
cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_RESIDENCY_FLAGS);")
|
|
||||||
|
|
||||||
typedef struct D3D12_QUERY_HEAP_DESC
|
typedef struct D3D12_QUERY_HEAP_DESC
|
||||||
{
|
{
|
||||||
|
@ -3715,8 +3326,6 @@ typedef enum D3D12_INDIRECT_ARGUMENT_TYPE
|
||||||
D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT_BUFFER_VIEW,
|
D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT_BUFFER_VIEW,
|
||||||
D3D12_INDIRECT_ARGUMENT_TYPE_SHADER_RESOURCE_VIEW,
|
D3D12_INDIRECT_ARGUMENT_TYPE_SHADER_RESOURCE_VIEW,
|
||||||
D3D12_INDIRECT_ARGUMENT_TYPE_UNORDERED_ACCESS_VIEW,
|
D3D12_INDIRECT_ARGUMENT_TYPE_UNORDERED_ACCESS_VIEW,
|
||||||
D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH_RAYS,
|
|
||||||
D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH_MESH,
|
|
||||||
} D3D12_INDIRECT_ARGUMENT_TYPE;
|
} D3D12_INDIRECT_ARGUMENT_TYPE;
|
||||||
|
|
||||||
typedef struct D3D12_INDIRECT_ARGUMENT_DESC
|
typedef struct D3D12_INDIRECT_ARGUMENT_DESC
|
||||||
|
@ -4102,67 +3711,6 @@ interface ID3D12Device6 : ID3D12Device5
|
||||||
D3D12_MEASUREMENTS_ACTION action, HANDLE event, BOOL further_measurements);
|
D3D12_MEASUREMENTS_ACTION action, HANDLE event, BOOL further_measurements);
|
||||||
}
|
}
|
||||||
|
|
||||||
[
|
|
||||||
uuid(5c014b53-68a1-4b9b-8bd1-dd6046b9358b),
|
|
||||||
object,
|
|
||||||
local,
|
|
||||||
pointer_default(unique)
|
|
||||||
]
|
|
||||||
interface ID3D12Device7 : ID3D12Device6
|
|
||||||
{
|
|
||||||
HRESULT AddToStateObject(const D3D12_STATE_OBJECT_DESC *addition,
|
|
||||||
ID3D12StateObject *state_object, REFIID riid, void **new_state_object);
|
|
||||||
|
|
||||||
HRESULT CreateProtectedResourceSession1(
|
|
||||||
const D3D12_PROTECTED_RESOURCE_SESSION_DESC1 *desc,
|
|
||||||
REFIID riid, void **session);
|
|
||||||
}
|
|
||||||
[
|
|
||||||
uuid(9218e6bb-f944-4f7e-a75c-b1b2c7b701f3),
|
|
||||||
object,
|
|
||||||
local,
|
|
||||||
pointer_default(unique)
|
|
||||||
]
|
|
||||||
interface ID3D12Device8 : ID3D12Device7
|
|
||||||
{
|
|
||||||
D3D12_RESOURCE_ALLOCATION_INFO GetResourceAllocationInfo2(UINT visible_mask,
|
|
||||||
UINT resource_desc_count, const D3D12_RESOURCE_DESC1 *resource_descs,
|
|
||||||
D3D12_RESOURCE_ALLOCATION_INFO1 *resource_allocation_infos);
|
|
||||||
|
|
||||||
HRESULT CreateCommittedResource2(const D3D12_HEAP_PROPERTIES *heap_properties,
|
|
||||||
D3D12_HEAP_FLAGS heap_flags, const D3D12_RESOURCE_DESC1 *resource_desc,
|
|
||||||
D3D12_RESOURCE_STATES initial_state, const D3D12_CLEAR_VALUE *optimized_clear_value,
|
|
||||||
ID3D12ProtectedResourceSession *protected_session, REFIID riid, void **resource);
|
|
||||||
|
|
||||||
HRESULT CreatePlacedResource1(ID3D12Heap *heap, UINT64 heap_offset,
|
|
||||||
const D3D12_RESOURCE_DESC1 *resource_desc, D3D12_RESOURCE_STATES initial_state,
|
|
||||||
const D3D12_CLEAR_VALUE *optimized_clear_value, REFIID riid, void **resource);
|
|
||||||
|
|
||||||
void CreateSamplerFeedbackUnorderedAccessView(ID3D12Resource *target_resource,
|
|
||||||
ID3D12Resource *feedback_resource, D3D12_CPU_DESCRIPTOR_HANDLE descriptor);
|
|
||||||
|
|
||||||
void GetCopyableFootprints1(const D3D12_RESOURCE_DESC1 *resource_desc,
|
|
||||||
UINT first_sub_resource, UINT sub_resource_count, UINT64 base_offset,
|
|
||||||
D3D12_PLACED_SUBRESOURCE_FOOTPRINT *layouts, UINT *row_count,
|
|
||||||
UINT64 *row_size, UINT64 *total_bytes);
|
|
||||||
}
|
|
||||||
[
|
|
||||||
uuid(4c80e962-f032-4f60-bc9e-ebc2cfa1d83c),
|
|
||||||
object,
|
|
||||||
local,
|
|
||||||
pointer_default(unique)
|
|
||||||
]
|
|
||||||
interface ID3D12Device9 : ID3D12Device8
|
|
||||||
{
|
|
||||||
HRESULT CreateShaderCacheSession(const D3D12_SHADER_CACHE_SESSION_DESC *desc,
|
|
||||||
REFIID riid, void **session);
|
|
||||||
|
|
||||||
HRESULT ShaderCacheControl(D3D12_SHADER_CACHE_KIND_FLAGS kinds,
|
|
||||||
D3D12_SHADER_CACHE_CONTROL_FLAGS control);
|
|
||||||
|
|
||||||
HRESULT CreateCommandQueue1(const D3D12_COMMAND_QUEUE_DESC *desc,
|
|
||||||
REFIID creator_id, REFIID riid, void **command_queue);
|
|
||||||
}
|
|
||||||
[
|
[
|
||||||
uuid(34ab647b-3cc8-46ac-841b-c0965645c046),
|
uuid(34ab647b-3cc8-46ac-841b-c0965645c046),
|
||||||
object,
|
object,
|
||||||
|
@ -4217,13 +3765,3 @@ typedef HRESULT (__stdcall *PFN_D3D12_CREATE_DEVICE)(IUnknown *adapter,
|
||||||
typedef HRESULT (__stdcall *PFN_D3D12_GET_DEBUG_INTERFACE)(REFIID iid, void **debug);
|
typedef HRESULT (__stdcall *PFN_D3D12_GET_DEBUG_INTERFACE)(REFIID iid, void **debug);
|
||||||
|
|
||||||
[local] HRESULT __stdcall D3D12GetDebugInterface(REFIID iid, void **debug);
|
[local] HRESULT __stdcall D3D12GetDebugInterface(REFIID iid, void **debug);
|
||||||
|
|
||||||
cpp_quote("DEFINE_GUID(D3D12ExperimentalShaderModels, 0x76f5573e, 0xf13a, 0x40f5, 0xb2, 0x97, 0x81, 0xce, 0x9e, 0x18, 0x93, 0x3f );")
|
|
||||||
cpp_quote("DEFINE_GUID(D3D12TiledResourceTier4, 0xc9c4725f, 0xa81a, 0x4f56, 0x8c, 0x5b, 0xc5, 0x10, 0x39, 0xd6, 0x94, 0xfb );")
|
|
||||||
cpp_quote("DEFINE_GUID(D3D12MetaCommand, 0xc734c97e, 0x8077, 0x48c8, 0x9f, 0xdc, 0xd9, 0xd1, 0xdd, 0x31, 0xdd, 0x77 );")
|
|
||||||
|
|
||||||
typedef HRESULT (__stdcall *PFN_D3D12_ENABLE_EXPERIMENTAL_FEATURES)(UINT num_features,
|
|
||||||
const IID *iids, void *config_structs, UINT *config_struct_sizes);
|
|
||||||
|
|
||||||
[local] HRESULT __stdcall D3D12EnableExperimentalFeatures(UINT num_features,
|
|
||||||
const IID *iids, void *config_structs, UINT *config_struct_sizes);
|
|
||||||
|
|
|
@ -77,7 +77,6 @@ typedef enum D3D_FEATURE_LEVEL
|
||||||
D3D_FEATURE_LEVEL_11_1 = 0xb100,
|
D3D_FEATURE_LEVEL_11_1 = 0xb100,
|
||||||
D3D_FEATURE_LEVEL_12_0 = 0xc000,
|
D3D_FEATURE_LEVEL_12_0 = 0xc000,
|
||||||
D3D_FEATURE_LEVEL_12_1 = 0xc100,
|
D3D_FEATURE_LEVEL_12_1 = 0xc100,
|
||||||
D3D_FEATURE_LEVEL_12_2 = 0xc200,
|
|
||||||
} D3D_FEATURE_LEVEL;
|
} D3D_FEATURE_LEVEL;
|
||||||
|
|
||||||
[
|
[
|
||||||
|
@ -94,7 +93,3 @@ interface ID3D10Blob : IUnknown
|
||||||
|
|
||||||
typedef ID3D10Blob ID3DBlob;
|
typedef ID3D10Blob ID3DBlob;
|
||||||
cpp_quote("#define IID_ID3DBlob IID_ID3D10Blob")
|
cpp_quote("#define IID_ID3DBlob IID_ID3D10Blob")
|
||||||
|
|
||||||
cpp_quote("DEFINE_GUID(WKPDID_D3DDebugObjectName,0x429b8c22,0x9188,0x4b0c,0x87,0x42,0xac,0xb0,0xbf,0x85,0xc2,0x00);")
|
|
||||||
cpp_quote("DEFINE_GUID(WKPDID_D3DDebugObjectNameW,0x4cca5fd8,0x921f,0x42c8,0x85,0x66,0x70,0xca,0xf2,0xa9,0xb7,0x41);")
|
|
||||||
cpp_quote("DEFINE_GUID(WKPDID_CommentStringW,0xd0149dc0,0x90e8,0x4ec8,0x81,0x44,0xe9,0x00,0xad,0x26,0x6b,0xb2);")
|
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
/*
|
|
||||||
* * Copyright 2021 NVIDIA Corporation
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
||||||
*/
|
|
||||||
import "vkd3d_d3d12.idl";
|
|
||||||
import "vkd3d_vk_includes.h";
|
|
||||||
|
|
||||||
[
|
|
||||||
uuid(11ea7a1a-0f6a-49bf-b612-3e30f8e201dd),
|
|
||||||
object,
|
|
||||||
local,
|
|
||||||
pointer_default(unique)
|
|
||||||
]
|
|
||||||
interface ID3D12DeviceExt : IUnknown
|
|
||||||
{
|
|
||||||
HRESULT GetVulkanHandles(VkInstance *vk_instance, VkPhysicalDevice *vk_physical_device, VkDevice *vk_device);
|
|
||||||
BOOL GetExtensionSupport(D3D12_VK_EXTENSION extension);
|
|
||||||
HRESULT CreateCubinComputeShaderWithName(const void *cubin_data, UINT32 cubin_size, UINT32 block_x, UINT32 block_y, UINT32 block_z, const char *shader_name, D3D12_CUBIN_DATA_HANDLE **handle);
|
|
||||||
HRESULT DestroyCubinComputeShader(D3D12_CUBIN_DATA_HANDLE *handle);
|
|
||||||
HRESULT GetCudaTextureObject(D3D12_CPU_DESCRIPTOR_HANDLE srv_handle, D3D12_CPU_DESCRIPTOR_HANDLE sampler_handle, UINT32 *cuda_texture_handle);
|
|
||||||
HRESULT GetCudaSurfaceObject(D3D12_CPU_DESCRIPTOR_HANDLE uav_handle, UINT32 *cuda_surface_handle);
|
|
||||||
HRESULT CaptureUAVInfo(D3D12_UAV_INFO *uav_info);
|
|
||||||
}
|
|
||||||
|
|
|
@ -135,12 +135,5 @@ typedef enum DXGI_FORMAT
|
||||||
DXGI_FORMAT_A8P8 = 0x72,
|
DXGI_FORMAT_A8P8 = 0x72,
|
||||||
DXGI_FORMAT_B4G4R4A4_UNORM = 0x73,
|
DXGI_FORMAT_B4G4R4A4_UNORM = 0x73,
|
||||||
|
|
||||||
DXGI_FORMAT_P208 = 0x82,
|
|
||||||
DXGI_FORMAT_V208 = 0x83,
|
|
||||||
DXGI_FORMAT_V408 = 0x84,
|
|
||||||
|
|
||||||
DXGI_FORMAT_SAMPLER_FEEDBACK_MIN_MIP_OPAQUE = 0xbd,
|
|
||||||
DXGI_FORMAT_SAMPLER_FEEDBACK_MIP_REGION_USED_OPAQUE = 0xbe,
|
|
||||||
|
|
||||||
DXGI_FORMAT_FORCE_UINT = 0xffffffff,
|
DXGI_FORMAT_FORCE_UINT = 0xffffffff,
|
||||||
} DXGI_FORMAT;
|
} DXGI_FORMAT;
|
||||||
|
|
|
@ -24,13 +24,23 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <hashmap.h>
|
#include <hashmap.h>
|
||||||
#include <vkd3d_types.h>
|
#include <vkd3d_types.h>
|
||||||
#include <vkd3d_d3d12.h>
|
|
||||||
#include <vkd3d.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
enum vkd3d_shader_structure_type
|
||||||
|
{
|
||||||
|
/* 1.2 */
|
||||||
|
VKD3D_SHADER_STRUCTURE_TYPE_SHADER_INTERFACE_INFO,
|
||||||
|
VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_ARGUMENTS,
|
||||||
|
VKD3D_SHADER_STRUCTURE_TYPE_SCAN_INFO,
|
||||||
|
VKD3D_SHADER_STRUCTURE_TYPE_TRANSFORM_FEEDBACK_INFO,
|
||||||
|
VKD3D_SHADER_STRUCTURE_TYPE_DOMAIN_SHADER_COMPILE_ARGUMENTS,
|
||||||
|
|
||||||
|
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_STRUCTURE_TYPE),
|
||||||
|
};
|
||||||
|
|
||||||
enum vkd3d_shader_compiler_option
|
enum vkd3d_shader_compiler_option
|
||||||
{
|
{
|
||||||
VKD3D_SHADER_STRIP_DEBUG = 0x00000001,
|
VKD3D_SHADER_STRIP_DEBUG = 0x00000001,
|
||||||
|
@ -54,22 +64,11 @@ enum vkd3d_shader_visibility
|
||||||
|
|
||||||
typedef uint64_t vkd3d_shader_hash_t;
|
typedef uint64_t vkd3d_shader_hash_t;
|
||||||
|
|
||||||
enum vkd3d_shader_meta_flags
|
|
||||||
{
|
|
||||||
VKD3D_SHADER_META_FLAG_REPLACED = 1 << 0,
|
|
||||||
VKD3D_SHADER_META_FLAG_USES_SUBGROUP_SIZE = 1 << 1,
|
|
||||||
VKD3D_SHADER_META_FLAG_USES_NATIVE_16BIT_OPERATIONS = 1 << 2,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct vkd3d_shader_meta
|
struct vkd3d_shader_meta
|
||||||
{
|
{
|
||||||
vkd3d_shader_hash_t hash;
|
vkd3d_shader_hash_t hash;
|
||||||
unsigned int cs_workgroup_size[3]; /* Only contains valid data if uses_subgroup_size is true. */
|
bool replaced;
|
||||||
unsigned int patch_vertex_count; /* Relevant for HS. May be 0, in which case the patch vertex count is not known. */
|
|
||||||
unsigned int cs_required_wave_size; /* If non-zero, force a specific CS subgroup size. */
|
|
||||||
uint32_t flags; /* vkd3d_shader_meta_flags */
|
|
||||||
};
|
};
|
||||||
STATIC_ASSERT(sizeof(struct vkd3d_shader_meta) == 32);
|
|
||||||
|
|
||||||
struct vkd3d_shader_code
|
struct vkd3d_shader_code
|
||||||
{
|
{
|
||||||
|
@ -78,8 +77,6 @@ struct vkd3d_shader_code
|
||||||
struct vkd3d_shader_meta meta;
|
struct vkd3d_shader_meta meta;
|
||||||
};
|
};
|
||||||
|
|
||||||
vkd3d_shader_hash_t vkd3d_shader_hash(const struct vkd3d_shader_code *shader);
|
|
||||||
|
|
||||||
enum vkd3d_shader_descriptor_type
|
enum vkd3d_shader_descriptor_type
|
||||||
{
|
{
|
||||||
VKD3D_SHADER_DESCRIPTOR_TYPE_UNKNOWN,
|
VKD3D_SHADER_DESCRIPTOR_TYPE_UNKNOWN,
|
||||||
|
@ -101,7 +98,7 @@ enum vkd3d_shader_binding_flag
|
||||||
{
|
{
|
||||||
VKD3D_SHADER_BINDING_FLAG_BUFFER = 0x00000001,
|
VKD3D_SHADER_BINDING_FLAG_BUFFER = 0x00000001,
|
||||||
VKD3D_SHADER_BINDING_FLAG_IMAGE = 0x00000002,
|
VKD3D_SHADER_BINDING_FLAG_IMAGE = 0x00000002,
|
||||||
VKD3D_SHADER_BINDING_FLAG_AUX_BUFFER = 0x00000004,
|
VKD3D_SHADER_BINDING_FLAG_COUNTER = 0x00000004,
|
||||||
VKD3D_SHADER_BINDING_FLAG_BINDLESS = 0x00000008,
|
VKD3D_SHADER_BINDING_FLAG_BINDLESS = 0x00000008,
|
||||||
VKD3D_SHADER_BINDING_FLAG_RAW_VA = 0x00000010,
|
VKD3D_SHADER_BINDING_FLAG_RAW_VA = 0x00000010,
|
||||||
VKD3D_SHADER_BINDING_FLAG_RAW_SSBO = 0x00000020,
|
VKD3D_SHADER_BINDING_FLAG_RAW_SSBO = 0x00000020,
|
||||||
|
@ -193,11 +190,12 @@ enum vkd3d_shader_interface_flag
|
||||||
VKD3D_SHADER_INTERFACE_BINDLESS_CBV_AS_STORAGE_BUFFER = 0x00000002u,
|
VKD3D_SHADER_INTERFACE_BINDLESS_CBV_AS_STORAGE_BUFFER = 0x00000002u,
|
||||||
VKD3D_SHADER_INTERFACE_SSBO_OFFSET_BUFFER = 0x00000004u,
|
VKD3D_SHADER_INTERFACE_SSBO_OFFSET_BUFFER = 0x00000004u,
|
||||||
VKD3D_SHADER_INTERFACE_TYPED_OFFSET_BUFFER = 0x00000008u,
|
VKD3D_SHADER_INTERFACE_TYPED_OFFSET_BUFFER = 0x00000008u,
|
||||||
VKD3D_SHADER_INTERFACE_DESCRIPTOR_QA_BUFFER = 0x00000010u
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct vkd3d_shader_interface_info
|
struct vkd3d_shader_interface_info
|
||||||
{
|
{
|
||||||
|
enum vkd3d_shader_structure_type type;
|
||||||
|
const void *next;
|
||||||
unsigned int flags; /* vkd3d_shader_interface_flags */
|
unsigned int flags; /* vkd3d_shader_interface_flags */
|
||||||
unsigned int min_ssbo_alignment;
|
unsigned int min_ssbo_alignment;
|
||||||
|
|
||||||
|
@ -212,58 +210,6 @@ struct vkd3d_shader_interface_info
|
||||||
const struct vkd3d_shader_descriptor_binding *push_constant_ubo_binding;
|
const struct vkd3d_shader_descriptor_binding *push_constant_ubo_binding;
|
||||||
/* Ignored unless VKD3D_SHADER_INTERFACE_SSBO_OFFSET_BUFFER or TYPED_OFFSET_BUFFER is set */
|
/* Ignored unless VKD3D_SHADER_INTERFACE_SSBO_OFFSET_BUFFER or TYPED_OFFSET_BUFFER is set */
|
||||||
const struct vkd3d_shader_descriptor_binding *offset_buffer_binding;
|
const struct vkd3d_shader_descriptor_binding *offset_buffer_binding;
|
||||||
|
|
||||||
#ifdef VKD3D_ENABLE_DESCRIPTOR_QA
|
|
||||||
/* Ignored unless VKD3D_SHADER_INTERFACE_DESCRIPTOR_QA_BUFFER is set. */
|
|
||||||
const struct vkd3d_shader_descriptor_binding *descriptor_qa_global_binding;
|
|
||||||
/* Ignored unless VKD3D_SHADER_INTERFACE_DESCRIPTOR_QA_BUFFER is set. */
|
|
||||||
const struct vkd3d_shader_descriptor_binding *descriptor_qa_heap_binding;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
VkShaderStageFlagBits stage;
|
|
||||||
|
|
||||||
const struct vkd3d_shader_transform_feedback_info *xfb_info;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct vkd3d_shader_descriptor_table
|
|
||||||
{
|
|
||||||
uint32_t table_index;
|
|
||||||
uint32_t binding_count;
|
|
||||||
struct vkd3d_shader_resource_binding *first_binding;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct vkd3d_shader_root_constant
|
|
||||||
{
|
|
||||||
uint32_t constant_index;
|
|
||||||
uint32_t constant_count;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct vkd3d_shader_root_descriptor
|
|
||||||
{
|
|
||||||
struct vkd3d_shader_resource_binding *binding;
|
|
||||||
uint32_t raw_va_root_descriptor_index;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct vkd3d_shader_root_parameter
|
|
||||||
{
|
|
||||||
D3D12_ROOT_PARAMETER_TYPE parameter_type;
|
|
||||||
union
|
|
||||||
{
|
|
||||||
struct vkd3d_shader_root_constant constant;
|
|
||||||
struct vkd3d_shader_root_descriptor descriptor;
|
|
||||||
struct vkd3d_shader_descriptor_table descriptor_table;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct vkd3d_shader_interface_local_info
|
|
||||||
{
|
|
||||||
const struct vkd3d_shader_root_parameter *local_root_parameters;
|
|
||||||
unsigned int local_root_parameter_count;
|
|
||||||
const struct vkd3d_shader_push_constant_buffer *shader_record_constant_buffers;
|
|
||||||
unsigned int shader_record_buffer_count;
|
|
||||||
const struct vkd3d_shader_resource_binding *bindings;
|
|
||||||
unsigned int binding_count;
|
|
||||||
uint32_t descriptor_size;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct vkd3d_shader_transform_feedback_element
|
struct vkd3d_shader_transform_feedback_element
|
||||||
|
@ -276,8 +222,12 @@ struct vkd3d_shader_transform_feedback_element
|
||||||
uint8_t output_slot;
|
uint8_t output_slot;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Extends vkd3d_shader_interface_info. */
|
||||||
struct vkd3d_shader_transform_feedback_info
|
struct vkd3d_shader_transform_feedback_info
|
||||||
{
|
{
|
||||||
|
enum vkd3d_shader_structure_type type;
|
||||||
|
const void *next;
|
||||||
|
|
||||||
const struct vkd3d_shader_transform_feedback_element *elements;
|
const struct vkd3d_shader_transform_feedback_element *elements;
|
||||||
unsigned int element_count;
|
unsigned int element_count;
|
||||||
const unsigned int *buffer_strides;
|
const unsigned int *buffer_strides;
|
||||||
|
@ -297,63 +247,14 @@ enum vkd3d_shader_target_extension
|
||||||
VKD3D_SHADER_TARGET_EXTENSION_NONE,
|
VKD3D_SHADER_TARGET_EXTENSION_NONE,
|
||||||
|
|
||||||
VKD3D_SHADER_TARGET_EXTENSION_SPV_EXT_DEMOTE_TO_HELPER_INVOCATION,
|
VKD3D_SHADER_TARGET_EXTENSION_SPV_EXT_DEMOTE_TO_HELPER_INVOCATION,
|
||||||
VKD3D_SHADER_TARGET_EXTENSION_READ_STORAGE_IMAGE_WITHOUT_FORMAT,
|
VKD3D_SHADER_TARGET_EXTENSION_READ_STORAGE_IMAGE_WITHOUT_FORMAT
|
||||||
VKD3D_SHADER_TARGET_EXTENSION_SPV_KHR_INTEGER_DOT_PRODUCT,
|
|
||||||
VKD3D_SHADER_TARGET_EXTENSION_RAY_TRACING_PRIMITIVE_CULLING,
|
|
||||||
VKD3D_SHADER_TARGET_EXTENSION_SCALAR_BLOCK_LAYOUT,
|
|
||||||
|
|
||||||
/* When using scalar block layout with a vec3 array on a byte address buffer,
|
|
||||||
* there is diverging behavior across hardware.
|
|
||||||
* On AMD, robustness is checked per component, which means we can implement ByteAddressBuffer
|
|
||||||
* without further hackery. On NVIDIA, robustness does not seem to work this way, so it's either
|
|
||||||
* all in range, or all out of range. We can implement structured buffer vectorization of vec3,
|
|
||||||
* but not byte address buffer. */
|
|
||||||
VKD3D_SHADER_TARGET_EXTENSION_ASSUME_PER_COMPONENT_SSBO_ROBUSTNESS,
|
|
||||||
VKD3D_SHADER_TARGET_EXTENSION_BARYCENTRIC_KHR,
|
|
||||||
VKD3D_SHADER_TARGET_EXTENSION_MIN_PRECISION_IS_NATIVE_16BIT,
|
|
||||||
VKD3D_SHADER_TARGET_EXTENSION_COUNT,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum vkd3d_shader_quirk
|
|
||||||
{
|
|
||||||
/* If sample or sample_b is used in control flow, force LOD 0.0 (which game should expect anyway).
|
|
||||||
* Works around specific, questionable shaders which rely on this to give sensible results,
|
|
||||||
* since LOD can become garbage on certain implementations, and even on native drivers
|
|
||||||
* the result is implementation defined.
|
|
||||||
* Outside of making this edge case well-defined in Vulkan or hacking driver compilers,
|
|
||||||
* this is the pragmatic solution.
|
|
||||||
* Hoisting gradients is not possible in all cases,
|
|
||||||
* and would not be worth it until it's a widespread problem. */
|
|
||||||
VKD3D_SHADER_QUIRK_FORCE_EXPLICIT_LOD_IN_CONTROL_FLOW = (1 << 0),
|
|
||||||
|
|
||||||
/* After every write to group shared memory, force a memory barrier.
|
|
||||||
* This works around buggy games which forget to use barrier(). */
|
|
||||||
VKD3D_SHADER_QUIRK_FORCE_TGSM_BARRIERS = (1 << 1),
|
|
||||||
|
|
||||||
/* For Position builtins in Output storage class, emit Invariant decoration.
|
|
||||||
* Normally, games have to emit Precise math for position, but if they forget ... */
|
|
||||||
VKD3D_SHADER_QUIRK_INVARIANT_POSITION = (1 << 2),
|
|
||||||
};
|
|
||||||
|
|
||||||
struct vkd3d_shader_quirk_hash
|
|
||||||
{
|
|
||||||
vkd3d_shader_hash_t shader_hash;
|
|
||||||
uint32_t quirks;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct vkd3d_shader_quirk_info
|
|
||||||
{
|
|
||||||
const struct vkd3d_shader_quirk_hash *hashes;
|
|
||||||
unsigned int num_hashes;
|
|
||||||
uint32_t default_quirks;
|
|
||||||
|
|
||||||
/* Quirks which are ORed in with the other masks (including default_quirks).
|
|
||||||
* Used mostly for additional overrides from VKD3D_CONFIG. */
|
|
||||||
uint32_t global_quirks;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct vkd3d_shader_compile_arguments
|
struct vkd3d_shader_compile_arguments
|
||||||
{
|
{
|
||||||
|
enum vkd3d_shader_structure_type type;
|
||||||
|
const void *next;
|
||||||
|
|
||||||
enum vkd3d_shader_target target;
|
enum vkd3d_shader_target target;
|
||||||
|
|
||||||
unsigned int target_extension_count;
|
unsigned int target_extension_count;
|
||||||
|
@ -365,8 +266,6 @@ struct vkd3d_shader_compile_arguments
|
||||||
bool dual_source_blending;
|
bool dual_source_blending;
|
||||||
const unsigned int *output_swizzles;
|
const unsigned int *output_swizzles;
|
||||||
unsigned int output_swizzle_count;
|
unsigned int output_swizzle_count;
|
||||||
|
|
||||||
const struct vkd3d_shader_quirk_info *quirks;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum vkd3d_tessellator_output_primitive
|
enum vkd3d_tessellator_output_primitive
|
||||||
|
@ -385,6 +284,16 @@ enum vkd3d_tessellator_partitioning
|
||||||
VKD3D_TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN = 4,
|
VKD3D_TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN = 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Extends vkd3d_shader_compile_arguments. */
|
||||||
|
struct vkd3d_shader_domain_shader_compile_arguments
|
||||||
|
{
|
||||||
|
enum vkd3d_shader_structure_type type;
|
||||||
|
const void *next;
|
||||||
|
|
||||||
|
enum vkd3d_tessellator_output_primitive output_primitive;
|
||||||
|
enum vkd3d_tessellator_partitioning partitioning;
|
||||||
|
};
|
||||||
|
|
||||||
/* root signature 1.0 */
|
/* root signature 1.0 */
|
||||||
enum vkd3d_filter
|
enum vkd3d_filter
|
||||||
{
|
{
|
||||||
|
@ -579,7 +488,6 @@ enum vkd3d_descriptor_range_flags
|
||||||
VKD3D_DESCRIPTOR_RANGE_FLAG_DATA_VOLATILE = 0x2,
|
VKD3D_DESCRIPTOR_RANGE_FLAG_DATA_VOLATILE = 0x2,
|
||||||
VKD3D_DESCRIPTOR_RANGE_FLAG_DATA_STATIC_WHILE_SET_AT_EXECUTE = 0x4,
|
VKD3D_DESCRIPTOR_RANGE_FLAG_DATA_STATIC_WHILE_SET_AT_EXECUTE = 0x4,
|
||||||
VKD3D_DESCRIPTOR_RANGE_FLAG_DATA_STATIC = 0x8,
|
VKD3D_DESCRIPTOR_RANGE_FLAG_DATA_STATIC = 0x8,
|
||||||
VKD3D_DESCRIPTOR_RANGE_FLAG_DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS = 0x10000
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct vkd3d_descriptor_range1
|
struct vkd3d_descriptor_range1
|
||||||
|
@ -648,20 +556,12 @@ enum vkd3d_shader_uav_flag
|
||||||
{
|
{
|
||||||
VKD3D_SHADER_UAV_FLAG_READ_ACCESS = 0x00000001,
|
VKD3D_SHADER_UAV_FLAG_READ_ACCESS = 0x00000001,
|
||||||
VKD3D_SHADER_UAV_FLAG_ATOMIC_COUNTER = 0x00000002,
|
VKD3D_SHADER_UAV_FLAG_ATOMIC_COUNTER = 0x00000002,
|
||||||
VKD3D_SHADER_UAV_FLAG_ATOMIC_ACCESS = 0x00000004,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct vkd3d_shader_scan_info
|
struct vkd3d_shader_scan_info
|
||||||
{
|
{
|
||||||
struct hash_map register_map;
|
struct hash_map register_map;
|
||||||
bool use_vocp;
|
bool use_vocp;
|
||||||
|
|
||||||
bool early_fragment_tests;
|
|
||||||
bool has_side_effects;
|
|
||||||
bool needs_late_zs;
|
|
||||||
bool discards;
|
|
||||||
bool has_uav_counter;
|
|
||||||
unsigned int patch_vertex_count;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum vkd3d_component_type
|
enum vkd3d_component_type
|
||||||
|
@ -754,11 +654,7 @@ int vkd3d_shader_compile_dxbc(const struct vkd3d_shader_code *dxbc,
|
||||||
void vkd3d_shader_free_shader_code(struct vkd3d_shader_code *code);
|
void vkd3d_shader_free_shader_code(struct vkd3d_shader_code *code);
|
||||||
|
|
||||||
int vkd3d_shader_parse_root_signature(const struct vkd3d_shader_code *dxbc,
|
int vkd3d_shader_parse_root_signature(const struct vkd3d_shader_code *dxbc,
|
||||||
struct vkd3d_versioned_root_signature_desc *root_signature,
|
struct vkd3d_versioned_root_signature_desc *root_signature);
|
||||||
vkd3d_shader_hash_t *compatibility_hash);
|
|
||||||
int vkd3d_shader_parse_root_signature_raw(const char *data, unsigned int data_size,
|
|
||||||
struct vkd3d_versioned_root_signature_desc *desc,
|
|
||||||
vkd3d_shader_hash_t *compatibility_hash);
|
|
||||||
void vkd3d_shader_free_root_signature(struct vkd3d_versioned_root_signature_desc *root_signature);
|
void vkd3d_shader_free_root_signature(struct vkd3d_versioned_root_signature_desc *root_signature);
|
||||||
|
|
||||||
/* FIXME: Add support for returning error messages (ID3DBlob). */
|
/* FIXME: Add support for returning error messages (ID3DBlob). */
|
||||||
|
@ -771,90 +667,18 @@ int vkd3d_shader_convert_root_signature(struct vkd3d_versioned_root_signature_de
|
||||||
int vkd3d_shader_scan_dxbc(const struct vkd3d_shader_code *dxbc,
|
int vkd3d_shader_scan_dxbc(const struct vkd3d_shader_code *dxbc,
|
||||||
struct vkd3d_shader_scan_info *scan_info);
|
struct vkd3d_shader_scan_info *scan_info);
|
||||||
|
|
||||||
|
/* If value cannot be determined, *patch_vertex_count returns 0. */
|
||||||
|
int vkd3d_shader_scan_patch_vertex_count(const struct vkd3d_shader_code *dxbc,
|
||||||
|
unsigned int *patch_vertex_count);
|
||||||
|
|
||||||
int vkd3d_shader_parse_input_signature(const struct vkd3d_shader_code *dxbc,
|
int vkd3d_shader_parse_input_signature(const struct vkd3d_shader_code *dxbc,
|
||||||
struct vkd3d_shader_signature *signature);
|
struct vkd3d_shader_signature *signature);
|
||||||
int vkd3d_shader_parse_output_signature(const struct vkd3d_shader_code *dxbc,
|
|
||||||
struct vkd3d_shader_signature *signature);
|
|
||||||
struct vkd3d_shader_signature_element *vkd3d_shader_find_signature_element(
|
struct vkd3d_shader_signature_element *vkd3d_shader_find_signature_element(
|
||||||
const struct vkd3d_shader_signature *signature, const char *semantic_name,
|
const struct vkd3d_shader_signature *signature, const char *semantic_name,
|
||||||
unsigned int semantic_index, unsigned int stream_index);
|
unsigned int semantic_index, unsigned int stream_index);
|
||||||
void vkd3d_shader_free_shader_signature(struct vkd3d_shader_signature *signature);
|
void vkd3d_shader_free_shader_signature(struct vkd3d_shader_signature *signature);
|
||||||
|
|
||||||
/* For DXR, use special purpose entry points since there's a lot of special purpose reflection required. */
|
int vkd3d_shader_supports_dxil(void);
|
||||||
struct vkd3d_shader_library_entry_point
|
|
||||||
{
|
|
||||||
unsigned int identifier;
|
|
||||||
VkShaderStageFlagBits stage;
|
|
||||||
WCHAR *mangled_entry_point;
|
|
||||||
WCHAR *plain_entry_point;
|
|
||||||
char *real_entry_point;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum vkd3d_shader_subobject_kind
|
|
||||||
{
|
|
||||||
/* Matches DXIL for simplicity. */
|
|
||||||
VKD3D_SHADER_SUBOBJECT_KIND_STATE_OBJECT_CONFIG = 0,
|
|
||||||
VKD3D_SHADER_SUBOBJECT_KIND_GLOBAL_ROOT_SIGNATURE = 1,
|
|
||||||
VKD3D_SHADER_SUBOBJECT_KIND_LOCAL_ROOT_SIGNATURE = 2,
|
|
||||||
VKD3D_SHADER_SUBOBJECT_KIND_SUBOBJECT_TO_EXPORTS_ASSOCIATION = 8,
|
|
||||||
VKD3D_SHADER_SUBOBJECT_KIND_RAYTRACING_SHADER_CONFIG = 9,
|
|
||||||
VKD3D_SHADER_SUBOBJECT_KIND_RAYTRACING_PIPELINE_CONFIG = 10,
|
|
||||||
VKD3D_SHADER_SUBOBJECT_KIND_HIT_GROUP = 11,
|
|
||||||
VKD3D_SHADER_SUBOBJECT_KIND_RAYTRACING_PIPELINE_CONFIG1 = 12,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct vkd3d_shader_library_subobject
|
|
||||||
{
|
|
||||||
enum vkd3d_shader_subobject_kind kind;
|
|
||||||
unsigned int dxil_identifier;
|
|
||||||
|
|
||||||
/* All const pointers here point directly to the DXBC blob,
|
|
||||||
* so they do not need to be freed.
|
|
||||||
* Fortunately for us, the C strings are zero-terminated in the blob itself. */
|
|
||||||
|
|
||||||
/* In the blob, ASCII is used as identifier, where API uses wide strings, sigh ... */
|
|
||||||
const char *name;
|
|
||||||
|
|
||||||
union
|
|
||||||
{
|
|
||||||
D3D12_RAYTRACING_PIPELINE_CONFIG1 pipeline_config;
|
|
||||||
D3D12_RAYTRACING_SHADER_CONFIG shader_config;
|
|
||||||
D3D12_STATE_OBJECT_CONFIG object_config;
|
|
||||||
|
|
||||||
/* Duped strings because API wants wide strings for no good reason. */
|
|
||||||
D3D12_HIT_GROUP_DESC hit_group;
|
|
||||||
D3D12_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION association;
|
|
||||||
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
const void *data;
|
|
||||||
size_t size;
|
|
||||||
} payload;
|
|
||||||
} data;
|
|
||||||
};
|
|
||||||
|
|
||||||
int vkd3d_shader_dxil_append_library_entry_points_and_subobjects(
|
|
||||||
const D3D12_DXIL_LIBRARY_DESC *library_desc,
|
|
||||||
unsigned int identifier,
|
|
||||||
struct vkd3d_shader_library_entry_point **entry_points,
|
|
||||||
size_t *entry_point_size, size_t *entry_point_count,
|
|
||||||
struct vkd3d_shader_library_subobject **subobjects,
|
|
||||||
size_t *subobjects_size, size_t *subobjects_count);
|
|
||||||
|
|
||||||
void vkd3d_shader_dxil_free_library_entry_points(struct vkd3d_shader_library_entry_point *entry_points, size_t count);
|
|
||||||
void vkd3d_shader_dxil_free_library_subobjects(struct vkd3d_shader_library_subobject *subobjects, size_t count);
|
|
||||||
|
|
||||||
int vkd3d_shader_compile_dxil_export(const struct vkd3d_shader_code *dxil,
|
|
||||||
const char *export,
|
|
||||||
struct vkd3d_shader_code *spirv,
|
|
||||||
const struct vkd3d_shader_interface_info *shader_interface_info,
|
|
||||||
const struct vkd3d_shader_interface_local_info *shader_interface_local_info,
|
|
||||||
const struct vkd3d_shader_compile_arguments *compiler_args);
|
|
||||||
|
|
||||||
uint32_t vkd3d_shader_compile_arguments_select_quirks(
|
|
||||||
const struct vkd3d_shader_compile_arguments *args, vkd3d_shader_hash_t hash);
|
|
||||||
|
|
||||||
uint64_t vkd3d_shader_get_revision(void);
|
|
||||||
|
|
||||||
#endif /* VKD3D_SHADER_NO_PROTOTYPES */
|
#endif /* VKD3D_SHADER_NO_PROTOTYPES */
|
||||||
|
|
||||||
|
@ -868,8 +692,7 @@ typedef int (*PFN_vkd3d_shader_compile_dxbc)(const struct vkd3d_shader_code *dxb
|
||||||
typedef void (*PFN_vkd3d_shader_free_shader_code)(struct vkd3d_shader_code *code);
|
typedef void (*PFN_vkd3d_shader_free_shader_code)(struct vkd3d_shader_code *code);
|
||||||
|
|
||||||
typedef int (*PFN_vkd3d_shader_parse_root_signature)(const struct vkd3d_shader_code *dxbc,
|
typedef int (*PFN_vkd3d_shader_parse_root_signature)(const struct vkd3d_shader_code *dxbc,
|
||||||
struct vkd3d_versioned_root_signature_desc *root_signature,
|
struct vkd3d_versioned_root_signature_desc *root_signature);
|
||||||
vkd3d_shader_hash_t *compatibility_hash);
|
|
||||||
typedef void (*PFN_vkd3d_shader_free_root_signature)(struct vkd3d_versioned_root_signature_desc *root_signature);
|
typedef void (*PFN_vkd3d_shader_free_root_signature)(struct vkd3d_versioned_root_signature_desc *root_signature);
|
||||||
|
|
||||||
typedef int (*PFN_vkd3d_shader_serialize_root_signature)(
|
typedef int (*PFN_vkd3d_shader_serialize_root_signature)(
|
||||||
|
@ -880,6 +703,8 @@ typedef int (*PFN_vkd3d_shader_convert_root_signature)(struct vkd3d_versioned_ro
|
||||||
|
|
||||||
typedef int (*PFN_vkd3d_shader_scan_dxbc)(const struct vkd3d_shader_code *dxbc,
|
typedef int (*PFN_vkd3d_shader_scan_dxbc)(const struct vkd3d_shader_code *dxbc,
|
||||||
struct vkd3d_shader_scan_info *scan_info);
|
struct vkd3d_shader_scan_info *scan_info);
|
||||||
|
typedef int (*PFN_vkd3d_shader_scan_patch_vertex_count)(const struct vkd3d_shader_code *dxbc,
|
||||||
|
unsigned int *patch_vertex_count);
|
||||||
|
|
||||||
typedef int (*PFN_vkd3d_shader_parse_input_signature)(const struct vkd3d_shader_code *dxbc,
|
typedef int (*PFN_vkd3d_shader_parse_input_signature)(const struct vkd3d_shader_code *dxbc,
|
||||||
struct vkd3d_shader_signature *signature);
|
struct vkd3d_shader_signature *signature);
|
||||||
|
|
|
@ -1,58 +0,0 @@
|
||||||
/*
|
|
||||||
* * Copyright 2021 NVIDIA Corporation
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
||||||
*/
|
|
||||||
#ifndef __VKD3D_VK_INCLUDES_H
|
|
||||||
#define __VKD3D_VK_INCLUDES_H
|
|
||||||
|
|
||||||
#if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__) ) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)
|
|
||||||
typedef struct VkCuFunctionNVX_T *VkCuFunctionNVX;
|
|
||||||
typedef struct VkCuModuleNVX_T *VkCuModuleNVX;
|
|
||||||
#else
|
|
||||||
typedef UINT64 VkCuFunctionNVX;
|
|
||||||
typedef UINT64 VkCuModuleNVX;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct VkPhysicalDevice_T *VkPhysicalDevice;
|
|
||||||
typedef struct VkCommandBuffer_T *VkCommandBuffer;
|
|
||||||
typedef struct VkInstance_T *VkInstance;
|
|
||||||
typedef struct VkDevice_T *VkDevice;
|
|
||||||
|
|
||||||
typedef enum D3D12_VK_EXTENSION
|
|
||||||
{
|
|
||||||
D3D12_VK_NVX_BINARY_IMPORT = 0x1,
|
|
||||||
D3D12_VK_NVX_IMAGE_VIEW_HANDLE = 0x2
|
|
||||||
} D3D12_VK_EXTENSION;
|
|
||||||
|
|
||||||
typedef struct D3D12_CUBIN_DATA_HANDLE
|
|
||||||
{
|
|
||||||
VkCuFunctionNVX vkCuFunction;
|
|
||||||
VkCuModuleNVX vkCuModule;
|
|
||||||
UINT32 blockX;
|
|
||||||
UINT32 blockY;
|
|
||||||
UINT32 blockZ;
|
|
||||||
} D3D12_CUBIN_DATA_HANDLE;
|
|
||||||
|
|
||||||
typedef struct D3D12_UAV_INFO
|
|
||||||
{
|
|
||||||
UINT32 version;
|
|
||||||
UINT32 surfaceHandle;
|
|
||||||
UINT64 gpuVAStart;
|
|
||||||
UINT64 gpuVASize;
|
|
||||||
} D3D12_UAV_INFO;
|
|
||||||
|
|
||||||
#endif // __VKD3D_VK_INCLUDES_H
|
|
||||||
|
|
|
@ -42,20 +42,8 @@
|
||||||
#define WIDL_C_INLINE_WRAPPERS
|
#define WIDL_C_INLINE_WRAPPERS
|
||||||
#include <vkd3d_windows.h>
|
#include <vkd3d_windows.h>
|
||||||
|
|
||||||
/* Vulkan headers include static const declarations. Enable static keyword for
|
|
||||||
* them.
|
|
||||||
*/
|
|
||||||
#ifdef __MINGW32__
|
|
||||||
# undef static
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define VK_USE_PLATFORM_WIN32_KHR
|
#define VK_USE_PLATFORM_WIN32_KHR
|
||||||
#include <vulkan/vulkan.h>
|
#include <vulkan/vulkan.h>
|
||||||
#include "private/vulkan_private_extensions.h"
|
|
||||||
|
|
||||||
#ifdef __MINGW32__
|
|
||||||
# define static
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <dxgi1_6.h>
|
#include <dxgi1_6.h>
|
||||||
|
|
||||||
|
@ -69,8 +57,6 @@
|
||||||
#define __vkd3d_dxgi1_4_h__
|
#define __vkd3d_dxgi1_4_h__
|
||||||
|
|
||||||
#include <vkd3d_swapchain_factory.h>
|
#include <vkd3d_swapchain_factory.h>
|
||||||
#include <vkd3d_command_list_vkd3d_ext.h>
|
|
||||||
#include <vkd3d_device_vkd3d_ext.h>
|
|
||||||
#include <vkd3d_d3d12.h>
|
#include <vkd3d_d3d12.h>
|
||||||
#include <vkd3d_d3d12sdklayers.h>
|
#include <vkd3d_d3d12sdklayers.h>
|
||||||
|
|
||||||
|
|
|
@ -88,9 +88,6 @@ typedef void *HANDLE;
|
||||||
|
|
||||||
typedef const WCHAR* LPCWSTR;
|
typedef const WCHAR* LPCWSTR;
|
||||||
|
|
||||||
#define _fseeki64(a, b, c) fseeko64(a, b, c)
|
|
||||||
#define _ftelli64(a) ftello64(a)
|
|
||||||
|
|
||||||
/* GUID */
|
/* GUID */
|
||||||
# ifdef __WIDL__
|
# ifdef __WIDL__
|
||||||
typedef struct
|
typedef struct
|
||||||
|
|
|
@ -3,9 +3,9 @@ LIBRARY d3d12.dll
|
||||||
EXPORTS
|
EXPORTS
|
||||||
D3D12CreateDevice @101
|
D3D12CreateDevice @101
|
||||||
D3D12GetDebugInterface @102
|
D3D12GetDebugInterface @102
|
||||||
D3D12CreateRootSignatureDeserializer
|
D3D12CreateRootSignatureDeserializer @107
|
||||||
D3D12CreateVersionedRootSignatureDeserializer
|
D3D12CreateVersionedRootSignatureDeserializer @108
|
||||||
|
|
||||||
D3D12EnableExperimentalFeatures
|
D3D12EnableExperimentalFeatures @110
|
||||||
D3D12SerializeRootSignature
|
D3D12SerializeRootSignature @115
|
||||||
D3D12SerializeVersionedRootSignature
|
D3D12SerializeVersionedRootSignature @116
|
||||||
|
|
|
@ -159,10 +159,44 @@ done:
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VkPhysicalDevice d3d12_find_physical_device(struct vkd3d_instance *instance,
|
static BOOL check_vk_instance_extension(VkInstance vk_instance,
|
||||||
|
PFN_vkGetInstanceProcAddr pfn_vkGetInstanceProcAddr, const char *name)
|
||||||
|
{
|
||||||
|
PFN_vkEnumerateInstanceExtensionProperties pfn_vkEnumerateInstanceExtensionProperties;
|
||||||
|
VkExtensionProperties *properties;
|
||||||
|
BOOL ret = FALSE;
|
||||||
|
unsigned int i;
|
||||||
|
uint32_t count;
|
||||||
|
|
||||||
|
pfn_vkEnumerateInstanceExtensionProperties
|
||||||
|
= (void *)pfn_vkGetInstanceProcAddr(vk_instance, "vkEnumerateInstanceExtensionProperties");
|
||||||
|
|
||||||
|
if (pfn_vkEnumerateInstanceExtensionProperties(NULL, &count, NULL) < 0)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (!(properties = calloc(count, sizeof(*properties))))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (pfn_vkEnumerateInstanceExtensionProperties(NULL, &count, properties) >= 0)
|
||||||
|
{
|
||||||
|
for (i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
if (!strcmp(properties[i].extensionName, name))
|
||||||
|
{
|
||||||
|
ret = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(properties);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static VkPhysicalDevice d3d12_get_vk_physical_device(struct vkd3d_instance *instance,
|
||||||
PFN_vkGetInstanceProcAddr pfn_vkGetInstanceProcAddr, struct DXGI_ADAPTER_DESC *adapter_desc)
|
PFN_vkGetInstanceProcAddr pfn_vkGetInstanceProcAddr, struct DXGI_ADAPTER_DESC *adapter_desc)
|
||||||
{
|
{
|
||||||
PFN_vkGetPhysicalDeviceProperties2 pfn_vkGetPhysicalDeviceProperties2;
|
PFN_vkGetPhysicalDeviceProperties2 pfn_vkGetPhysicalDeviceProperties2 = NULL;
|
||||||
PFN_vkGetPhysicalDeviceProperties pfn_vkGetPhysicalDeviceProperties;
|
PFN_vkGetPhysicalDeviceProperties pfn_vkGetPhysicalDeviceProperties;
|
||||||
PFN_vkEnumeratePhysicalDevices pfn_vkEnumeratePhysicalDevices;
|
PFN_vkEnumeratePhysicalDevices pfn_vkEnumeratePhysicalDevices;
|
||||||
VkPhysicalDevice vk_physical_device = VK_NULL_HANDLE;
|
VkPhysicalDevice vk_physical_device = VK_NULL_HANDLE;
|
||||||
|
@ -177,8 +211,10 @@ static VkPhysicalDevice d3d12_find_physical_device(struct vkd3d_instance *instan
|
||||||
vk_instance = vkd3d_instance_get_vk_instance(instance);
|
vk_instance = vkd3d_instance_get_vk_instance(instance);
|
||||||
|
|
||||||
pfn_vkEnumeratePhysicalDevices = (void *)pfn_vkGetInstanceProcAddr(vk_instance, "vkEnumeratePhysicalDevices");
|
pfn_vkEnumeratePhysicalDevices = (void *)pfn_vkGetInstanceProcAddr(vk_instance, "vkEnumeratePhysicalDevices");
|
||||||
|
|
||||||
pfn_vkGetPhysicalDeviceProperties = (void *)pfn_vkGetInstanceProcAddr(vk_instance, "vkGetPhysicalDeviceProperties");
|
pfn_vkGetPhysicalDeviceProperties = (void *)pfn_vkGetInstanceProcAddr(vk_instance, "vkGetPhysicalDeviceProperties");
|
||||||
pfn_vkGetPhysicalDeviceProperties2 = (void *)pfn_vkGetInstanceProcAddr(vk_instance, "vkGetPhysicalDeviceProperties2");
|
if (check_vk_instance_extension(vk_instance, pfn_vkGetInstanceProcAddr, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME))
|
||||||
|
pfn_vkGetPhysicalDeviceProperties2 = (void *)pfn_vkGetInstanceProcAddr(vk_instance, "vkGetPhysicalDeviceProperties2KHR");
|
||||||
|
|
||||||
if ((vr = pfn_vkEnumeratePhysicalDevices(vk_instance, &count, NULL)) < 0)
|
if ((vr = pfn_vkEnumeratePhysicalDevices(vk_instance, &count, NULL)) < 0)
|
||||||
{
|
{
|
||||||
|
@ -197,36 +233,28 @@ static VkPhysicalDevice d3d12_find_physical_device(struct vkd3d_instance *instan
|
||||||
if ((vr = pfn_vkEnumeratePhysicalDevices(vk_instance, &count, vk_physical_devices)) < 0)
|
if ((vr = pfn_vkEnumeratePhysicalDevices(vk_instance, &count, vk_physical_devices)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
|
if (pfn_vkGetPhysicalDeviceProperties2)
|
||||||
|
{
|
||||||
TRACE("Matching adapters by LUIDs.\n");
|
TRACE("Matching adapters by LUIDs.\n");
|
||||||
|
|
||||||
for (i = 0; i < count; ++i)
|
for (i = 0; i < count; ++i)
|
||||||
{
|
{
|
||||||
pfn_vkGetPhysicalDeviceProperties(vk_physical_devices[i], &properties2.properties);
|
memset(&id_properties, 0, sizeof(id_properties));
|
||||||
|
|
||||||
/* Skip over physical devices below our minimum API version */
|
|
||||||
if (properties2.properties.apiVersion < VKD3D_MIN_API_VERSION)
|
|
||||||
{
|
|
||||||
WARN("Skipped adapter %s as it is below our minimum API version.", properties2.properties.deviceName);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
id_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES;
|
id_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES;
|
||||||
id_properties.pNext = NULL;
|
|
||||||
|
|
||||||
properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
|
properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
|
||||||
properties2.pNext = &id_properties;
|
properties2.pNext = &id_properties;
|
||||||
|
|
||||||
pfn_vkGetPhysicalDeviceProperties2(vk_physical_devices[i], &properties2);
|
pfn_vkGetPhysicalDeviceProperties2(vk_physical_devices[i], &properties2);
|
||||||
|
|
||||||
if (id_properties.deviceLUIDValid && !memcmp(id_properties.deviceLUID, &adapter_desc->AdapterLuid, VK_LUID_SIZE))
|
if (!memcmp(id_properties.deviceLUID, &adapter_desc->AdapterLuid, VK_LUID_SIZE))
|
||||||
{
|
{
|
||||||
vk_physical_device = vk_physical_devices[i];
|
vk_physical_device = vk_physical_devices[i];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!vk_physical_device)
|
|
||||||
{
|
|
||||||
TRACE("Matching adapters by PCI IDs.\n");
|
TRACE("Matching adapters by PCI IDs.\n");
|
||||||
|
|
||||||
for (i = 0; i < count; ++i)
|
for (i = 0; i < count; ++i)
|
||||||
|
@ -240,7 +268,6 @@ static VkPhysicalDevice d3d12_find_physical_device(struct vkd3d_instance *instan
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!vk_physical_device)
|
if (!vk_physical_device)
|
||||||
{
|
{
|
||||||
|
@ -257,6 +284,7 @@ done:
|
||||||
HRESULT WINAPI DLLEXPORT D3D12CreateDevice(IUnknown *adapter, D3D_FEATURE_LEVEL minimum_feature_level,
|
HRESULT WINAPI DLLEXPORT D3D12CreateDevice(IUnknown *adapter, D3D_FEATURE_LEVEL minimum_feature_level,
|
||||||
REFIID iid, void **device)
|
REFIID iid, void **device)
|
||||||
{
|
{
|
||||||
|
struct vkd3d_optional_instance_extensions_info optional_extensions_info;
|
||||||
struct vkd3d_instance_create_info instance_create_info;
|
struct vkd3d_instance_create_info instance_create_info;
|
||||||
PFN_vkGetInstanceProcAddr pfn_vkGetInstanceProcAddr;
|
PFN_vkGetInstanceProcAddr pfn_vkGetInstanceProcAddr;
|
||||||
struct vkd3d_device_create_info device_create_info;
|
struct vkd3d_device_create_info device_create_info;
|
||||||
|
@ -270,6 +298,10 @@ HRESULT WINAPI DLLEXPORT D3D12CreateDevice(IUnknown *adapter, D3D_FEATURE_LEVEL
|
||||||
VK_KHR_SURFACE_EXTENSION_NAME,
|
VK_KHR_SURFACE_EXTENSION_NAME,
|
||||||
VK_KHR_WIN32_SURFACE_EXTENSION_NAME,
|
VK_KHR_WIN32_SURFACE_EXTENSION_NAME,
|
||||||
};
|
};
|
||||||
|
static const char * const optional_instance_extensions[] =
|
||||||
|
{
|
||||||
|
VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
|
||||||
|
};
|
||||||
static const char * const device_extensions[] =
|
static const char * const device_extensions[] =
|
||||||
{
|
{
|
||||||
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
|
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
|
||||||
|
@ -293,14 +325,20 @@ HRESULT WINAPI DLLEXPORT D3D12CreateDevice(IUnknown *adapter, D3D_FEATURE_LEVEL
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
optional_extensions_info.type = VKD3D_STRUCTURE_TYPE_OPTIONAL_INSTANCE_EXTENSIONS_INFO;
|
||||||
|
optional_extensions_info.next = NULL;
|
||||||
|
optional_extensions_info.extensions = optional_instance_extensions;
|
||||||
|
optional_extensions_info.extension_count = ARRAYSIZE(optional_instance_extensions);
|
||||||
|
|
||||||
|
instance_create_info.type = VKD3D_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
||||||
|
instance_create_info.next = &optional_extensions_info;
|
||||||
instance_create_info.pfn_signal_event = d3d12_signal_event;
|
instance_create_info.pfn_signal_event = d3d12_signal_event;
|
||||||
instance_create_info.pfn_create_thread = d3d12_create_thread;
|
instance_create_info.pfn_create_thread = d3d12_create_thread;
|
||||||
instance_create_info.pfn_join_thread = d3d12_join_thread;
|
instance_create_info.pfn_join_thread = d3d12_join_thread;
|
||||||
|
instance_create_info.wchar_size = sizeof(WCHAR);
|
||||||
instance_create_info.pfn_vkGetInstanceProcAddr = pfn_vkGetInstanceProcAddr;
|
instance_create_info.pfn_vkGetInstanceProcAddr = pfn_vkGetInstanceProcAddr;
|
||||||
instance_create_info.instance_extensions = instance_extensions;
|
instance_create_info.instance_extensions = instance_extensions;
|
||||||
instance_create_info.instance_extension_count = ARRAYSIZE(instance_extensions);
|
instance_create_info.instance_extension_count = ARRAYSIZE(instance_extensions);
|
||||||
instance_create_info.optional_instance_extensions = NULL;
|
|
||||||
instance_create_info.optional_instance_extension_count = 0;
|
|
||||||
|
|
||||||
if (FAILED(hr = vkd3d_create_instance(&instance_create_info, &instance)))
|
if (FAILED(hr = vkd3d_create_instance(&instance_create_info, &instance)))
|
||||||
{
|
{
|
||||||
|
@ -308,14 +346,14 @@ HRESULT WINAPI DLLEXPORT D3D12CreateDevice(IUnknown *adapter, D3D_FEATURE_LEVEL
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
device_create_info.type = VKD3D_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
|
||||||
|
device_create_info.next = NULL;
|
||||||
device_create_info.minimum_feature_level = minimum_feature_level;
|
device_create_info.minimum_feature_level = minimum_feature_level;
|
||||||
device_create_info.instance = instance;
|
device_create_info.instance = instance;
|
||||||
device_create_info.instance_create_info = NULL;
|
device_create_info.instance_create_info = NULL;
|
||||||
device_create_info.vk_physical_device = d3d12_find_physical_device(instance, pfn_vkGetInstanceProcAddr, &adapter_desc);
|
device_create_info.vk_physical_device = d3d12_get_vk_physical_device(instance, pfn_vkGetInstanceProcAddr, &adapter_desc);
|
||||||
device_create_info.device_extensions = device_extensions;
|
device_create_info.device_extensions = device_extensions;
|
||||||
device_create_info.device_extension_count = ARRAYSIZE(device_extensions);
|
device_create_info.device_extension_count = ARRAYSIZE(device_extensions);
|
||||||
device_create_info.optional_device_extensions = NULL;
|
|
||||||
device_create_info.optional_device_extension_count = 0;
|
|
||||||
device_create_info.parent = (IUnknown *)dxgi_adapter;
|
device_create_info.parent = (IUnknown *)dxgi_adapter;
|
||||||
memcpy(&device_create_info.adapter_luid, &adapter_desc.AdapterLuid, VK_LUID_SIZE);
|
memcpy(&device_create_info.adapter_luid, &adapter_desc.AdapterLuid, VK_LUID_SIZE);
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ d3d12_lib = shared_library('d3d12', d3d12_src,
|
||||||
dependencies : [ vkd3d_dep, lib_dxgi ],
|
dependencies : [ vkd3d_dep, lib_dxgi ],
|
||||||
include_directories : vkd3d_private_includes,
|
include_directories : vkd3d_private_includes,
|
||||||
install : true,
|
install : true,
|
||||||
objects : not vkd3d_is_msvc ? 'd3d12.def' : [],
|
objects : not vkd3d_msvc ? 'd3d12.def' : [],
|
||||||
vs_module_defs : 'd3d12.def',
|
vs_module_defs : 'd3d12.def',
|
||||||
override_options : [ 'c_std='+vkd3d_c_std ])
|
override_options : [ 'c_std='+vkd3d_c_std ])
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,6 @@
|
||||||
#include "vkd3d_debug.h"
|
#include "vkd3d_debug.h"
|
||||||
#include "vkd3d_threads.h"
|
#include "vkd3d_threads.h"
|
||||||
|
|
||||||
#include "vkd3d_platform.h"
|
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
@ -60,13 +58,13 @@ static FILE *vkd3d_log_file;
|
||||||
|
|
||||||
static void vkd3d_dbg_init_once(void)
|
static void vkd3d_dbg_init_once(void)
|
||||||
{
|
{
|
||||||
char vkd3d_debug[VKD3D_PATH_MAX];
|
const char *vkd3d_debug;
|
||||||
unsigned int channel, i;
|
unsigned int channel, i;
|
||||||
|
|
||||||
for (channel = 0; channel < VKD3D_DBG_CHANNEL_COUNT; channel++)
|
for (channel = 0; channel < VKD3D_DBG_CHANNEL_COUNT; channel++)
|
||||||
{
|
{
|
||||||
if (!vkd3d_get_env_var(env_for_channel[channel], vkd3d_debug, sizeof(vkd3d_debug)))
|
if (!(vkd3d_debug = getenv(env_for_channel[channel])))
|
||||||
strncpy(vkd3d_debug, "", VKD3D_PATH_MAX);
|
vkd3d_debug = "";
|
||||||
|
|
||||||
for (i = 1; i < ARRAY_SIZE(debug_level_names); ++i)
|
for (i = 1; i < ARRAY_SIZE(debug_level_names); ++i)
|
||||||
if (!strcmp(debug_level_names[i], vkd3d_debug))
|
if (!strcmp(debug_level_names[i], vkd3d_debug))
|
||||||
|
@ -77,7 +75,7 @@ static void vkd3d_dbg_init_once(void)
|
||||||
vkd3d_dbg_level[channel] = VKD3D_DBG_LEVEL_FIXME;
|
vkd3d_dbg_level[channel] = VKD3D_DBG_LEVEL_FIXME;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vkd3d_get_env_var("VKD3D_LOG_FILE", vkd3d_debug, sizeof(vkd3d_debug)))
|
if ((vkd3d_debug = getenv("VKD3D_LOG_FILE")))
|
||||||
{
|
{
|
||||||
vkd3d_log_file = fopen(vkd3d_debug, "w");
|
vkd3d_log_file = fopen(vkd3d_debug, "w");
|
||||||
if (!vkd3d_log_file)
|
if (!vkd3d_log_file)
|
||||||
|
@ -123,7 +121,7 @@ void vkd3d_dbg_printf(enum vkd3d_dbg_channel channel, enum vkd3d_dbg_level level
|
||||||
|
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
spinlock_acquire(&spin);
|
spinlock_acquire(&spin);
|
||||||
fprintf(log_file, "%04x:%s:%s: ", tid, debug_level_names[level], function);
|
fprintf(log_file, "%u:%s:%s: ", tid, debug_level_names[level], function);
|
||||||
vfprintf(log_file, fmt, args);
|
vfprintf(log_file, fmt, args);
|
||||||
spinlock_release(&spin);
|
spinlock_release(&spin);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
@ -221,10 +219,10 @@ const char *debugstr_a(const char *str)
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *debugstr_w(const WCHAR *wstr)
|
static const char *debugstr_w16(const uint16_t *wstr)
|
||||||
{
|
{
|
||||||
char *buffer, *ptr;
|
char *buffer, *ptr;
|
||||||
WCHAR c;
|
uint16_t c;
|
||||||
|
|
||||||
if (!wstr)
|
if (!wstr)
|
||||||
return "(null)";
|
return "(null)";
|
||||||
|
@ -281,13 +279,80 @@ const char *debugstr_w(const WCHAR *wstr)
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char *debugstr_w32(const uint32_t *wstr)
|
||||||
|
{
|
||||||
|
char *buffer, *ptr;
|
||||||
|
uint32_t c;
|
||||||
|
|
||||||
|
if (!wstr)
|
||||||
|
return "(null)";
|
||||||
|
|
||||||
|
ptr = buffer = get_buffer();
|
||||||
|
|
||||||
|
*ptr++ = '"';
|
||||||
|
while ((c = *wstr++) && ptr <= buffer + VKD3D_DEBUG_BUFFER_SIZE - 10)
|
||||||
|
{
|
||||||
|
int escape_char;
|
||||||
|
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case '"':
|
||||||
|
case '\\':
|
||||||
|
case '\n':
|
||||||
|
case '\r':
|
||||||
|
case '\t':
|
||||||
|
escape_char = c;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
escape_char = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (escape_char)
|
||||||
|
{
|
||||||
|
*ptr++ = '\\';
|
||||||
|
*ptr++ = escape_char;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isprint(c))
|
||||||
|
{
|
||||||
|
*ptr++ = c;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*ptr++ = '\\';
|
||||||
|
sprintf(ptr, "%04x", c);
|
||||||
|
ptr += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*ptr++ = '"';
|
||||||
|
|
||||||
|
if (c)
|
||||||
|
{
|
||||||
|
*ptr++ = '.';
|
||||||
|
*ptr++ = '.';
|
||||||
|
*ptr++ = '.';
|
||||||
|
}
|
||||||
|
*ptr = '\0';
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *debugstr_w(const WCHAR *wstr, size_t wchar_size)
|
||||||
|
{
|
||||||
|
if (wchar_size == 2)
|
||||||
|
return debugstr_w16((const uint16_t *)wstr);
|
||||||
|
return debugstr_w32((const uint32_t *)wstr);
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int vkd3d_env_var_as_uint(const char *name, unsigned int default_value)
|
unsigned int vkd3d_env_var_as_uint(const char *name, unsigned int default_value)
|
||||||
{
|
{
|
||||||
char value[VKD3D_PATH_MAX];
|
const char *value = getenv(name);
|
||||||
unsigned long r;
|
unsigned long r;
|
||||||
char *end_ptr;
|
char *end_ptr;
|
||||||
|
|
||||||
if (vkd3d_get_env_var(name, value, sizeof(value)) && strlen(value) > 0)
|
if (value)
|
||||||
{
|
{
|
||||||
errno = 0;
|
errno = 0;
|
||||||
r = strtoul(value, &end_ptr, 0);
|
r = strtoul(value, &end_ptr, 0);
|
||||||
|
|
|
@ -1,188 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2022 Hans-Kristian Arntzen for Valve Corporation
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define VKD3D_DBG_CHANNEL VKD3D_DBG_CHANNEL_API
|
|
||||||
|
|
||||||
#include "vkd3d_file_utils.h"
|
|
||||||
#include "vkd3d_debug.h"
|
|
||||||
|
|
||||||
/* For disk cache. */
|
|
||||||
#ifdef _WIN32
|
|
||||||
#include <windows.h>
|
|
||||||
#include <io.h>
|
|
||||||
#else
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
bool vkd3d_file_rename_overwrite(const char *from_path, const char *to_path)
|
|
||||||
{
|
|
||||||
#ifdef _WIN32
|
|
||||||
DWORD code = ERROR_SUCCESS;
|
|
||||||
|
|
||||||
if (!MoveFileA(from_path, to_path))
|
|
||||||
{
|
|
||||||
code = GetLastError();
|
|
||||||
if (code == ERROR_ALREADY_EXISTS)
|
|
||||||
{
|
|
||||||
code = ERROR_SUCCESS;
|
|
||||||
if (!ReplaceFileA(to_path, from_path, NULL, 0, NULL, NULL))
|
|
||||||
code = GetLastError();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return code == ERROR_SUCCESS;
|
|
||||||
#else
|
|
||||||
return rename(from_path, to_path) == 0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
bool vkd3d_file_rename_no_replace(const char *from_path, const char *to_path)
|
|
||||||
{
|
|
||||||
#ifdef _WIN32
|
|
||||||
DWORD code = ERROR_SUCCESS;
|
|
||||||
if (!MoveFileA(from_path, to_path))
|
|
||||||
code = GetLastError();
|
|
||||||
return code == ERROR_SUCCESS;
|
|
||||||
#else
|
|
||||||
return renameat2(AT_FDCWD, from_path, AT_FDCWD, to_path, RENAME_NOREPLACE) == 0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
bool vkd3d_file_delete(const char *path)
|
|
||||||
{
|
|
||||||
#ifdef _WIN32
|
|
||||||
DWORD code = ERROR_SUCCESS;
|
|
||||||
if (!DeleteFileA(path))
|
|
||||||
code = GetLastError();
|
|
||||||
return code == ERROR_SUCCESS;
|
|
||||||
#else
|
|
||||||
return unlink(path) == 0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
FILE *vkd3d_file_open_exclusive_write(const char *path)
|
|
||||||
{
|
|
||||||
#ifdef _WIN32
|
|
||||||
/* From Fossilize. AFAIK, there is no direct way to make this work with FILE interface, so have to roundtrip
|
|
||||||
* through jank POSIX layer.
|
|
||||||
* wbx kinda works, but Wine warns about it, despite it working anyways.
|
|
||||||
* Older MSVC runtimes do not support wbx. */
|
|
||||||
FILE *file = NULL;
|
|
||||||
int fd;
|
|
||||||
fd = _open(path, _O_BINARY | _O_WRONLY | _O_CREAT | _O_EXCL | _O_TRUNC | _O_SEQUENTIAL,
|
|
||||||
_S_IWRITE | _S_IREAD);
|
|
||||||
if (fd >= 0)
|
|
||||||
{
|
|
||||||
file = _fdopen(fd, "wb");
|
|
||||||
/* _fdopen takes ownership. */
|
|
||||||
if (!file)
|
|
||||||
_close(fd);
|
|
||||||
}
|
|
||||||
return file;
|
|
||||||
#else
|
|
||||||
return fopen(path, "wbx");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void vkd3d_file_unmap(struct vkd3d_memory_mapped_file *file)
|
|
||||||
{
|
|
||||||
if (file->mapped)
|
|
||||||
{
|
|
||||||
#ifdef _WIN32
|
|
||||||
UnmapViewOfFile(file->mapped);
|
|
||||||
#else
|
|
||||||
munmap(file->mapped, file->mapped_size);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
memset(file, 0, sizeof(*file));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool vkd3d_file_map_read_only(const char *path, struct vkd3d_memory_mapped_file *file)
|
|
||||||
{
|
|
||||||
#ifdef _WIN32
|
|
||||||
DWORD size_hi, size_lo;
|
|
||||||
HANDLE file_mapping;
|
|
||||||
HANDLE handle;
|
|
||||||
#else
|
|
||||||
struct stat stat_buf;
|
|
||||||
int fd;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
file->mapped = NULL;
|
|
||||||
file->mapped_size = 0;
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
handle = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL,
|
|
||||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
|
|
||||||
INVALID_HANDLE_VALUE);
|
|
||||||
if (handle == INVALID_HANDLE_VALUE)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
size_lo = GetFileSize(handle, &size_hi);
|
|
||||||
file->mapped_size = size_lo | (((uint64_t)size_hi) << 32);
|
|
||||||
|
|
||||||
file_mapping = CreateFileMappingA(handle, NULL, PAGE_READONLY, 0, 0, NULL);
|
|
||||||
if (file_mapping == INVALID_HANDLE_VALUE)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
file->mapped = MapViewOfFile(file_mapping, FILE_MAP_READ, 0, 0, file->mapped_size);
|
|
||||||
CloseHandle(file_mapping);
|
|
||||||
file_mapping = INVALID_HANDLE_VALUE;
|
|
||||||
if (!file->mapped)
|
|
||||||
{
|
|
||||||
ERR("Failed to MapViewOfFile for %s.\n", path);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
|
||||||
if (handle != INVALID_HANDLE_VALUE)
|
|
||||||
CloseHandle(handle);
|
|
||||||
#else
|
|
||||||
fd = open(path, O_RDONLY);
|
|
||||||
if (fd < 0)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
if (fstat(fd, &stat_buf) < 0)
|
|
||||||
{
|
|
||||||
ERR("Failed to fstat pipeline cache.\n");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Map private to make sure we get CoW behavior in case someone clobbers
|
|
||||||
* the cache while in flight. We need to read data directly out of the cache. */
|
|
||||||
file->mapped = mmap(NULL, stat_buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
|
|
||||||
if (file->mapped != MAP_FAILED)
|
|
||||||
file->mapped_size = stat_buf.st_size;
|
|
||||||
else
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
out:
|
|
||||||
if (fd >= 0)
|
|
||||||
close(fd);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!file->mapped)
|
|
||||||
file->mapped_size = 0;
|
|
||||||
return file->mapped != NULL;
|
|
||||||
}
|
|
|
@ -2,10 +2,7 @@ vkd3d_common_src = [
|
||||||
'debug.c',
|
'debug.c',
|
||||||
'memory.c',
|
'memory.c',
|
||||||
'utf8.c',
|
'utf8.c',
|
||||||
'profiling.c',
|
'profiling.c'
|
||||||
'string.c',
|
|
||||||
'file_utils.c',
|
|
||||||
'platform.c',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
vkd3d_common_lib = static_library('vkd3d_common', vkd3d_common_src, vkd3d_header_files,
|
vkd3d_common_lib = static_library('vkd3d_common', vkd3d_common_src, vkd3d_header_files,
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
#define VKD3D_DBG_CHANNEL VKD3D_DBG_CHANNEL_API
|
#define VKD3D_DBG_CHANNEL VKD3D_DBG_CHANNEL_API
|
||||||
|
|
||||||
#include "vkd3d_profiling.h"
|
#include "vkd3d_profiling.h"
|
||||||
#include "vkd3d_platform.h"
|
|
||||||
#include "vkd3d_threads.h"
|
#include "vkd3d_threads.h"
|
||||||
#include "vkd3d_debug.h"
|
#include "vkd3d_debug.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -125,10 +124,8 @@ static void vkd3d_init_profiling_path(const char *path)
|
||||||
|
|
||||||
static void vkd3d_init_profiling_once(void)
|
static void vkd3d_init_profiling_once(void)
|
||||||
{
|
{
|
||||||
char path[VKD3D_PATH_MAX];
|
const char *path = getenv("VKD3D_PROFILE_PATH");
|
||||||
|
if (path)
|
||||||
vkd3d_get_env_var("VKD3D_PROFILE_PATH", path, sizeof(path));
|
|
||||||
if (strlen(path) > 0)
|
|
||||||
vkd3d_init_profiling_path(path);
|
vkd3d_init_profiling_path(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,176 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2021 Hans-Kristian Arntzen for Valve Corporation
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define VKD3D_DBG_CHANNEL VKD3D_DBG_CHANNEL_API
|
|
||||||
|
|
||||||
#include "vkd3d_string.h"
|
|
||||||
#include "vkd3d_memory.h"
|
|
||||||
|
|
||||||
STATIC_ASSERT(sizeof(WCHAR) == sizeof(uint16_t));
|
|
||||||
|
|
||||||
char *vkd3d_strdup(const char *str)
|
|
||||||
{
|
|
||||||
/* strdup() is actually not standard. */
|
|
||||||
char *duped;
|
|
||||||
size_t len;
|
|
||||||
|
|
||||||
len = strlen(str) + 1;
|
|
||||||
|
|
||||||
duped = vkd3d_malloc(len);
|
|
||||||
if (duped)
|
|
||||||
memcpy(duped, str, len);
|
|
||||||
return duped;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *vkd3d_strdup_n(const char *str, size_t n)
|
|
||||||
{
|
|
||||||
char *duped;
|
|
||||||
size_t len;
|
|
||||||
|
|
||||||
len = strnlen(str, n);
|
|
||||||
|
|
||||||
duped = vkd3d_malloc(len + 1);
|
|
||||||
if (duped)
|
|
||||||
{
|
|
||||||
memcpy(duped, str, len);
|
|
||||||
duped[len] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
return duped;
|
|
||||||
}
|
|
||||||
|
|
||||||
WCHAR *vkd3d_wstrdup(const WCHAR *str)
|
|
||||||
{
|
|
||||||
WCHAR *duped;
|
|
||||||
size_t len;
|
|
||||||
|
|
||||||
len = vkd3d_wcslen(str) + 1;
|
|
||||||
|
|
||||||
duped = vkd3d_malloc(len * sizeof(WCHAR));
|
|
||||||
if (duped)
|
|
||||||
memcpy(duped, str, len * sizeof(WCHAR));
|
|
||||||
return duped;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool vkd3d_export_strequal(const WCHAR *a, const WCHAR *b)
|
|
||||||
{
|
|
||||||
if (!a || !b)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
while (*a != '\0' && *b != '\0')
|
|
||||||
{
|
|
||||||
if (*a != *b)
|
|
||||||
return false;
|
|
||||||
a++;
|
|
||||||
b++;
|
|
||||||
}
|
|
||||||
return *a == *b;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool vkd3d_export_strequal_mixed(const WCHAR *a, const char *b)
|
|
||||||
{
|
|
||||||
if (!a || !b)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
while (*a != '\0' && *b != '\0')
|
|
||||||
{
|
|
||||||
if (*a != *b)
|
|
||||||
return false;
|
|
||||||
a++;
|
|
||||||
b++;
|
|
||||||
}
|
|
||||||
return *a == *b;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool vkd3d_export_strequal_substr(const WCHAR *a, size_t expected_n, const WCHAR *b)
|
|
||||||
{
|
|
||||||
size_t n = 0;
|
|
||||||
|
|
||||||
if (!a || !b)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
while (*a != '\0' && *b != '\0' && n < expected_n)
|
|
||||||
{
|
|
||||||
if (*a != *b)
|
|
||||||
return false;
|
|
||||||
a++;
|
|
||||||
b++;
|
|
||||||
n++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return n == expected_n && *b == '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
WCHAR *vkd3d_dup_entry_point(const char *str)
|
|
||||||
{
|
|
||||||
return vkd3d_dup_entry_point_n(str, strlen(str));
|
|
||||||
}
|
|
||||||
|
|
||||||
WCHAR *vkd3d_dup_entry_point_n(const char *str, size_t len)
|
|
||||||
{
|
|
||||||
WCHAR *duped;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
duped = vkd3d_malloc((len + 1) * sizeof(WCHAR));
|
|
||||||
if (!duped)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
for (i = 0; i < len; i++)
|
|
||||||
duped[i] = (unsigned char)str[i];
|
|
||||||
duped[len] = 0;
|
|
||||||
return duped;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool is_valid_identifier_character(char v)
|
|
||||||
{
|
|
||||||
return (v >= 'a' && v <= 'z') || (v >= 'A' && v <= 'Z') || v == '_' || (v >= '0' && v <= '9');
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char *vkd3d_manged_entry_point_scan(const char *entry, const char **out_end_entry)
|
|
||||||
{
|
|
||||||
const char *end_entry;
|
|
||||||
|
|
||||||
while (*entry != '\0' && !is_valid_identifier_character(*entry))
|
|
||||||
entry++;
|
|
||||||
|
|
||||||
end_entry = entry;
|
|
||||||
while (*end_entry != '\0' && is_valid_identifier_character(*end_entry))
|
|
||||||
end_entry++;
|
|
||||||
|
|
||||||
if (entry == end_entry)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
*out_end_entry = end_entry;
|
|
||||||
return entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
WCHAR *vkd3d_dup_demangled_entry_point(const char *entry)
|
|
||||||
{
|
|
||||||
const char *end_entry;
|
|
||||||
if (!(entry = vkd3d_manged_entry_point_scan(entry, &end_entry)))
|
|
||||||
return NULL;
|
|
||||||
return vkd3d_dup_entry_point_n(entry, end_entry - entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
char *vkd3d_dup_demangled_entry_point_ascii(const char *entry)
|
|
||||||
{
|
|
||||||
const char *end_entry;
|
|
||||||
if (!(entry = vkd3d_manged_entry_point_scan(entry, &end_entry)))
|
|
||||||
return NULL;
|
|
||||||
return vkd3d_strdup_n(entry, end_entry - entry);
|
|
||||||
}
|
|
|
@ -84,9 +84,9 @@ static void vkd3d_utf8_append(char **dst, uint32_t c)
|
||||||
*dst += 4;
|
*dst += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t vkd3d_utf16_read(const WCHAR **src)
|
static uint32_t vkd3d_utf16_read(const uint16_t **src)
|
||||||
{
|
{
|
||||||
const WCHAR *s = *src;
|
const uint16_t *s = *src;
|
||||||
|
|
||||||
if (s[0] < 0xd800 || s[0] > 0xdfff) /* Not a surrogate pair. */
|
if (s[0] < 0xd800 || s[0] > 0xdfff) /* Not a surrogate pair. */
|
||||||
{
|
{
|
||||||
|
@ -105,15 +105,21 @@ static uint32_t vkd3d_utf16_read(const WCHAR **src)
|
||||||
return 0x10000 + ((s[0] & 0x3ff) << 10) + (s[1] & 0x3ff);
|
return 0x10000 + ((s[0] & 0x3ff) << 10) + (s[1] & 0x3ff);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool vkd3d_string_should_loop_u16(ptrdiff_t max_elements, const WCHAR* src, const WCHAR* wstr)
|
static inline bool vkd3d_string_should_loop_u16(ptrdiff_t max_elements, const uint16_t* src, const uint16_t* wstr)
|
||||||
{
|
{
|
||||||
ptrdiff_t cursor_pos = src - wstr;
|
ptrdiff_t cursor_pos = src - wstr;
|
||||||
return (!max_elements || cursor_pos < max_elements) && *src;
|
return (!max_elements || cursor_pos < max_elements) && *src;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *vkd3d_strdup_w_utf8(const WCHAR *wstr, size_t max_elements)
|
static inline bool vkd3d_string_should_loop_u32(ptrdiff_t max_elements, const uint32_t* src, const uint32_t* wstr)
|
||||||
{
|
{
|
||||||
const WCHAR *src = wstr;
|
ptrdiff_t cursor_pos = src - wstr;
|
||||||
|
return (!max_elements || cursor_pos < max_elements) && *src;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *vkd3d_strdup_w16_utf8(const uint16_t *wstr, size_t max_elements)
|
||||||
|
{
|
||||||
|
const uint16_t *src = wstr;
|
||||||
size_t dst_size = 0;
|
size_t dst_size = 0;
|
||||||
char *dst, *utf8;
|
char *dst, *utf8;
|
||||||
uint32_t c;
|
uint32_t c;
|
||||||
|
@ -137,7 +143,36 @@ char *vkd3d_strdup_w_utf8(const WCHAR *wstr, size_t max_elements)
|
||||||
continue;
|
continue;
|
||||||
vkd3d_utf8_append(&utf8, c);
|
vkd3d_utf8_append(&utf8, c);
|
||||||
}
|
}
|
||||||
*utf8 = '\0';
|
*utf8 = 0;
|
||||||
|
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *vkd3d_strdup_w32_utf8(const uint32_t *wstr, size_t max_elements)
|
||||||
|
{
|
||||||
|
const uint32_t *src = wstr;
|
||||||
|
size_t dst_size = 0;
|
||||||
|
char *dst, *utf8;
|
||||||
|
|
||||||
|
while (vkd3d_string_should_loop_u32(max_elements, src, wstr))
|
||||||
|
dst_size += vkd3d_utf8_len(*src++);
|
||||||
|
++dst_size;
|
||||||
|
|
||||||
|
if (!(dst = vkd3d_malloc(dst_size)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
utf8 = dst;
|
||||||
|
src = wstr;
|
||||||
|
while (vkd3d_string_should_loop_u32(max_elements, src, wstr))
|
||||||
|
vkd3d_utf8_append(&utf8, *src++);
|
||||||
|
*utf8 = 0;
|
||||||
|
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *vkd3d_strdup_w_utf8(const WCHAR *wstr, size_t wchar_size, size_t max_elements)
|
||||||
|
{
|
||||||
|
if (wchar_size == 2)
|
||||||
|
return vkd3d_strdup_w16_utf8((const uint16_t *)wstr, max_elements);
|
||||||
|
return vkd3d_strdup_w32_utf8((const uint32_t *)wstr, max_elements);
|
||||||
|
}
|
||||||
|
|
|
@ -1346,7 +1346,6 @@ static const enum vkd3d_shader_register_type register_type_table[] =
|
||||||
/* VKD3D_SM5_RT_DEPTHOUT_LESS_EQUAL */ VKD3DSPR_DEPTHOUTLE,
|
/* VKD3D_SM5_RT_DEPTHOUT_LESS_EQUAL */ VKD3DSPR_DEPTHOUTLE,
|
||||||
/* UNKNOWN */ ~0u,
|
/* UNKNOWN */ ~0u,
|
||||||
/* VKD3D_SM5_RT_STENCILREFOUT */ VKD3DSPR_STENCILREFOUT,
|
/* VKD3D_SM5_RT_STENCILREFOUT */ VKD3DSPR_STENCILREFOUT,
|
||||||
/* VKD3D_SM5_RT_INNERCOVERAGE */ VKD3DSPR_INNERCOVERAGE,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct vkd3d_sm4_opcode_info *get_opcode_info(enum vkd3d_sm4_opcode opcode)
|
static const struct vkd3d_sm4_opcode_info *get_opcode_info(enum vkd3d_sm4_opcode opcode)
|
||||||
|
@ -2249,21 +2248,6 @@ static int isgn_handler(const char *data, DWORD data_size, DWORD tag, void *ctx)
|
||||||
return shader_parse_signature(tag, data, data_size, is);
|
return shader_parse_signature(tag, data, data_size, is);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int osgn_handler(const char *data, DWORD data_size, DWORD tag, void *ctx)
|
|
||||||
{
|
|
||||||
struct vkd3d_shader_signature *is = ctx;
|
|
||||||
|
|
||||||
if (tag != TAG_OSGN && tag != TAG_OSG1)
|
|
||||||
return VKD3D_OK;
|
|
||||||
|
|
||||||
if (is->elements)
|
|
||||||
{
|
|
||||||
FIXME("Multiple input signatures.\n");
|
|
||||||
vkd3d_shader_free_shader_signature(is);
|
|
||||||
}
|
|
||||||
return shader_parse_signature(tag, data, data_size, is);
|
|
||||||
}
|
|
||||||
|
|
||||||
int shader_parse_input_signature(const void *dxbc, size_t dxbc_length,
|
int shader_parse_input_signature(const void *dxbc, size_t dxbc_length,
|
||||||
struct vkd3d_shader_signature *signature)
|
struct vkd3d_shader_signature *signature)
|
||||||
{
|
{
|
||||||
|
@ -2275,17 +2259,6 @@ int shader_parse_input_signature(const void *dxbc, size_t dxbc_length,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int shader_parse_output_signature(const void *dxbc, size_t dxbc_length,
|
|
||||||
struct vkd3d_shader_signature *signature)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
memset(signature, 0, sizeof(*signature));
|
|
||||||
if ((ret = parse_dxbc(dxbc, dxbc_length, osgn_handler, signature)) < 0)
|
|
||||||
ERR("Failed to parse output signature.\n");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int dxil_handler(const char *data, DWORD data_size, DWORD tag, void *context)
|
static int dxil_handler(const char *data, DWORD data_size, DWORD tag, void *context)
|
||||||
{
|
{
|
||||||
switch (tag)
|
switch (tag)
|
||||||
|
@ -2453,8 +2426,7 @@ static void shader_validate_descriptor_range1(const struct vkd3d_descriptor_rang
|
||||||
| VKD3D_DESCRIPTOR_RANGE_FLAG_DESCRIPTORS_VOLATILE
|
| VKD3D_DESCRIPTOR_RANGE_FLAG_DESCRIPTORS_VOLATILE
|
||||||
| VKD3D_DESCRIPTOR_RANGE_FLAG_DATA_VOLATILE
|
| VKD3D_DESCRIPTOR_RANGE_FLAG_DATA_VOLATILE
|
||||||
| VKD3D_DESCRIPTOR_RANGE_FLAG_DATA_STATIC_WHILE_SET_AT_EXECUTE
|
| VKD3D_DESCRIPTOR_RANGE_FLAG_DATA_STATIC_WHILE_SET_AT_EXECUTE
|
||||||
| VKD3D_DESCRIPTOR_RANGE_FLAG_DATA_STATIC
|
| VKD3D_DESCRIPTOR_RANGE_FLAG_DATA_STATIC);
|
||||||
| VKD3D_DESCRIPTOR_RANGE_FLAG_DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS);
|
|
||||||
|
|
||||||
if (unknown_flags)
|
if (unknown_flags)
|
||||||
FIXME("Unknown descriptor range flags %#x.\n", unknown_flags);
|
FIXME("Unknown descriptor range flags %#x.\n", unknown_flags);
|
||||||
|
@ -2755,9 +2727,8 @@ static int shader_parse_static_samplers(struct root_signature_parser_context *co
|
||||||
return VKD3D_OK;
|
return VKD3D_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int vkd3d_shader_parse_root_signature_raw(const char *data, unsigned int data_size,
|
static int shader_parse_root_signature(const char *data, unsigned int data_size,
|
||||||
struct vkd3d_versioned_root_signature_desc *desc,
|
struct vkd3d_versioned_root_signature_desc *desc)
|
||||||
vkd3d_shader_hash_t *compatibility_hash)
|
|
||||||
{
|
{
|
||||||
struct vkd3d_root_signature_desc *v_1_0 = &desc->v_1_0;
|
struct vkd3d_root_signature_desc *v_1_0 = &desc->v_1_0;
|
||||||
struct root_signature_parser_context context;
|
struct root_signature_parser_context context;
|
||||||
|
@ -2765,8 +2736,6 @@ int vkd3d_shader_parse_root_signature_raw(const char *data, unsigned int data_si
|
||||||
const char *ptr = data;
|
const char *ptr = data;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
memset(desc, 0, sizeof(*desc));
|
|
||||||
|
|
||||||
context.data = data;
|
context.data = data;
|
||||||
context.data_size = data_size;
|
context.data_size = data_size;
|
||||||
|
|
||||||
|
@ -2838,46 +2807,28 @@ int vkd3d_shader_parse_root_signature_raw(const char *data, unsigned int data_si
|
||||||
read_uint32(&ptr, &v_1_0->flags);
|
read_uint32(&ptr, &v_1_0->flags);
|
||||||
TRACE("Flags %#x.\n", v_1_0->flags);
|
TRACE("Flags %#x.\n", v_1_0->flags);
|
||||||
|
|
||||||
if (compatibility_hash)
|
|
||||||
{
|
|
||||||
struct vkd3d_shader_code code = { data, data_size };
|
|
||||||
*compatibility_hash = vkd3d_shader_hash(&code);
|
|
||||||
}
|
|
||||||
|
|
||||||
return VKD3D_OK;
|
return VKD3D_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rts0_handler(const char *data, DWORD data_size, DWORD tag, void *context)
|
static int rts0_handler(const char *data, DWORD data_size, DWORD tag, void *context)
|
||||||
{
|
{
|
||||||
struct vkd3d_shader_code *payload = context;
|
struct vkd3d_versioned_root_signature_desc *desc = context;
|
||||||
|
|
||||||
if (tag != TAG_RTS0)
|
if (tag != TAG_RTS0)
|
||||||
return VKD3D_OK;
|
return VKD3D_OK;
|
||||||
|
|
||||||
payload->code = data;
|
return shader_parse_root_signature(data, data_size, desc);
|
||||||
payload->size = data_size;
|
|
||||||
return VKD3D_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int vkd3d_shader_parse_root_signature(const struct vkd3d_shader_code *dxbc,
|
int vkd3d_shader_parse_root_signature(const struct vkd3d_shader_code *dxbc,
|
||||||
struct vkd3d_versioned_root_signature_desc *root_signature,
|
struct vkd3d_versioned_root_signature_desc *root_signature)
|
||||||
vkd3d_shader_hash_t *compatibility_hash)
|
|
||||||
{
|
{
|
||||||
struct vkd3d_shader_code raw_payload;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
TRACE("dxbc {%p, %zu}, root_signature %p.\n", dxbc->code, dxbc->size, root_signature);
|
TRACE("dxbc {%p, %zu}, root_signature %p.\n", dxbc->code, dxbc->size, root_signature);
|
||||||
|
|
||||||
memset(&raw_payload, 0, sizeof(raw_payload));
|
memset(root_signature, 0, sizeof(*root_signature));
|
||||||
|
if ((ret = parse_dxbc(dxbc->code, dxbc->size, rts0_handler, root_signature)) < 0)
|
||||||
if ((ret = parse_dxbc(dxbc->code, dxbc->size, rts0_handler, &raw_payload)) < 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
if (!raw_payload.code)
|
|
||||||
return VKD3D_ERROR;
|
|
||||||
|
|
||||||
if ((ret = vkd3d_shader_parse_root_signature_raw(raw_payload.code, raw_payload.size,
|
|
||||||
root_signature, compatibility_hash)) < 0)
|
|
||||||
{
|
{
|
||||||
vkd3d_shader_free_root_signature(root_signature);
|
vkd3d_shader_free_root_signature(root_signature);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -20,8 +20,6 @@
|
||||||
|
|
||||||
#include "vkd3d_shader_private.h"
|
#include "vkd3d_shader_private.h"
|
||||||
|
|
||||||
#include "vkd3d_platform.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
@ -32,8 +30,6 @@ static void vkd3d_shader_dump_blob(const char *path, vkd3d_shader_hash_t hash, c
|
||||||
|
|
||||||
snprintf(filename, ARRAY_SIZE(filename), "%s/%016"PRIx64".%s", path, hash, ext);
|
snprintf(filename, ARRAY_SIZE(filename), "%s/%016"PRIx64".%s", path, hash, ext);
|
||||||
|
|
||||||
INFO("Dumping blob to %s.\n", filename);
|
|
||||||
|
|
||||||
/* Exclusive open to avoid multiple threads spamming out the same shader module, and avoids race condition. */
|
/* Exclusive open to avoid multiple threads spamming out the same shader module, and avoids race condition. */
|
||||||
if ((f = fopen(filename, "wbx")))
|
if ((f = fopen(filename, "wbx")))
|
||||||
{
|
{
|
||||||
|
@ -44,12 +40,25 @@ static void vkd3d_shader_dump_blob(const char *path, vkd3d_shader_hash_t hash, c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool vkd3d_shader_replace_path(const char *filename, vkd3d_shader_hash_t hash, const void **data, size_t *size)
|
bool vkd3d_shader_replace(vkd3d_shader_hash_t hash, const void **data, size_t *size)
|
||||||
{
|
{
|
||||||
|
static bool enabled = true;
|
||||||
|
char filename[1024];
|
||||||
void *buffer = NULL;
|
void *buffer = NULL;
|
||||||
|
const char *path;
|
||||||
FILE *f = NULL;
|
FILE *f = NULL;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
|
if (!enabled)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!(path = getenv("VKD3D_SHADER_OVERRIDE")))
|
||||||
|
{
|
||||||
|
enabled = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(filename, ARRAY_SIZE(filename), "%s/%016"PRIx64".spv", path, hash);
|
||||||
if ((f = fopen(filename, "rb")))
|
if ((f = fopen(filename, "rb")))
|
||||||
{
|
{
|
||||||
if (fseek(f, 0, SEEK_END) < 0)
|
if (fseek(f, 0, SEEK_END) < 0)
|
||||||
|
@ -69,7 +78,7 @@ static bool vkd3d_shader_replace_path(const char *filename, vkd3d_shader_hash_t
|
||||||
|
|
||||||
*data = buffer;
|
*data = buffer;
|
||||||
*size = len;
|
*size = len;
|
||||||
INFO("Overriding shader hash %016"PRIx64" with alternative SPIR-V module from %s!\n", hash, filename);
|
WARN("Overriding shader hash %016"PRIx64" with alternative SPIR-V module!\n", hash);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -80,53 +89,15 @@ err:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool vkd3d_shader_replace(vkd3d_shader_hash_t hash, const void **data, size_t *size)
|
|
||||||
{
|
|
||||||
static bool enabled = true;
|
|
||||||
char path[VKD3D_PATH_MAX];
|
|
||||||
char filename[1024];
|
|
||||||
|
|
||||||
if (!enabled)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!vkd3d_get_env_var("VKD3D_SHADER_OVERRIDE", path, sizeof(path)))
|
|
||||||
{
|
|
||||||
enabled = false;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
snprintf(filename, ARRAY_SIZE(filename), "%s/%016"PRIx64".spv", path, hash);
|
|
||||||
return vkd3d_shader_replace_path(filename, hash, data, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool vkd3d_shader_replace_export(vkd3d_shader_hash_t hash, const void **data, size_t *size, const char *export)
|
|
||||||
{
|
|
||||||
static bool enabled = true;
|
|
||||||
char path[VKD3D_PATH_MAX];
|
|
||||||
char filename[1024];
|
|
||||||
|
|
||||||
if (!enabled)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!vkd3d_get_env_var("VKD3D_SHADER_OVERRIDE", path, sizeof(path)))
|
|
||||||
{
|
|
||||||
enabled = false;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
snprintf(filename, ARRAY_SIZE(filename), "%s/%016"PRIx64".lib.%s.spv", path, hash, export);
|
|
||||||
return vkd3d_shader_replace_path(filename, hash, data, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void vkd3d_shader_dump_shader(vkd3d_shader_hash_t hash, const struct vkd3d_shader_code *shader, const char *ext)
|
void vkd3d_shader_dump_shader(vkd3d_shader_hash_t hash, const struct vkd3d_shader_code *shader, const char *ext)
|
||||||
{
|
{
|
||||||
static bool enabled = true;
|
static bool enabled = true;
|
||||||
char path[VKD3D_PATH_MAX];
|
const char *path;
|
||||||
|
|
||||||
if (!enabled)
|
if (!enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!vkd3d_get_env_var("VKD3D_SHADER_DUMP_PATH", path, sizeof(path)))
|
if (!(path = getenv("VKD3D_SHADER_DUMP_PATH")))
|
||||||
{
|
{
|
||||||
enabled = false;
|
enabled = false;
|
||||||
return;
|
return;
|
||||||
|
@ -138,12 +109,12 @@ void vkd3d_shader_dump_shader(vkd3d_shader_hash_t hash, const struct vkd3d_shade
|
||||||
void vkd3d_shader_dump_spirv_shader(vkd3d_shader_hash_t hash, const struct vkd3d_shader_code *shader)
|
void vkd3d_shader_dump_spirv_shader(vkd3d_shader_hash_t hash, const struct vkd3d_shader_code *shader)
|
||||||
{
|
{
|
||||||
static bool enabled = true;
|
static bool enabled = true;
|
||||||
char path[VKD3D_PATH_MAX];
|
const char *path;
|
||||||
|
|
||||||
if (!enabled)
|
if (!enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!vkd3d_get_env_var("VKD3D_SHADER_DUMP_PATH", path, sizeof(path)))
|
if (!(path = getenv("VKD3D_SHADER_DUMP_PATH")))
|
||||||
{
|
{
|
||||||
enabled = false;
|
enabled = false;
|
||||||
return;
|
return;
|
||||||
|
@ -152,26 +123,6 @@ void vkd3d_shader_dump_spirv_shader(vkd3d_shader_hash_t hash, const struct vkd3d
|
||||||
vkd3d_shader_dump_blob(path, hash, shader->code, shader->size, "spv");
|
vkd3d_shader_dump_blob(path, hash, shader->code, shader->size, "spv");
|
||||||
}
|
}
|
||||||
|
|
||||||
void vkd3d_shader_dump_spirv_shader_export(vkd3d_shader_hash_t hash, const struct vkd3d_shader_code *shader,
|
|
||||||
const char *export)
|
|
||||||
{
|
|
||||||
static bool enabled = true;
|
|
||||||
char path[VKD3D_PATH_MAX];
|
|
||||||
char tag[1024];
|
|
||||||
|
|
||||||
if (!enabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!vkd3d_get_env_var("VKD3D_SHADER_DUMP_PATH", path, sizeof(path)))
|
|
||||||
{
|
|
||||||
enabled = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
snprintf(tag, sizeof(tag), "lib.%s.spv", export);
|
|
||||||
vkd3d_shader_dump_blob(path, hash, shader->code, shader->size, tag);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct vkd3d_shader_parser
|
struct vkd3d_shader_parser
|
||||||
{
|
{
|
||||||
struct vkd3d_shader_desc shader_desc;
|
struct vkd3d_shader_desc shader_desc;
|
||||||
|
@ -215,6 +166,12 @@ static int vkd3d_shader_validate_compile_args(const struct vkd3d_shader_compile_
|
||||||
if (!compile_args)
|
if (!compile_args)
|
||||||
return VKD3D_OK;
|
return VKD3D_OK;
|
||||||
|
|
||||||
|
if (compile_args->type != VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_ARGUMENTS)
|
||||||
|
{
|
||||||
|
WARN("Invalid structure type %#x.\n", compile_args->type);
|
||||||
|
return VKD3D_ERROR_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
|
||||||
switch (compile_args->target)
|
switch (compile_args->target)
|
||||||
{
|
{
|
||||||
case VKD3D_SHADER_TARGET_SPIRV_VULKAN_1_0:
|
case VKD3D_SHADER_TARGET_SPIRV_VULKAN_1_0:
|
||||||
|
@ -298,29 +255,6 @@ static void vkd3d_shader_scan_destroy(struct vkd3d_shader_scan_info *scan_info)
|
||||||
hash_map_clear(&scan_info->register_map);
|
hash_map_clear(&scan_info->register_map);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vkd3d_shader_validate_shader_type(enum vkd3d_shader_type type, VkShaderStageFlagBits stages)
|
|
||||||
{
|
|
||||||
static const VkShaderStageFlagBits table[VKD3D_SHADER_TYPE_COUNT] = {
|
|
||||||
VK_SHADER_STAGE_FRAGMENT_BIT,
|
|
||||||
VK_SHADER_STAGE_VERTEX_BIT,
|
|
||||||
VK_SHADER_STAGE_GEOMETRY_BIT,
|
|
||||||
VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
|
|
||||||
VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
|
|
||||||
VK_SHADER_STAGE_COMPUTE_BIT,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (type >= VKD3D_SHADER_TYPE_COUNT)
|
|
||||||
return VKD3D_ERROR_INVALID_ARGUMENT;
|
|
||||||
|
|
||||||
if (table[type] != stages)
|
|
||||||
{
|
|
||||||
ERR("Expected VkShaderStage #%x, but got VkShaderStage #%x.\n", stages, table[type]);
|
|
||||||
return VKD3D_ERROR_INVALID_ARGUMENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int vkd3d_shader_compile_dxbc(const struct vkd3d_shader_code *dxbc,
|
int vkd3d_shader_compile_dxbc(const struct vkd3d_shader_code *dxbc,
|
||||||
struct vkd3d_shader_code *spirv, unsigned int compiler_options,
|
struct vkd3d_shader_code *spirv, unsigned int compiler_options,
|
||||||
const struct vkd3d_shader_interface_info *shader_interface_info,
|
const struct vkd3d_shader_interface_info *shader_interface_info,
|
||||||
|
@ -336,22 +270,32 @@ int vkd3d_shader_compile_dxbc(const struct vkd3d_shader_code *dxbc,
|
||||||
TRACE("dxbc {%p, %zu}, spirv %p, compiler_options %#x, shader_interface_info %p, compile_args %p.\n",
|
TRACE("dxbc {%p, %zu}, spirv %p, compiler_options %#x, shader_interface_info %p, compile_args %p.\n",
|
||||||
dxbc->code, dxbc->size, spirv, compiler_options, shader_interface_info, compile_args);
|
dxbc->code, dxbc->size, spirv, compiler_options, shader_interface_info, compile_args);
|
||||||
|
|
||||||
|
if (shader_interface_info && shader_interface_info->type != VKD3D_SHADER_STRUCTURE_TYPE_SHADER_INTERFACE_INFO)
|
||||||
|
{
|
||||||
|
WARN("Invalid structure type %#x.\n", shader_interface_info->type);
|
||||||
|
return VKD3D_ERROR_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
|
||||||
if ((ret = vkd3d_shader_validate_compile_args(compile_args)) < 0)
|
if ((ret = vkd3d_shader_validate_compile_args(compile_args)) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/* DXIL is handled externally through dxil-spirv. */
|
/* DXIL is handled externally through dxil-spirv. */
|
||||||
if (shader_is_dxil(dxbc->code, dxbc->size))
|
if (shader_is_dxil(dxbc->code, dxbc->size))
|
||||||
{
|
{
|
||||||
|
#ifdef HAVE_DXIL_SPV
|
||||||
return vkd3d_shader_compile_dxil(dxbc, spirv, shader_interface_info, compile_args);
|
return vkd3d_shader_compile_dxil(dxbc, spirv, shader_interface_info, compile_args);
|
||||||
|
#else
|
||||||
|
ERR("DXIL shader found, but DXIL support is not enabled in vkd3d.\n");
|
||||||
|
return VKD3D_ERROR_INVALID_SHADER;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&spirv->meta, 0, sizeof(spirv->meta));
|
|
||||||
|
|
||||||
hash = vkd3d_shader_hash(dxbc);
|
hash = vkd3d_shader_hash(dxbc);
|
||||||
|
spirv->meta.replaced = false;
|
||||||
spirv->meta.hash = hash;
|
spirv->meta.hash = hash;
|
||||||
if (vkd3d_shader_replace(hash, &spirv->code, &spirv->size))
|
if (vkd3d_shader_replace(hash, &spirv->code, &spirv->size))
|
||||||
{
|
{
|
||||||
spirv->meta.flags |= VKD3D_SHADER_META_FLAG_REPLACED;
|
spirv->meta.replaced = true;
|
||||||
return VKD3D_OK;
|
return VKD3D_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -363,31 +307,19 @@ int vkd3d_shader_compile_dxbc(const struct vkd3d_shader_code *dxbc,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
spirv->meta.patch_vertex_count = scan_info.patch_vertex_count;
|
|
||||||
|
|
||||||
if ((ret = vkd3d_shader_parser_init(&parser, dxbc)) < 0)
|
if ((ret = vkd3d_shader_parser_init(&parser, dxbc)) < 0)
|
||||||
{
|
{
|
||||||
vkd3d_shader_scan_destroy(&scan_info);
|
vkd3d_shader_scan_destroy(&scan_info);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shader_interface_info)
|
|
||||||
{
|
|
||||||
if ((ret = vkd3d_shader_validate_shader_type(parser.shader_version.type, shader_interface_info->stage)) < 0)
|
|
||||||
{
|
|
||||||
vkd3d_shader_scan_destroy(&scan_info);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
vkd3d_shader_dump_shader(hash, dxbc, "dxbc");
|
vkd3d_shader_dump_shader(hash, dxbc, "dxbc");
|
||||||
|
|
||||||
if (TRACE_ON())
|
if (TRACE_ON())
|
||||||
vkd3d_shader_trace(parser.data);
|
vkd3d_shader_trace(parser.data);
|
||||||
|
|
||||||
if (!(spirv_compiler = vkd3d_dxbc_compiler_create(&parser.shader_version,
|
if (!(spirv_compiler = vkd3d_dxbc_compiler_create(&parser.shader_version,
|
||||||
&parser.shader_desc, compiler_options, shader_interface_info, compile_args, &scan_info,
|
&parser.shader_desc, compiler_options, shader_interface_info, compile_args, &scan_info)))
|
||||||
spirv->meta.hash)))
|
|
||||||
{
|
{
|
||||||
ERR("Failed to create DXBC compiler.\n");
|
ERR("Failed to create DXBC compiler.\n");
|
||||||
vkd3d_shader_scan_destroy(&scan_info);
|
vkd3d_shader_scan_destroy(&scan_info);
|
||||||
|
@ -434,24 +366,6 @@ static bool vkd3d_shader_instruction_is_uav_read(const struct vkd3d_shader_instr
|
||||||
|| ((handler_idx == VKD3DSIH_LD_STRUCTURED || handler_idx == VKD3DSIH_LD_STRUCTURED_FEEDBACK) && instruction->src[2].reg.type == VKD3DSPR_UAV);
|
|| ((handler_idx == VKD3DSIH_LD_STRUCTURED || handler_idx == VKD3DSIH_LD_STRUCTURED_FEEDBACK) && instruction->src[2].reg.type == VKD3DSPR_UAV);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool vkd3d_shader_instruction_is_uav_write(const struct vkd3d_shader_instruction *instruction)
|
|
||||||
{
|
|
||||||
enum VKD3D_SHADER_INSTRUCTION_HANDLER handler_idx = instruction->handler_idx;
|
|
||||||
return (VKD3DSIH_ATOMIC_AND <= handler_idx && handler_idx <= VKD3DSIH_ATOMIC_XOR)
|
|
||||||
|| (VKD3DSIH_IMM_ATOMIC_ALLOC <= handler_idx && handler_idx <= VKD3DSIH_IMM_ATOMIC_XOR)
|
|
||||||
|| handler_idx == VKD3DSIH_STORE_UAV_TYPED
|
|
||||||
|| handler_idx == VKD3DSIH_STORE_RAW
|
|
||||||
|| handler_idx == VKD3DSIH_STORE_STRUCTURED;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool vkd3d_shader_instruction_is_uav_atomic(const struct vkd3d_shader_instruction *instruction)
|
|
||||||
{
|
|
||||||
enum VKD3D_SHADER_INSTRUCTION_HANDLER handler_idx = instruction->handler_idx;
|
|
||||||
return ((VKD3DSIH_ATOMIC_AND <= handler_idx && handler_idx <= VKD3DSIH_ATOMIC_XOR) ||
|
|
||||||
(VKD3DSIH_IMM_ATOMIC_AND <= handler_idx && handler_idx <= VKD3DSIH_IMM_ATOMIC_XOR)) &&
|
|
||||||
handler_idx != VKD3DSIH_IMM_ATOMIC_CONSUME;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void vkd3d_shader_scan_record_uav_read(struct vkd3d_shader_scan_info *scan_info,
|
static void vkd3d_shader_scan_record_uav_read(struct vkd3d_shader_scan_info *scan_info,
|
||||||
const struct vkd3d_shader_register *reg)
|
const struct vkd3d_shader_register *reg)
|
||||||
{
|
{
|
||||||
|
@ -459,13 +373,6 @@ static void vkd3d_shader_scan_record_uav_read(struct vkd3d_shader_scan_info *sca
|
||||||
reg->idx[0].offset, VKD3D_SHADER_UAV_FLAG_READ_ACCESS);
|
reg->idx[0].offset, VKD3D_SHADER_UAV_FLAG_READ_ACCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vkd3d_shader_scan_record_uav_atomic(struct vkd3d_shader_scan_info *scan_info,
|
|
||||||
const struct vkd3d_shader_register *reg)
|
|
||||||
{
|
|
||||||
vkd3d_shader_scan_set_register_flags(scan_info, VKD3DSPR_UAV,
|
|
||||||
reg->idx[0].offset, VKD3D_SHADER_UAV_FLAG_ATOMIC_ACCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool vkd3d_shader_instruction_is_uav_counter(const struct vkd3d_shader_instruction *instruction)
|
static bool vkd3d_shader_instruction_is_uav_counter(const struct vkd3d_shader_instruction *instruction)
|
||||||
{
|
{
|
||||||
enum VKD3D_SHADER_INSTRUCTION_HANDLER handler_idx = instruction->handler_idx;
|
enum VKD3D_SHADER_INSTRUCTION_HANDLER handler_idx = instruction->handler_idx;
|
||||||
|
@ -476,8 +383,6 @@ static bool vkd3d_shader_instruction_is_uav_counter(const struct vkd3d_shader_in
|
||||||
static void vkd3d_shader_scan_record_uav_counter(struct vkd3d_shader_scan_info *scan_info,
|
static void vkd3d_shader_scan_record_uav_counter(struct vkd3d_shader_scan_info *scan_info,
|
||||||
const struct vkd3d_shader_register *reg)
|
const struct vkd3d_shader_register *reg)
|
||||||
{
|
{
|
||||||
scan_info->has_side_effects = true;
|
|
||||||
scan_info->has_uav_counter = true;
|
|
||||||
vkd3d_shader_scan_set_register_flags(scan_info, VKD3DSPR_UAV,
|
vkd3d_shader_scan_set_register_flags(scan_info, VKD3DSPR_UAV,
|
||||||
reg->idx[0].offset, VKD3D_SHADER_UAV_FLAG_ATOMIC_COUNTER);
|
reg->idx[0].offset, VKD3D_SHADER_UAV_FLAG_ATOMIC_COUNTER);
|
||||||
}
|
}
|
||||||
|
@ -491,83 +396,81 @@ static void vkd3d_shader_scan_input_declaration(struct vkd3d_shader_scan_info *s
|
||||||
scan_info->use_vocp = true;
|
scan_info->use_vocp = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vkd3d_shader_scan_output_declaration(struct vkd3d_shader_scan_info *scan_info,
|
|
||||||
const struct vkd3d_shader_instruction *instruction)
|
|
||||||
{
|
|
||||||
switch (instruction->declaration.dst.reg.type)
|
|
||||||
{
|
|
||||||
case VKD3DSPR_DEPTHOUT:
|
|
||||||
case VKD3DSPR_DEPTHOUTLE:
|
|
||||||
case VKD3DSPR_DEPTHOUTGE:
|
|
||||||
case VKD3DSPR_STENCILREFOUT:
|
|
||||||
case VKD3DSPR_SAMPLEMASK:
|
|
||||||
scan_info->needs_late_zs = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_info *scan_info,
|
static void vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_info *scan_info,
|
||||||
const struct vkd3d_shader_instruction *instruction)
|
const struct vkd3d_shader_instruction *instruction)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
bool is_atomic;
|
|
||||||
|
|
||||||
switch (instruction->handler_idx)
|
switch (instruction->handler_idx)
|
||||||
{
|
{
|
||||||
case VKD3DSIH_DCL_INPUT:
|
case VKD3DSIH_DCL_INPUT:
|
||||||
vkd3d_shader_scan_input_declaration(scan_info, instruction);
|
vkd3d_shader_scan_input_declaration(scan_info, instruction);
|
||||||
break;
|
break;
|
||||||
case VKD3DSIH_DCL_OUTPUT:
|
|
||||||
vkd3d_shader_scan_output_declaration(scan_info, instruction);
|
|
||||||
break;
|
|
||||||
case VKD3DSIH_DISCARD:
|
|
||||||
scan_info->discards = true;
|
|
||||||
break;
|
|
||||||
case VKD3DSIH_DCL_GLOBAL_FLAGS:
|
|
||||||
if (instruction->flags & VKD3DSGF_FORCE_EARLY_DEPTH_STENCIL)
|
|
||||||
scan_info->early_fragment_tests = true;
|
|
||||||
break;
|
|
||||||
case VKD3DSIH_DCL_INPUT_CONTROL_POINT_COUNT:
|
|
||||||
scan_info->patch_vertex_count = instruction->declaration.count;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vkd3d_shader_instruction_is_uav_read(instruction))
|
if (vkd3d_shader_instruction_is_uav_read(instruction))
|
||||||
{
|
{
|
||||||
is_atomic = vkd3d_shader_instruction_is_uav_atomic(instruction);
|
|
||||||
|
|
||||||
for (i = 0; i < instruction->dst_count; ++i)
|
for (i = 0; i < instruction->dst_count; ++i)
|
||||||
{
|
{
|
||||||
if (instruction->dst[i].reg.type == VKD3DSPR_UAV)
|
if (instruction->dst[i].reg.type == VKD3DSPR_UAV)
|
||||||
{
|
|
||||||
vkd3d_shader_scan_record_uav_read(scan_info, &instruction->dst[i].reg);
|
vkd3d_shader_scan_record_uav_read(scan_info, &instruction->dst[i].reg);
|
||||||
if (is_atomic)
|
|
||||||
vkd3d_shader_scan_record_uav_atomic(scan_info, &instruction->dst[i].reg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
for (i = 0; i < instruction->src_count; ++i)
|
for (i = 0; i < instruction->src_count; ++i)
|
||||||
{
|
{
|
||||||
if (instruction->src[i].reg.type == VKD3DSPR_UAV)
|
if (instruction->src[i].reg.type == VKD3DSPR_UAV)
|
||||||
{
|
|
||||||
vkd3d_shader_scan_record_uav_read(scan_info, &instruction->src[i].reg);
|
vkd3d_shader_scan_record_uav_read(scan_info, &instruction->src[i].reg);
|
||||||
if (is_atomic)
|
|
||||||
vkd3d_shader_scan_record_uav_atomic(scan_info, &instruction->src[i].reg);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (vkd3d_shader_instruction_is_uav_write(instruction))
|
|
||||||
scan_info->has_side_effects = true;
|
|
||||||
|
|
||||||
if (vkd3d_shader_instruction_is_uav_counter(instruction))
|
if (vkd3d_shader_instruction_is_uav_counter(instruction))
|
||||||
vkd3d_shader_scan_record_uav_counter(scan_info, &instruction->src[0].reg);
|
vkd3d_shader_scan_record_uav_counter(scan_info, &instruction->src[0].reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int vkd3d_shader_scan_patch_vertex_count(const struct vkd3d_shader_code *dxbc,
|
||||||
|
unsigned int *patch_vertex_count)
|
||||||
|
{
|
||||||
|
struct vkd3d_shader_instruction instruction;
|
||||||
|
struct vkd3d_shader_parser parser;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (shader_is_dxil(dxbc->code, dxbc->size))
|
||||||
|
{
|
||||||
|
/* TODO */
|
||||||
|
*patch_vertex_count = 0;
|
||||||
|
return VKD3D_OK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ((ret = vkd3d_shader_parser_init(&parser, dxbc)) < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
*patch_vertex_count = 0;
|
||||||
|
|
||||||
|
while (!shader_sm4_is_end(parser.data, &parser.ptr))
|
||||||
|
{
|
||||||
|
shader_sm4_read_instruction(parser.data, &parser.ptr, &instruction);
|
||||||
|
|
||||||
|
if (instruction.handler_idx == VKD3DSIH_INVALID)
|
||||||
|
{
|
||||||
|
WARN("Encountered unrecognized or invalid instruction.\n");
|
||||||
|
vkd3d_shader_parser_destroy(&parser);
|
||||||
|
return VKD3D_ERROR_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (instruction.handler_idx == VKD3DSIH_DCL_INPUT_CONTROL_POINT_COUNT)
|
||||||
|
{
|
||||||
|
*patch_vertex_count = instruction.declaration.count;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vkd3d_shader_parser_destroy(&parser);
|
||||||
|
return VKD3D_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int vkd3d_shader_scan_dxbc(const struct vkd3d_shader_code *dxbc,
|
int vkd3d_shader_scan_dxbc(const struct vkd3d_shader_code *dxbc,
|
||||||
struct vkd3d_shader_scan_info *scan_info)
|
struct vkd3d_shader_scan_info *scan_info)
|
||||||
{
|
{
|
||||||
|
@ -675,14 +578,6 @@ int vkd3d_shader_parse_input_signature(const struct vkd3d_shader_code *dxbc,
|
||||||
return shader_parse_input_signature(dxbc->code, dxbc->size, signature);
|
return shader_parse_input_signature(dxbc->code, dxbc->size, signature);
|
||||||
}
|
}
|
||||||
|
|
||||||
int vkd3d_shader_parse_output_signature(const struct vkd3d_shader_code *dxbc,
|
|
||||||
struct vkd3d_shader_signature *signature)
|
|
||||||
{
|
|
||||||
TRACE("dxbc {%p, %zu}, signature %p.\n", dxbc->code, dxbc->size, signature);
|
|
||||||
|
|
||||||
return shader_parse_output_signature(dxbc->code, dxbc->size, signature);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct vkd3d_shader_signature_element *vkd3d_shader_find_signature_element(
|
struct vkd3d_shader_signature_element *vkd3d_shader_find_signature_element(
|
||||||
const struct vkd3d_shader_signature *signature, const char *semantic_name,
|
const struct vkd3d_shader_signature *signature, const char *semantic_name,
|
||||||
unsigned int semantic_index, unsigned int stream_index)
|
unsigned int semantic_index, unsigned int stream_index)
|
||||||
|
@ -713,38 +608,23 @@ void vkd3d_shader_free_shader_signature(struct vkd3d_shader_signature *signature
|
||||||
signature->elements = NULL;
|
signature->elements = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int vkd3d_shader_supports_dxil(void)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_DXIL_SPV
|
||||||
|
return 1;
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
vkd3d_shader_hash_t vkd3d_shader_hash(const struct vkd3d_shader_code *shader)
|
vkd3d_shader_hash_t vkd3d_shader_hash(const struct vkd3d_shader_code *shader)
|
||||||
{
|
{
|
||||||
vkd3d_shader_hash_t h = hash_fnv1_init();
|
vkd3d_shader_hash_t h = 0xcbf29ce484222325ull;
|
||||||
const uint8_t *code = shader->code;
|
const uint8_t *code = shader->code;
|
||||||
size_t i, n;
|
size_t i, n;
|
||||||
|
|
||||||
for (i = 0, n = shader->size; i < n; i++)
|
for (i = 0, n = shader->size; i < n; i++)
|
||||||
h = hash_fnv1_iterate_u8(h, code[i]);
|
h = (h * 0x100000001b3ull) ^ code[i];
|
||||||
|
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t vkd3d_shader_compile_arguments_select_quirks(
|
|
||||||
const struct vkd3d_shader_compile_arguments *compile_args, vkd3d_shader_hash_t shader_hash)
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
if (compile_args && compile_args->quirks)
|
|
||||||
{
|
|
||||||
for (i = 0; i < compile_args->quirks->num_hashes; i++)
|
|
||||||
if (compile_args->quirks->hashes[i].shader_hash == shader_hash)
|
|
||||||
return compile_args->quirks->hashes[i].quirks | compile_args->quirks->global_quirks;
|
|
||||||
return compile_args->quirks->default_quirks | compile_args->quirks->global_quirks;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t vkd3d_shader_get_revision(void)
|
|
||||||
{
|
|
||||||
/* This is meant to be bumped every time a change is made to the shader compiler.
|
|
||||||
* Might get nuked later ...
|
|
||||||
* It's not immediately useful for invalidating pipeline caches, since that would mostly be covered
|
|
||||||
* by vkd3d-proton Git hash. */
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
|
@ -342,7 +342,6 @@ enum vkd3d_shader_register_type
|
||||||
VKD3DSPR_DEPTHOUTLE,
|
VKD3DSPR_DEPTHOUTLE,
|
||||||
VKD3DSPR_RASTERIZER,
|
VKD3DSPR_RASTERIZER,
|
||||||
VKD3DSPR_STENCILREFOUT,
|
VKD3DSPR_STENCILREFOUT,
|
||||||
VKD3DSPR_INNERCOVERAGE,
|
|
||||||
|
|
||||||
VKD3DSPR_INVALID = ~0u,
|
VKD3DSPR_INVALID = ~0u,
|
||||||
};
|
};
|
||||||
|
@ -781,8 +780,6 @@ void free_shader_desc(struct vkd3d_shader_desc *desc);
|
||||||
|
|
||||||
int shader_parse_input_signature(const void *dxbc, size_t dxbc_length,
|
int shader_parse_input_signature(const void *dxbc, size_t dxbc_length,
|
||||||
struct vkd3d_shader_signature *signature);
|
struct vkd3d_shader_signature *signature);
|
||||||
int shader_parse_output_signature(const void *dxbc, size_t dxbc_length,
|
|
||||||
struct vkd3d_shader_signature *signature);
|
|
||||||
|
|
||||||
struct vkd3d_dxbc_compiler;
|
struct vkd3d_dxbc_compiler;
|
||||||
|
|
||||||
|
@ -790,8 +787,7 @@ struct vkd3d_dxbc_compiler *vkd3d_dxbc_compiler_create(const struct vkd3d_shader
|
||||||
const struct vkd3d_shader_desc *shader_desc, uint32_t compiler_options,
|
const struct vkd3d_shader_desc *shader_desc, uint32_t compiler_options,
|
||||||
const struct vkd3d_shader_interface_info *shader_interface_info,
|
const struct vkd3d_shader_interface_info *shader_interface_info,
|
||||||
const struct vkd3d_shader_compile_arguments *compile_args,
|
const struct vkd3d_shader_compile_arguments *compile_args,
|
||||||
const struct vkd3d_shader_scan_info *scan_info,
|
const struct vkd3d_shader_scan_info *scan_info);
|
||||||
vkd3d_shader_hash_t shader_hash);
|
|
||||||
int vkd3d_dxbc_compiler_handle_instruction(struct vkd3d_dxbc_compiler *compiler,
|
int vkd3d_dxbc_compiler_handle_instruction(struct vkd3d_dxbc_compiler *compiler,
|
||||||
const struct vkd3d_shader_instruction *instruction);
|
const struct vkd3d_shader_instruction *instruction);
|
||||||
int vkd3d_dxbc_compiler_generate_spirv(struct vkd3d_dxbc_compiler *compiler,
|
int vkd3d_dxbc_compiler_generate_spirv(struct vkd3d_dxbc_compiler *compiler,
|
||||||
|
@ -801,11 +797,8 @@ void vkd3d_dxbc_compiler_destroy(struct vkd3d_dxbc_compiler *compiler);
|
||||||
void vkd3d_compute_dxbc_checksum(const void *dxbc, size_t size, uint32_t checksum[4]);
|
void vkd3d_compute_dxbc_checksum(const void *dxbc, size_t size, uint32_t checksum[4]);
|
||||||
|
|
||||||
void vkd3d_shader_dump_spirv_shader(vkd3d_shader_hash_t hash, const struct vkd3d_shader_code *shader);
|
void vkd3d_shader_dump_spirv_shader(vkd3d_shader_hash_t hash, const struct vkd3d_shader_code *shader);
|
||||||
void vkd3d_shader_dump_spirv_shader_export(vkd3d_shader_hash_t hash, const struct vkd3d_shader_code *shader,
|
|
||||||
const char *export);
|
|
||||||
void vkd3d_shader_dump_shader(vkd3d_shader_hash_t hash, const struct vkd3d_shader_code *shader, const char *ext);
|
void vkd3d_shader_dump_shader(vkd3d_shader_hash_t hash, const struct vkd3d_shader_code *shader, const char *ext);
|
||||||
bool vkd3d_shader_replace(vkd3d_shader_hash_t hash, const void **data, size_t *size);
|
bool vkd3d_shader_replace(vkd3d_shader_hash_t hash, const void **data, size_t *size);
|
||||||
bool vkd3d_shader_replace_export(vkd3d_shader_hash_t hash, const void **data, size_t *size, const char *export);
|
|
||||||
|
|
||||||
static inline enum vkd3d_component_type vkd3d_component_type_from_data_type(
|
static inline enum vkd3d_component_type vkd3d_component_type_from_data_type(
|
||||||
enum vkd3d_data_type data_type)
|
enum vkd3d_data_type data_type)
|
||||||
|
@ -907,6 +900,27 @@ static inline unsigned int vkd3d_compact_swizzle(unsigned int swizzle, unsigned
|
||||||
return compacted_swizzle;
|
return compacted_swizzle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct vkd3d_struct
|
||||||
|
{
|
||||||
|
enum vkd3d_shader_structure_type type;
|
||||||
|
const void *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define vkd3d_find_struct(c, t) vkd3d_find_struct_(c, VKD3D_SHADER_STRUCTURE_TYPE_##t)
|
||||||
|
static inline const void *vkd3d_find_struct_(const struct vkd3d_struct *chain,
|
||||||
|
enum vkd3d_shader_structure_type type)
|
||||||
|
{
|
||||||
|
while (chain)
|
||||||
|
{
|
||||||
|
if (chain->type == type)
|
||||||
|
return chain;
|
||||||
|
|
||||||
|
chain = chain->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
#define VKD3D_DXBC_MAX_SOURCE_COUNT 6
|
#define VKD3D_DXBC_MAX_SOURCE_COUNT 6
|
||||||
#define VKD3D_DXBC_HEADER_SIZE (8 * sizeof(uint32_t))
|
#define VKD3D_DXBC_HEADER_SIZE (8 * sizeof(uint32_t))
|
||||||
|
|
||||||
|
@ -919,4 +933,6 @@ int vkd3d_shader_compile_dxil(const struct vkd3d_shader_code *dxbc,
|
||||||
const struct vkd3d_shader_interface_info *shader_interface_info,
|
const struct vkd3d_shader_interface_info *shader_interface_info,
|
||||||
const struct vkd3d_shader_compile_arguments *compiler_args);
|
const struct vkd3d_shader_compile_arguments *compiler_args);
|
||||||
|
|
||||||
|
vkd3d_shader_hash_t vkd3d_shader_hash(const struct vkd3d_shader_code *shader);
|
||||||
|
|
||||||
#endif /* __VKD3D_SHADER_PRIVATE_H */
|
#endif /* __VKD3D_SHADER_PRIVATE_H */
|
||||||
|
|
|
@ -6,11 +6,11 @@ vkd3d_utils_lib = shared_library('vkd3d-proton-utils', vkd3d_utils_src,
|
||||||
dependencies : vkd3d_dep,
|
dependencies : vkd3d_dep,
|
||||||
include_directories : vkd3d_private_includes,
|
include_directories : vkd3d_private_includes,
|
||||||
install : true,
|
install : true,
|
||||||
objects : not vkd3d_is_msvc and vkd3d_platform == 'windows'
|
objects : not vkd3d_msvc and vkd3d_platform == 'windows'
|
||||||
? 'vkd3d-proton-utils.def'
|
? 'vkd3d-proton-utils.def'
|
||||||
: [],
|
: [],
|
||||||
vs_module_defs : 'vkd3d-proton-utils.def',
|
vs_module_defs : 'vkd3d-proton-utils.def',
|
||||||
version : '3.0.0',
|
version : '2.0.0',
|
||||||
c_args : '-DVKD3D_UTILS_EXPORTS',
|
c_args : '-DVKD3D_UTILS_EXPORTS',
|
||||||
override_options : [ 'c_std='+vkd3d_c_std ])
|
override_options : [ 'c_std='+vkd3d_c_std ])
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
LIBRARY vkd3d-proton-utils-3.dll
|
LIBRARY vkd3d-proton-utils-2.dll
|
||||||
|
|
||||||
EXPORTS
|
EXPORTS
|
||||||
D3D12CreateDevice @101
|
D3D12CreateDevice @101
|
||||||
D3D12GetDebugInterface @102
|
D3D12GetDebugInterface @102
|
||||||
D3D12CreateRootSignatureDeserializer
|
D3D12CreateRootSignatureDeserializer @107
|
||||||
D3D12CreateVersionedRootSignatureDeserializer
|
D3D12CreateVersionedRootSignatureDeserializer @108
|
||||||
|
|
||||||
D3D12EnableExperimentalFeatures
|
D3D12EnableExperimentalFeatures @110
|
||||||
D3D12SerializeRootSignature
|
D3D12SerializeRootSignature @115
|
||||||
D3D12SerializeVersionedRootSignature
|
D3D12SerializeVersionedRootSignature @116
|
||||||
|
|
||||||
vkd3d_create_event
|
vkd3d_create_event
|
||||||
vkd3d_wait_event
|
vkd3d_wait_event
|
||||||
|
|
|
@ -31,6 +31,7 @@ VKD3D_UTILS_EXPORT HRESULT WINAPI D3D12GetDebugInterface(REFIID iid, void **debu
|
||||||
VKD3D_UTILS_EXPORT HRESULT WINAPI D3D12CreateDevice(IUnknown *adapter,
|
VKD3D_UTILS_EXPORT HRESULT WINAPI D3D12CreateDevice(IUnknown *adapter,
|
||||||
D3D_FEATURE_LEVEL minimum_feature_level, REFIID iid, void **device)
|
D3D_FEATURE_LEVEL minimum_feature_level, REFIID iid, void **device)
|
||||||
{
|
{
|
||||||
|
struct vkd3d_optional_instance_extensions_info optional_extensions_info;
|
||||||
struct vkd3d_instance_create_info instance_create_info;
|
struct vkd3d_instance_create_info instance_create_info;
|
||||||
struct vkd3d_device_create_info device_create_info;
|
struct vkd3d_device_create_info device_create_info;
|
||||||
|
|
||||||
|
@ -54,14 +55,22 @@ VKD3D_UTILS_EXPORT HRESULT WINAPI D3D12CreateDevice(IUnknown *adapter,
|
||||||
if (adapter)
|
if (adapter)
|
||||||
FIXME("Ignoring adapter %p.\n", adapter);
|
FIXME("Ignoring adapter %p.\n", adapter);
|
||||||
|
|
||||||
|
memset(&optional_extensions_info, 0, sizeof(optional_extensions_info));
|
||||||
|
optional_extensions_info.type = VKD3D_STRUCTURE_TYPE_OPTIONAL_INSTANCE_EXTENSIONS_INFO;
|
||||||
|
optional_extensions_info.extensions = optional_instance_extensions;
|
||||||
|
optional_extensions_info.extension_count = ARRAY_SIZE(optional_instance_extensions);
|
||||||
|
|
||||||
memset(&instance_create_info, 0, sizeof(instance_create_info));
|
memset(&instance_create_info, 0, sizeof(instance_create_info));
|
||||||
|
instance_create_info.type = VKD3D_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
||||||
|
instance_create_info.next = &optional_extensions_info;
|
||||||
instance_create_info.pfn_signal_event = vkd3d_signal_event;
|
instance_create_info.pfn_signal_event = vkd3d_signal_event;
|
||||||
|
instance_create_info.wchar_size = sizeof(WCHAR);
|
||||||
instance_create_info.instance_extensions = instance_extensions;
|
instance_create_info.instance_extensions = instance_extensions;
|
||||||
instance_create_info.instance_extension_count = ARRAY_SIZE(instance_extensions);
|
instance_create_info.instance_extension_count = ARRAY_SIZE(instance_extensions);
|
||||||
instance_create_info.optional_instance_extensions = optional_instance_extensions;
|
|
||||||
instance_create_info.optional_instance_extension_count = ARRAY_SIZE(optional_instance_extensions);
|
|
||||||
|
|
||||||
memset(&device_create_info, 0, sizeof(device_create_info));
|
memset(&device_create_info, 0, sizeof(device_create_info));
|
||||||
|
device_create_info.type = VKD3D_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
|
||||||
|
device_create_info.next = NULL;
|
||||||
device_create_info.minimum_feature_level = minimum_feature_level;
|
device_create_info.minimum_feature_level = minimum_feature_level;
|
||||||
device_create_info.instance_create_info = &instance_create_info;
|
device_create_info.instance_create_info = &instance_create_info;
|
||||||
device_create_info.device_extensions = device_extensions;
|
device_create_info.device_extensions = device_extensions;
|
||||||
|
|
|
@ -1,498 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2021 Hans-Kristian Arntzen for Valve Corporation
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define VKD3D_DBG_CHANNEL VKD3D_DBG_CHANNEL_API
|
|
||||||
#include "vkd3d_private.h"
|
|
||||||
|
|
||||||
#define RT_TRACE TRACE
|
|
||||||
|
|
||||||
void vkd3d_acceleration_structure_build_info_cleanup(
|
|
||||||
struct vkd3d_acceleration_structure_build_info *info)
|
|
||||||
{
|
|
||||||
if (info->primitive_counts != info->primitive_counts_stack)
|
|
||||||
vkd3d_free(info->primitive_counts);
|
|
||||||
if (info->geometries != info->geometries_stack)
|
|
||||||
vkd3d_free(info->geometries);
|
|
||||||
if (info->build_range_ptrs != info->build_range_ptr_stack)
|
|
||||||
vkd3d_free((void *)info->build_range_ptrs);
|
|
||||||
if (info->build_ranges != info->build_range_stack)
|
|
||||||
vkd3d_free(info->build_ranges);
|
|
||||||
}
|
|
||||||
|
|
||||||
static VkBuildAccelerationStructureFlagsKHR d3d12_build_flags_to_vk(
|
|
||||||
D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS flags)
|
|
||||||
{
|
|
||||||
VkBuildAccelerationStructureFlagsKHR vk_flags = 0;
|
|
||||||
|
|
||||||
if (flags & D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_ALLOW_COMPACTION)
|
|
||||||
vk_flags |= VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_KHR;
|
|
||||||
if (flags & D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_ALLOW_UPDATE)
|
|
||||||
vk_flags |= VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR;
|
|
||||||
if (flags & D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_MINIMIZE_MEMORY)
|
|
||||||
vk_flags |= VK_BUILD_ACCELERATION_STRUCTURE_LOW_MEMORY_BIT_KHR;
|
|
||||||
if (flags & D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_PREFER_FAST_BUILD)
|
|
||||||
vk_flags |= VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR;
|
|
||||||
if (flags & D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_PREFER_FAST_TRACE)
|
|
||||||
vk_flags |= VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR;
|
|
||||||
|
|
||||||
return vk_flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
static VkGeometryFlagsKHR d3d12_geometry_flags_to_vk(D3D12_RAYTRACING_GEOMETRY_FLAGS flags)
|
|
||||||
{
|
|
||||||
VkGeometryFlagsKHR vk_flags = 0;
|
|
||||||
|
|
||||||
if (flags & D3D12_RAYTRACING_GEOMETRY_FLAG_OPAQUE)
|
|
||||||
vk_flags |= VK_GEOMETRY_OPAQUE_BIT_KHR;
|
|
||||||
if (flags & D3D12_RAYTRACING_GEOMETRY_FLAG_NO_DUPLICATE_ANYHIT_INVOCATION)
|
|
||||||
vk_flags |= VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_KHR;
|
|
||||||
|
|
||||||
return vk_flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool vkd3d_acceleration_structure_convert_inputs(const struct d3d12_device *device,
|
|
||||||
struct vkd3d_acceleration_structure_build_info *info,
|
|
||||||
const D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS *desc)
|
|
||||||
{
|
|
||||||
VkAccelerationStructureGeometryTrianglesDataKHR *triangles;
|
|
||||||
VkAccelerationStructureBuildGeometryInfoKHR *build_info;
|
|
||||||
VkAccelerationStructureGeometryAabbsDataKHR *aabbs;
|
|
||||||
const D3D12_RAYTRACING_GEOMETRY_DESC *geom_desc;
|
|
||||||
bool have_triangles, have_aabbs;
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
RT_TRACE("Converting inputs.\n");
|
|
||||||
RT_TRACE("=====================\n");
|
|
||||||
|
|
||||||
build_info = &info->build_info;
|
|
||||||
memset(build_info, 0, sizeof(*build_info));
|
|
||||||
build_info->sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR;
|
|
||||||
|
|
||||||
if (desc->Type == D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL)
|
|
||||||
{
|
|
||||||
build_info->type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR;
|
|
||||||
RT_TRACE("Top level build.\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
build_info->type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
|
|
||||||
RT_TRACE("Bottom level build.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
build_info->flags = d3d12_build_flags_to_vk(desc->Flags);
|
|
||||||
|
|
||||||
if (desc->Flags & D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_PERFORM_UPDATE)
|
|
||||||
{
|
|
||||||
RT_TRACE("BUILD_FLAG_PERFORM_UPDATE.\n");
|
|
||||||
build_info->mode = VK_BUILD_ACCELERATION_STRUCTURE_MODE_UPDATE_KHR;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
build_info->mode = VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR;
|
|
||||||
|
|
||||||
info->geometries = info->geometries_stack;
|
|
||||||
info->primitive_counts = info->primitive_counts_stack;
|
|
||||||
info->build_ranges = info->build_range_stack;
|
|
||||||
info->build_range_ptrs = info->build_range_ptr_stack;
|
|
||||||
|
|
||||||
if (desc->Type == D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL)
|
|
||||||
{
|
|
||||||
memset(info->geometries, 0, sizeof(*info->geometries));
|
|
||||||
info->geometries[0].sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR;
|
|
||||||
info->geometries[0].geometryType = VK_GEOMETRY_TYPE_INSTANCES_KHR;
|
|
||||||
info->geometries[0].geometry.instances.sType =
|
|
||||||
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_INSTANCES_DATA_KHR;
|
|
||||||
info->geometries[0].geometry.instances.arrayOfPointers =
|
|
||||||
desc->DescsLayout == D3D12_ELEMENTS_LAYOUT_ARRAY_OF_POINTERS ? VK_TRUE : VK_FALSE;
|
|
||||||
info->geometries[0].geometry.instances.data.deviceAddress = desc->InstanceDescs;
|
|
||||||
|
|
||||||
info->primitive_counts = info->primitive_counts_stack;
|
|
||||||
info->primitive_counts[0] = desc->NumDescs;
|
|
||||||
build_info->geometryCount = 1;
|
|
||||||
RT_TRACE(" ArrayOfPointers: %u.\n",
|
|
||||||
desc->DescsLayout == D3D12_ELEMENTS_LAYOUT_ARRAY_OF_POINTERS ? 1 : 0);
|
|
||||||
RT_TRACE(" NumDescs: %u.\n", info->primitive_counts[0]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
have_triangles = false;
|
|
||||||
have_aabbs = false;
|
|
||||||
|
|
||||||
if (desc->NumDescs <= VKD3D_BUILD_INFO_STACK_COUNT)
|
|
||||||
{
|
|
||||||
memset(info->geometries, 0, sizeof(*info->geometries) * desc->NumDescs);
|
|
||||||
memset(info->primitive_counts, 0, sizeof(*info->primitive_counts) * desc->NumDescs);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
info->geometries = vkd3d_calloc(desc->NumDescs, sizeof(*info->geometries));
|
|
||||||
info->primitive_counts = vkd3d_calloc(desc->NumDescs, sizeof(*info->primitive_counts));
|
|
||||||
info->build_ranges = vkd3d_malloc(desc->NumDescs * sizeof(*info->build_ranges));
|
|
||||||
info->build_range_ptrs = vkd3d_malloc(desc->NumDescs * sizeof(*info->build_range_ptrs));
|
|
||||||
}
|
|
||||||
build_info->geometryCount = desc->NumDescs;
|
|
||||||
|
|
||||||
for (i = 0; i < desc->NumDescs; i++)
|
|
||||||
{
|
|
||||||
info->geometries[i].sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR;
|
|
||||||
RT_TRACE(" Geom %u:\n", i);
|
|
||||||
|
|
||||||
if (desc->DescsLayout == D3D12_ELEMENTS_LAYOUT_ARRAY_OF_POINTERS)
|
|
||||||
{
|
|
||||||
geom_desc = desc->ppGeometryDescs[i];
|
|
||||||
RT_TRACE(" ArrayOfPointers\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
geom_desc = &desc->pGeometryDescs[i];
|
|
||||||
RT_TRACE(" PointerToArray\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
info->geometries[i].flags = d3d12_geometry_flags_to_vk(geom_desc->Flags);
|
|
||||||
RT_TRACE(" Flags = #%x\n", geom_desc->Flags);
|
|
||||||
|
|
||||||
switch (geom_desc->Type)
|
|
||||||
{
|
|
||||||
case D3D12_RAYTRACING_GEOMETRY_TYPE_TRIANGLES:
|
|
||||||
/* Runtime validates this. */
|
|
||||||
if (have_aabbs)
|
|
||||||
{
|
|
||||||
ERR("Cannot mix and match geometry types in a BLAS.\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
have_triangles = true;
|
|
||||||
|
|
||||||
info->geometries[i].geometryType = VK_GEOMETRY_TYPE_TRIANGLES_KHR;
|
|
||||||
triangles = &info->geometries[i].geometry.triangles;
|
|
||||||
triangles->sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR;
|
|
||||||
triangles->indexData.deviceAddress = geom_desc->Triangles.IndexBuffer;
|
|
||||||
if (geom_desc->Triangles.IndexFormat != DXGI_FORMAT_UNKNOWN)
|
|
||||||
{
|
|
||||||
if (!geom_desc->Triangles.IndexBuffer)
|
|
||||||
WARN("Application is using IndexBuffer = 0 and IndexFormat != UNKNOWN. Likely application bug.\n");
|
|
||||||
|
|
||||||
triangles->indexType =
|
|
||||||
geom_desc->Triangles.IndexFormat == DXGI_FORMAT_R16_UINT ?
|
|
||||||
VK_INDEX_TYPE_UINT16 : VK_INDEX_TYPE_UINT32;
|
|
||||||
info->primitive_counts[i] = geom_desc->Triangles.IndexCount / 3;
|
|
||||||
RT_TRACE(" Indexed : Index count = %u (%u bits)\n",
|
|
||||||
geom_desc->Triangles.IndexCount,
|
|
||||||
triangles->indexType == VK_INDEX_TYPE_UINT16 ? 16 : 32);
|
|
||||||
RT_TRACE(" Vertex count: %u\n", geom_desc->Triangles.VertexCount);
|
|
||||||
RT_TRACE(" IBO VA: %"PRIx64".\n", geom_desc->Triangles.IndexBuffer);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
info->primitive_counts[i] = geom_desc->Triangles.VertexCount / 3;
|
|
||||||
triangles->indexType = VK_INDEX_TYPE_NONE_KHR;
|
|
||||||
RT_TRACE(" Triangle list : Vertex count: %u\n", geom_desc->Triangles.VertexCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
triangles->maxVertex = max(1, geom_desc->Triangles.VertexCount) - 1;
|
|
||||||
triangles->vertexStride = geom_desc->Triangles.VertexBuffer.StrideInBytes;
|
|
||||||
triangles->vertexFormat = vkd3d_internal_get_vk_format(device, geom_desc->Triangles.VertexFormat);
|
|
||||||
triangles->vertexData.deviceAddress = geom_desc->Triangles.VertexBuffer.StartAddress;
|
|
||||||
triangles->transformData.deviceAddress = geom_desc->Triangles.Transform3x4;
|
|
||||||
|
|
||||||
RT_TRACE(" Transform3x4: %s\n", geom_desc->Triangles.Transform3x4 ? "on" : "off");
|
|
||||||
RT_TRACE(" Vertex format: %s\n", debug_dxgi_format(geom_desc->Triangles.VertexFormat));
|
|
||||||
RT_TRACE(" VBO VA: %"PRIx64"\n", geom_desc->Triangles.VertexBuffer.StartAddress);
|
|
||||||
RT_TRACE(" Vertex stride: %"PRIu64" bytes\n", geom_desc->Triangles.VertexBuffer.StrideInBytes);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case D3D12_RAYTRACING_GEOMETRY_TYPE_PROCEDURAL_PRIMITIVE_AABBS:
|
|
||||||
/* Runtime validates this. */
|
|
||||||
if (have_triangles)
|
|
||||||
{
|
|
||||||
ERR("Cannot mix and match geometry types in a BLAS.\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
have_aabbs = true;
|
|
||||||
|
|
||||||
info->geometries[i].geometryType = VK_GEOMETRY_TYPE_AABBS_KHR;
|
|
||||||
aabbs = &info->geometries[i].geometry.aabbs;
|
|
||||||
aabbs->sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_AABBS_DATA_KHR;
|
|
||||||
aabbs->stride = geom_desc->AABBs.AABBs.StrideInBytes;
|
|
||||||
aabbs->data.deviceAddress = geom_desc->AABBs.AABBs.StartAddress;
|
|
||||||
info->primitive_counts[i] = geom_desc->AABBs.AABBCount;
|
|
||||||
RT_TRACE(" AABB stride: %"PRIu64" bytes\n", geom_desc->AABBs.AABBs.StrideInBytes);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
FIXME("Unsupported geometry type %u.\n", geom_desc->Type);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
RT_TRACE(" Primitive count %u.\n", info->primitive_counts[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < build_info->geometryCount; i++)
|
|
||||||
{
|
|
||||||
info->build_range_ptrs[i] = &info->build_ranges[i];
|
|
||||||
info->build_ranges[i].primitiveCount = info->primitive_counts[i];
|
|
||||||
info->build_ranges[i].firstVertex = 0;
|
|
||||||
info->build_ranges[i].primitiveOffset = 0;
|
|
||||||
info->build_ranges[i].transformOffset = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
build_info->pGeometries = info->geometries;
|
|
||||||
|
|
||||||
RT_TRACE("=====================\n");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void vkd3d_acceleration_structure_end_barrier(struct d3d12_command_list *list)
|
|
||||||
{
|
|
||||||
/* We resolve the query in TRANSFER, but DXR expects UNORDERED_ACCESS. */
|
|
||||||
const struct vkd3d_vk_device_procs *vk_procs = &list->device->vk_procs;
|
|
||||||
VkMemoryBarrier barrier;
|
|
||||||
|
|
||||||
barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
|
|
||||||
barrier.pNext = NULL;
|
|
||||||
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
|
||||||
barrier.dstAccessMask = 0;
|
|
||||||
|
|
||||||
VK_CALL(vkCmdPipelineBarrier(list->vk_command_buffer,
|
|
||||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
|
||||||
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0,
|
|
||||||
1, &barrier, 0, NULL, 0, NULL));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void vkd3d_acceleration_structure_write_postbuild_info(
|
|
||||||
struct d3d12_command_list *list,
|
|
||||||
const D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_DESC *desc,
|
|
||||||
VkDeviceSize desc_offset,
|
|
||||||
VkAccelerationStructureKHR vk_acceleration_structure)
|
|
||||||
{
|
|
||||||
const struct vkd3d_vk_device_procs *vk_procs = &list->device->vk_procs;
|
|
||||||
const struct vkd3d_unique_resource *resource;
|
|
||||||
VkQueryPool vk_query_pool;
|
|
||||||
VkQueryType vk_query_type;
|
|
||||||
uint32_t vk_query_index;
|
|
||||||
VkDeviceSize stride;
|
|
||||||
uint32_t type_index;
|
|
||||||
VkBuffer vk_buffer;
|
|
||||||
uint32_t offset;
|
|
||||||
|
|
||||||
resource = vkd3d_va_map_deref(&list->device->memory_allocator.va_map, desc->DestBuffer);
|
|
||||||
if (!resource)
|
|
||||||
{
|
|
||||||
ERR("Invalid resource.\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
vk_buffer = resource->vk_buffer;
|
|
||||||
offset = desc->DestBuffer - resource->va;
|
|
||||||
offset += desc_offset;
|
|
||||||
|
|
||||||
if (desc->InfoType == D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_COMPACTED_SIZE)
|
|
||||||
{
|
|
||||||
vk_query_type = VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR;
|
|
||||||
type_index = VKD3D_QUERY_TYPE_INDEX_RT_COMPACTED_SIZE;
|
|
||||||
stride = sizeof(uint64_t);
|
|
||||||
}
|
|
||||||
else if (desc->InfoType == D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_CURRENT_SIZE &&
|
|
||||||
list->device->device_info.ray_tracing_maintenance1_features.rayTracingMaintenance1)
|
|
||||||
{
|
|
||||||
vk_query_type = VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SIZE_KHR;
|
|
||||||
type_index = VKD3D_QUERY_TYPE_INDEX_RT_CURRENT_SIZE;
|
|
||||||
stride = sizeof(uint64_t);
|
|
||||||
}
|
|
||||||
else if (desc->InfoType == D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_SERIALIZATION)
|
|
||||||
{
|
|
||||||
vk_query_type = VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR;
|
|
||||||
type_index = VKD3D_QUERY_TYPE_INDEX_RT_SERIALIZE_SIZE;
|
|
||||||
stride = sizeof(uint64_t);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FIXME("Unsupported InfoType %u.\n", desc->InfoType);
|
|
||||||
/* TODO: CURRENT_SIZE is something we cannot query in Vulkan, so
|
|
||||||
* we'll need to keep around a buffer to handle this.
|
|
||||||
* For now, just clear to 0. */
|
|
||||||
VK_CALL(vkCmdFillBuffer(list->vk_command_buffer, vk_buffer, offset,
|
|
||||||
sizeof(uint64_t), 0));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!d3d12_command_allocator_allocate_query_from_type_index(list->allocator,
|
|
||||||
type_index, &vk_query_pool, &vk_query_index))
|
|
||||||
{
|
|
||||||
ERR("Failed to allocate query.\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
d3d12_command_list_reset_query(list, vk_query_pool, vk_query_index);
|
|
||||||
|
|
||||||
VK_CALL(vkCmdWriteAccelerationStructuresPropertiesKHR(list->vk_command_buffer,
|
|
||||||
1, &vk_acceleration_structure, vk_query_type, vk_query_pool, vk_query_index));
|
|
||||||
VK_CALL(vkCmdCopyQueryPoolResults(list->vk_command_buffer,
|
|
||||||
vk_query_pool, vk_query_index, 1,
|
|
||||||
vk_buffer, offset, stride,
|
|
||||||
VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT));
|
|
||||||
|
|
||||||
if (desc->InfoType == D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_SERIALIZATION)
|
|
||||||
{
|
|
||||||
if (list->device->device_info.ray_tracing_maintenance1_features.rayTracingMaintenance1)
|
|
||||||
{
|
|
||||||
type_index = VKD3D_QUERY_TYPE_INDEX_RT_SERIALIZE_SIZE_BOTTOM_LEVEL_POINTERS;
|
|
||||||
if (!d3d12_command_allocator_allocate_query_from_type_index(list->allocator,
|
|
||||||
type_index, &vk_query_pool, &vk_query_index))
|
|
||||||
{
|
|
||||||
ERR("Failed to allocate query.\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
d3d12_command_list_reset_query(list, vk_query_pool, vk_query_index);
|
|
||||||
|
|
||||||
VK_CALL(vkCmdWriteAccelerationStructuresPropertiesKHR(list->vk_command_buffer,
|
|
||||||
1, &vk_acceleration_structure, vk_query_type, vk_query_pool, vk_query_index));
|
|
||||||
VK_CALL(vkCmdCopyQueryPoolResults(list->vk_command_buffer,
|
|
||||||
vk_query_pool, vk_query_index, 1,
|
|
||||||
vk_buffer, offset + sizeof(uint64_t), stride,
|
|
||||||
VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FIXME("NumBottomLevelPointers will always return 0.\n");
|
|
||||||
VK_CALL(vkCmdFillBuffer(list->vk_command_buffer, vk_buffer, offset + sizeof(uint64_t),
|
|
||||||
sizeof(uint64_t), 0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void vkd3d_acceleration_structure_emit_postbuild_info(
|
|
||||||
struct d3d12_command_list *list,
|
|
||||||
const D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_DESC *desc,
|
|
||||||
uint32_t count,
|
|
||||||
const D3D12_GPU_VIRTUAL_ADDRESS *addresses)
|
|
||||||
{
|
|
||||||
const struct vkd3d_vk_device_procs *vk_procs = &list->device->vk_procs;
|
|
||||||
VkAccelerationStructureKHR vk_acceleration_structure;
|
|
||||||
VkMemoryBarrier barrier;
|
|
||||||
VkDeviceSize stride;
|
|
||||||
uint32_t i;
|
|
||||||
|
|
||||||
barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
|
|
||||||
barrier.pNext = NULL;
|
|
||||||
barrier.srcAccessMask = 0;
|
|
||||||
barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
|
||||||
|
|
||||||
/* We resolve the query in TRANSFER, but DXR expects UNORDERED_ACCESS. */
|
|
||||||
VK_CALL(vkCmdPipelineBarrier(list->vk_command_buffer,
|
|
||||||
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
|
|
||||||
VK_PIPELINE_STAGE_TRANSFER_BIT, 0,
|
|
||||||
1, &barrier, 0, NULL, 0, NULL));
|
|
||||||
|
|
||||||
stride = desc->InfoType == D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_SERIALIZATION ?
|
|
||||||
2 * sizeof(uint64_t) : sizeof(uint64_t);
|
|
||||||
|
|
||||||
for (i = 0; i < count; i++)
|
|
||||||
{
|
|
||||||
vk_acceleration_structure = vkd3d_va_map_place_acceleration_structure(
|
|
||||||
&list->device->memory_allocator.va_map, list->device, addresses[i]);
|
|
||||||
if (vk_acceleration_structure)
|
|
||||||
vkd3d_acceleration_structure_write_postbuild_info(list, desc, i * stride, vk_acceleration_structure);
|
|
||||||
else
|
|
||||||
ERR("Failed to query acceleration structure for VA 0x%"PRIx64".\n", addresses[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
vkd3d_acceleration_structure_end_barrier(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
void vkd3d_acceleration_structure_emit_immediate_postbuild_info(
|
|
||||||
struct d3d12_command_list *list, uint32_t count,
|
|
||||||
const D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_DESC *desc,
|
|
||||||
VkAccelerationStructureKHR vk_acceleration_structure)
|
|
||||||
{
|
|
||||||
/* In D3D12 we are supposed to be able to emit without an explicit barrier,
|
|
||||||
* but we need to emit them for Vulkan. */
|
|
||||||
|
|
||||||
const struct vkd3d_vk_device_procs *vk_procs = &list->device->vk_procs;
|
|
||||||
VkMemoryBarrier barrier;
|
|
||||||
uint32_t i;
|
|
||||||
|
|
||||||
barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
|
|
||||||
barrier.pNext = NULL;
|
|
||||||
barrier.srcAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR;
|
|
||||||
/* The query accesses STRUCTURE_READ_BIT in BUILD_BIT stage. */
|
|
||||||
barrier.dstAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_TRANSFER_WRITE_BIT;
|
|
||||||
|
|
||||||
/* Writing to the result buffer is supposed to happen in UNORDERED_ACCESS on DXR for
|
|
||||||
* some bizarre reason, so we have to satisfy a transfer barrier.
|
|
||||||
* Have to basically do a full stall to make this work ... */
|
|
||||||
VK_CALL(vkCmdPipelineBarrier(list->vk_command_buffer,
|
|
||||||
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
|
|
||||||
VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR | VK_PIPELINE_STAGE_TRANSFER_BIT, 0,
|
|
||||||
1, &barrier, 0, NULL, 0, NULL));
|
|
||||||
|
|
||||||
/* Could optimize a bit by batching more aggressively, but no idea if it's going to help in practice. */
|
|
||||||
for (i = 0; i < count; i++)
|
|
||||||
vkd3d_acceleration_structure_write_postbuild_info(list, &desc[i], 0, vk_acceleration_structure);
|
|
||||||
|
|
||||||
vkd3d_acceleration_structure_end_barrier(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool convert_copy_mode(
|
|
||||||
D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE mode,
|
|
||||||
VkCopyAccelerationStructureModeKHR *vk_mode)
|
|
||||||
{
|
|
||||||
switch (mode)
|
|
||||||
{
|
|
||||||
case D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE_CLONE:
|
|
||||||
*vk_mode = VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_KHR;
|
|
||||||
return true;
|
|
||||||
case D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE_COMPACT:
|
|
||||||
*vk_mode = VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_KHR;
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
FIXME("Unsupported RTAS copy mode #%x.\n", mode);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void vkd3d_acceleration_structure_copy(
|
|
||||||
struct d3d12_command_list *list,
|
|
||||||
D3D12_GPU_VIRTUAL_ADDRESS dst, D3D12_GPU_VIRTUAL_ADDRESS src,
|
|
||||||
D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE mode)
|
|
||||||
{
|
|
||||||
const struct vkd3d_vk_device_procs *vk_procs = &list->device->vk_procs;
|
|
||||||
VkAccelerationStructureKHR dst_as, src_as;
|
|
||||||
VkCopyAccelerationStructureInfoKHR info;
|
|
||||||
|
|
||||||
dst_as = vkd3d_va_map_place_acceleration_structure(&list->device->memory_allocator.va_map, list->device, dst);
|
|
||||||
if (dst_as == VK_NULL_HANDLE)
|
|
||||||
{
|
|
||||||
ERR("Invalid dst address #%"PRIx64" for RTAS copy.\n", dst);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
src_as = vkd3d_va_map_place_acceleration_structure(&list->device->memory_allocator.va_map, list->device, src);
|
|
||||||
if (src_as == VK_NULL_HANDLE)
|
|
||||||
{
|
|
||||||
ERR("Invalid src address #%"PRIx64" for RTAS copy.\n", src);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
info.sType = VK_STRUCTURE_TYPE_COPY_ACCELERATION_STRUCTURE_INFO_KHR;
|
|
||||||
info.pNext = NULL;
|
|
||||||
info.dst = dst_as;
|
|
||||||
info.src = src_as;
|
|
||||||
if (convert_copy_mode(mode, &info.mode))
|
|
||||||
VK_CALL(vkCmdCopyAccelerationStructureKHR(list->vk_command_buffer, &info));
|
|
||||||
}
|
|
|
@ -1,655 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2022 Hans-Kristian Arntzen for Valve Corporation
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define VKD3D_DBG_CHANNEL VKD3D_DBG_CHANNEL_API
|
|
||||||
|
|
||||||
#include "vkd3d_private.h"
|
|
||||||
#include "vkd3d_debug.h"
|
|
||||||
#include "vkd3d_common.h"
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
/* Just allocate everything up front. This only consumes host memory anyways. */
|
|
||||||
#define MAX_COMMAND_LISTS (32 * 1024)
|
|
||||||
|
|
||||||
/* Questionable on 32-bit, but we don't really care. */
|
|
||||||
#define NV_ENCODE_CHECKPOINT(context, counter) ((void*) ((uintptr_t)(context) + (uintptr_t)MAX_COMMAND_LISTS * (counter)))
|
|
||||||
#define NV_CHECKPOINT_CONTEXT(ptr) ((uint32_t)((uintptr_t)(ptr) % MAX_COMMAND_LISTS))
|
|
||||||
#define NV_CHECKPOINT_COUNTER(ptr) ((uint32_t)((uintptr_t)(ptr) / MAX_COMMAND_LISTS))
|
|
||||||
|
|
||||||
static const char *vkd3d_breadcrumb_command_type_to_str(enum vkd3d_breadcrumb_command_type type)
|
|
||||||
{
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case VKD3D_BREADCRUMB_COMMAND_SET_TOP_MARKER:
|
|
||||||
return "top_marker";
|
|
||||||
case VKD3D_BREADCRUMB_COMMAND_SET_BOTTOM_MARKER:
|
|
||||||
return "bottom_marker";
|
|
||||||
case VKD3D_BREADCRUMB_COMMAND_SET_SHADER_HASH:
|
|
||||||
return "set_shader_hash";
|
|
||||||
case VKD3D_BREADCRUMB_COMMAND_DRAW:
|
|
||||||
return "draw";
|
|
||||||
case VKD3D_BREADCRUMB_COMMAND_DRAW_INDEXED:
|
|
||||||
return "draw_indexed";
|
|
||||||
case VKD3D_BREADCRUMB_COMMAND_DISPATCH:
|
|
||||||
return "dispatch";
|
|
||||||
case VKD3D_BREADCRUMB_COMMAND_EXECUTE_INDIRECT:
|
|
||||||
return "execute_indirect";
|
|
||||||
case VKD3D_BREADCRUMB_COMMAND_EXECUTE_INDIRECT_TEMPLATE:
|
|
||||||
return "execute_indirect_template";
|
|
||||||
case VKD3D_BREADCRUMB_COMMAND_COPY:
|
|
||||||
return "copy";
|
|
||||||
case VKD3D_BREADCRUMB_COMMAND_RESOLVE:
|
|
||||||
return "resolve";
|
|
||||||
case VKD3D_BREADCRUMB_COMMAND_WBI:
|
|
||||||
return "wbi";
|
|
||||||
case VKD3D_BREADCRUMB_COMMAND_RESOLVE_QUERY:
|
|
||||||
return "resolve_query";
|
|
||||||
case VKD3D_BREADCRUMB_COMMAND_GATHER_VIRTUAL_QUERY:
|
|
||||||
return "gather_virtual_query";
|
|
||||||
case VKD3D_BREADCRUMB_COMMAND_BUILD_RTAS:
|
|
||||||
return "build_rtas";
|
|
||||||
case VKD3D_BREADCRUMB_COMMAND_COPY_RTAS:
|
|
||||||
return "copy_rtas";
|
|
||||||
case VKD3D_BREADCRUMB_COMMAND_EMIT_RTAS_POSTBUILD:
|
|
||||||
return "emit_rtas_postbuild";
|
|
||||||
case VKD3D_BREADCRUMB_COMMAND_TRACE_RAYS:
|
|
||||||
return "trace_rays";
|
|
||||||
case VKD3D_BREADCRUMB_COMMAND_BARRIER:
|
|
||||||
return "barrier";
|
|
||||||
case VKD3D_BREADCRUMB_COMMAND_AUX32:
|
|
||||||
return "aux32";
|
|
||||||
case VKD3D_BREADCRUMB_COMMAND_AUX64:
|
|
||||||
return "aux64";
|
|
||||||
case VKD3D_BREADCRUMB_COMMAND_VBO:
|
|
||||||
return "vbo";
|
|
||||||
case VKD3D_BREADCRUMB_COMMAND_IBO:
|
|
||||||
return "ibo";
|
|
||||||
case VKD3D_BREADCRUMB_COMMAND_ROOT_DESC:
|
|
||||||
return "root_desc";
|
|
||||||
case VKD3D_BREADCRUMB_COMMAND_ROOT_CONST:
|
|
||||||
return "root_const";
|
|
||||||
case VKD3D_BREADCRUMB_COMMAND_TAG:
|
|
||||||
return "tag";
|
|
||||||
|
|
||||||
default:
|
|
||||||
return "?";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT vkd3d_breadcrumb_tracer_init(struct vkd3d_breadcrumb_tracer *tracer, struct d3d12_device *device)
|
|
||||||
{
|
|
||||||
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
|
||||||
D3D12_HEAP_PROPERTIES heap_properties;
|
|
||||||
D3D12_RESOURCE_DESC1 resource_desc;
|
|
||||||
VkMemoryPropertyFlags memory_props;
|
|
||||||
HRESULT hr;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
memset(tracer, 0, sizeof(*tracer));
|
|
||||||
|
|
||||||
if ((rc = pthread_mutex_init(&tracer->lock, NULL)))
|
|
||||||
return hresult_from_errno(rc);
|
|
||||||
|
|
||||||
if (device->vk_info.AMD_buffer_marker)
|
|
||||||
{
|
|
||||||
INFO("Enabling AMD_buffer_marker breadcrumbs.\n");
|
|
||||||
memset(&resource_desc, 0, sizeof(resource_desc));
|
|
||||||
resource_desc.Width = MAX_COMMAND_LISTS * sizeof(struct vkd3d_breadcrumb_counter);
|
|
||||||
resource_desc.Height = 1;
|
|
||||||
resource_desc.DepthOrArraySize = 1;
|
|
||||||
resource_desc.MipLevels = 1;
|
|
||||||
resource_desc.Format = DXGI_FORMAT_UNKNOWN;
|
|
||||||
resource_desc.SampleDesc.Count = 1;
|
|
||||||
resource_desc.SampleDesc.Quality = 0;
|
|
||||||
resource_desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
|
|
||||||
resource_desc.Flags = D3D12_RESOURCE_FLAG_NONE;
|
|
||||||
|
|
||||||
if (FAILED(hr = vkd3d_create_buffer(device, &heap_properties, D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS,
|
|
||||||
&resource_desc, &tracer->host_buffer)))
|
|
||||||
{
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
memory_props = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT |
|
|
||||||
VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
|
|
||||||
|
|
||||||
/* If device faults in the middle of execution we will never get the chance to flush device caches.
|
|
||||||
* Make sure that breadcrumbs are always written directly out.
|
|
||||||
* This is the primary usecase for the device coherent/uncached extension after all ...
|
|
||||||
* Don't make this a hard requirement since buffer markers might be implicitly coherent on some
|
|
||||||
* implementations (Turnip?). */
|
|
||||||
if (device->device_info.device_coherent_memory_features_amd.deviceCoherentMemory)
|
|
||||||
{
|
|
||||||
memory_props |= VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD |
|
|
||||||
VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FAILED(hr = vkd3d_allocate_buffer_memory(device, tracer->host_buffer,
|
|
||||||
memory_props, &tracer->host_buffer_memory)))
|
|
||||||
{
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (VK_CALL(vkMapMemory(device->vk_device, tracer->host_buffer_memory.vk_memory,
|
|
||||||
0, VK_WHOLE_SIZE,
|
|
||||||
0, (void**)&tracer->mapped)) != VK_SUCCESS)
|
|
||||||
{
|
|
||||||
hr = E_OUTOFMEMORY;
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(tracer->mapped, 0, sizeof(*tracer->mapped) * MAX_COMMAND_LISTS);
|
|
||||||
}
|
|
||||||
else if (device->vk_info.NV_device_diagnostic_checkpoints)
|
|
||||||
{
|
|
||||||
INFO("Enabling NV_device_diagnostics_checkpoints breadcrumbs.\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ERR("Breadcrumbs require support for either AMD_buffer_marker or NV_device_diagnostics_checkpoints.\n");
|
|
||||||
hr = E_FAIL;
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
tracer->trace_contexts = vkd3d_calloc(MAX_COMMAND_LISTS, sizeof(*tracer->trace_contexts));
|
|
||||||
tracer->trace_context_index = 0;
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
|
|
||||||
err:
|
|
||||||
vkd3d_breadcrumb_tracer_cleanup(tracer, device);
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void vkd3d_breadcrumb_tracer_cleanup(struct vkd3d_breadcrumb_tracer *tracer, struct d3d12_device *device)
|
|
||||||
{
|
|
||||||
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
|
||||||
|
|
||||||
if (device->vk_info.AMD_buffer_marker)
|
|
||||||
{
|
|
||||||
VK_CALL(vkDestroyBuffer(device->vk_device, tracer->host_buffer, NULL));
|
|
||||||
vkd3d_free_device_memory(device, &tracer->host_buffer_memory);
|
|
||||||
}
|
|
||||||
|
|
||||||
vkd3d_free(tracer->trace_contexts);
|
|
||||||
pthread_mutex_destroy(&tracer->lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int vkd3d_breadcrumb_tracer_allocate_command_list(struct vkd3d_breadcrumb_tracer *tracer,
|
|
||||||
struct d3d12_command_list *list, struct d3d12_command_allocator *allocator)
|
|
||||||
{
|
|
||||||
unsigned int index = UINT32_MAX;
|
|
||||||
unsigned int iteration_count;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
if ((rc = pthread_mutex_lock(&tracer->lock)))
|
|
||||||
{
|
|
||||||
ERR("Failed to lock mutex, rc %d.\n", rc);
|
|
||||||
return UINT32_MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Since this is a ring, this is extremely likely to succeed on first attempt. */
|
|
||||||
for (iteration_count = 0; iteration_count < MAX_COMMAND_LISTS; iteration_count++)
|
|
||||||
{
|
|
||||||
tracer->trace_context_index = (tracer->trace_context_index + 1) % MAX_COMMAND_LISTS;
|
|
||||||
if (!tracer->trace_contexts[tracer->trace_context_index].locked)
|
|
||||||
{
|
|
||||||
tracer->trace_contexts[tracer->trace_context_index].locked = 1;
|
|
||||||
index = tracer->trace_context_index;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_mutex_unlock(&tracer->lock);
|
|
||||||
|
|
||||||
if (index == UINT32_MAX)
|
|
||||||
{
|
|
||||||
ERR("Failed to allocate new index for command list.\n");
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
TRACE("Allocating breadcrumb context %u for list %p.\n", index, list);
|
|
||||||
list->breadcrumb_context_index = index;
|
|
||||||
|
|
||||||
/* Need to clear this on a fresh allocation rather than release, since we can end up releasing a command list
|
|
||||||
* before we observe the device lost. */
|
|
||||||
tracer->trace_contexts[index].command_count = 0;
|
|
||||||
tracer->trace_contexts[index].counter = 0;
|
|
||||||
|
|
||||||
if (list->device->vk_info.AMD_buffer_marker)
|
|
||||||
memset(&tracer->mapped[index], 0, sizeof(tracer->mapped[index]));
|
|
||||||
|
|
||||||
vkd3d_array_reserve((void**)&allocator->breadcrumb_context_indices, &allocator->breadcrumb_context_index_size,
|
|
||||||
allocator->breadcrumb_context_index_count + 1,
|
|
||||||
sizeof(*allocator->breadcrumb_context_indices));
|
|
||||||
allocator->breadcrumb_context_indices[allocator->breadcrumb_context_index_count++] = index;
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Command allocator keeps a list of allocated breadcrumb command lists. */
|
|
||||||
void vkd3d_breadcrumb_tracer_release_command_lists(struct vkd3d_breadcrumb_tracer *tracer,
|
|
||||||
const unsigned int *indices, size_t indices_count)
|
|
||||||
{
|
|
||||||
unsigned int index;
|
|
||||||
size_t i;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
if (!indices_count)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if ((rc = pthread_mutex_lock(&tracer->lock)))
|
|
||||||
{
|
|
||||||
ERR("Failed to lock mutex, rc %d.\n", rc);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < indices_count; i++)
|
|
||||||
{
|
|
||||||
index = indices[i];
|
|
||||||
if (index != UINT32_MAX)
|
|
||||||
tracer->trace_contexts[index].locked = 0;
|
|
||||||
TRACE("Releasing breadcrumb context %u.\n", index);
|
|
||||||
}
|
|
||||||
pthread_mutex_unlock(&tracer->lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void vkd3d_breadcrumb_tracer_report_command_list(
|
|
||||||
const struct vkd3d_breadcrumb_command_list_trace_context *context,
|
|
||||||
uint32_t begin_marker,
|
|
||||||
uint32_t end_marker)
|
|
||||||
{
|
|
||||||
const struct vkd3d_breadcrumb_command *cmd;
|
|
||||||
bool observed_begin_cmd = false;
|
|
||||||
bool observed_end_cmd = false;
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
if (end_marker == 0)
|
|
||||||
{
|
|
||||||
ERR(" ===== Potential crash region BEGIN (make sure RADV_DEBUG=syncshaders is used for maximum accuracy) =====\n");
|
|
||||||
observed_begin_cmd = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We can assume that possible culprit commands lie between the end_marker
|
|
||||||
* and top_marker. */
|
|
||||||
for (i = 0; i < context->command_count; i++)
|
|
||||||
{
|
|
||||||
cmd = &context->commands[i];
|
|
||||||
|
|
||||||
/* If there is a command which sets TOP_OF_PIPE, but we haven't observed the marker yet,
|
|
||||||
* the command processor hasn't gotten there yet (most likely ...), so that should be the
|
|
||||||
* natural end-point. */
|
|
||||||
if (!observed_end_cmd &&
|
|
||||||
cmd->type == VKD3D_BREADCRUMB_COMMAND_SET_TOP_MARKER &&
|
|
||||||
cmd->count > begin_marker)
|
|
||||||
{
|
|
||||||
observed_end_cmd = true;
|
|
||||||
ERR(" ===== Potential crash region END =====\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cmd->type == VKD3D_BREADCRUMB_COMMAND_AUX32)
|
|
||||||
{
|
|
||||||
ERR(" Set arg: %u (#%x)\n", cmd->word_32bit, cmd->word_32bit);
|
|
||||||
}
|
|
||||||
else if (cmd->type == VKD3D_BREADCRUMB_COMMAND_AUX64)
|
|
||||||
{
|
|
||||||
ERR(" Set arg: %"PRIu64" (#%"PRIx64")\n", cmd->word_64bit, cmd->word_64bit);
|
|
||||||
}
|
|
||||||
else if (cmd->type == VKD3D_BREADCRUMB_COMMAND_TAG)
|
|
||||||
{
|
|
||||||
ERR(" Tag: %s\n", cmd->tag);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ERR(" Command: %s\n", vkd3d_breadcrumb_command_type_to_str(cmd->type));
|
|
||||||
|
|
||||||
switch (cmd->type)
|
|
||||||
{
|
|
||||||
case VKD3D_BREADCRUMB_COMMAND_SET_TOP_MARKER:
|
|
||||||
case VKD3D_BREADCRUMB_COMMAND_SET_BOTTOM_MARKER:
|
|
||||||
ERR(" marker: %u\n", cmd->count);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case VKD3D_BREADCRUMB_COMMAND_SET_SHADER_HASH:
|
|
||||||
ERR(" hash: %016"PRIx64", stage: %x\n", cmd->shader.hash, cmd->shader.stage);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We have proved we observed this command is complete.
|
|
||||||
* Some command after this signal is at fault. */
|
|
||||||
if (!observed_begin_cmd &&
|
|
||||||
cmd->type == VKD3D_BREADCRUMB_COMMAND_SET_BOTTOM_MARKER &&
|
|
||||||
cmd->count == end_marker)
|
|
||||||
{
|
|
||||||
observed_begin_cmd = true;
|
|
||||||
ERR(" ===== Potential crash region BEGIN (make sure RADV_DEBUG=syncshaders is used for maximum accuracy) =====\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void vkd3d_breadcrumb_tracer_report_command_list_amd(struct vkd3d_breadcrumb_tracer *tracer,
|
|
||||||
unsigned int context_index)
|
|
||||||
{
|
|
||||||
const struct vkd3d_breadcrumb_command_list_trace_context *context;
|
|
||||||
uint32_t begin_marker;
|
|
||||||
uint32_t end_marker;
|
|
||||||
|
|
||||||
context = &tracer->trace_contexts[context_index];
|
|
||||||
|
|
||||||
/* Unused, cannot be the cause. */
|
|
||||||
if (context->counter == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
begin_marker = tracer->mapped[context_index].begin_marker;
|
|
||||||
end_marker = tracer->mapped[context_index].end_marker;
|
|
||||||
|
|
||||||
/* Never executed, cannot be the cause. */
|
|
||||||
if (begin_marker == 0 && end_marker == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Successfully retired, cannot be the cause. */
|
|
||||||
if (begin_marker == UINT32_MAX && end_marker == UINT32_MAX)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Edge case if we re-submitted a command list,
|
|
||||||
* but it ends up crashing before we hit any BOTTOM_OF_PIPE
|
|
||||||
* marker. Normalize the inputs such that end_marker <= begin_marker. */
|
|
||||||
if (begin_marker > 0 && end_marker == UINT32_MAX)
|
|
||||||
end_marker = 0;
|
|
||||||
|
|
||||||
ERR("Found pending command list context %u in executable state, TOP_OF_PIPE marker %u, BOTTOM_OF_PIPE marker %u.\n",
|
|
||||||
context_index, begin_marker, end_marker);
|
|
||||||
vkd3d_breadcrumb_tracer_report_command_list(context, begin_marker, end_marker);
|
|
||||||
ERR("Done analyzing command list.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void vkd3d_breadcrumb_tracer_report_queue_nv(struct vkd3d_breadcrumb_tracer *tracer,
|
|
||||||
struct d3d12_device *device,
|
|
||||||
VkQueue vk_queue)
|
|
||||||
{
|
|
||||||
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
|
||||||
uint32_t begin_marker, end_marker;
|
|
||||||
uint32_t checkpoint_context_index;
|
|
||||||
VkCheckpointDataNV *checkpoints;
|
|
||||||
uint32_t checkpoint_marker;
|
|
||||||
uint32_t checkpoint_count;
|
|
||||||
uint32_t context_index;
|
|
||||||
uint32_t i;
|
|
||||||
|
|
||||||
VK_CALL(vkGetQueueCheckpointDataNV(vk_queue, &checkpoint_count, NULL));
|
|
||||||
if (checkpoint_count == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
checkpoints = vkd3d_calloc(checkpoint_count, sizeof(VkCheckpointDataNV));
|
|
||||||
for (i = 0; i < checkpoint_count; i++)
|
|
||||||
checkpoints[i].sType = VK_STRUCTURE_TYPE_CHECKPOINT_DATA_NV;
|
|
||||||
VK_CALL(vkGetQueueCheckpointDataNV(vk_queue, &checkpoint_count, checkpoints));
|
|
||||||
|
|
||||||
context_index = UINT32_MAX;
|
|
||||||
begin_marker = 0;
|
|
||||||
end_marker = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < checkpoint_count; i++)
|
|
||||||
{
|
|
||||||
checkpoint_context_index = NV_CHECKPOINT_CONTEXT(checkpoints[i].pCheckpointMarker);
|
|
||||||
checkpoint_marker = NV_CHECKPOINT_COUNTER(checkpoints[i].pCheckpointMarker);
|
|
||||||
|
|
||||||
if (context_index != checkpoint_context_index && context_index != UINT32_MAX)
|
|
||||||
{
|
|
||||||
FIXME("Markers have different contexts. Execution is likely split across multiple command buffers?\n");
|
|
||||||
context_index = UINT32_MAX;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
context_index = checkpoint_context_index;
|
|
||||||
|
|
||||||
if (checkpoints[i].stage == VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT && checkpoint_marker > begin_marker)
|
|
||||||
{
|
|
||||||
/* We want to find the latest TOP_OF_PIPE_BIT. Then we prove that command processor got to that point. */
|
|
||||||
begin_marker = checkpoint_marker;
|
|
||||||
}
|
|
||||||
else if (checkpoints[i].stage == VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT && checkpoint_marker > end_marker)
|
|
||||||
{
|
|
||||||
/* We want to find the latest BOTTOM_OF_PIPE_BIT. Then we prove that we got that far. */
|
|
||||||
end_marker = checkpoint_marker;
|
|
||||||
}
|
|
||||||
else if (checkpoints[i].stage != VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT &&
|
|
||||||
checkpoints[i].stage != VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT)
|
|
||||||
{
|
|
||||||
FIXME("Unexpected checkpoint pipeline stage. #%x\n", checkpoints[i].stage);
|
|
||||||
context_index = UINT32_MAX;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (context_index != UINT32_MAX && begin_marker != 0 && end_marker != 0 && end_marker != UINT32_MAX)
|
|
||||||
{
|
|
||||||
ERR("Found pending command list context %u in executable state, TOP_OF_PIPE marker %u, BOTTOM_OF_PIPE marker %u.\n",
|
|
||||||
context_index, begin_marker, end_marker);
|
|
||||||
vkd3d_breadcrumb_tracer_report_command_list(&tracer->trace_contexts[context_index], begin_marker, end_marker);
|
|
||||||
ERR("Done analyzing command list.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
vkd3d_free(checkpoints);
|
|
||||||
}
|
|
||||||
|
|
||||||
void vkd3d_breadcrumb_tracer_report_device_lost(struct vkd3d_breadcrumb_tracer *tracer,
|
|
||||||
struct d3d12_device *device)
|
|
||||||
{
|
|
||||||
struct vkd3d_queue_family_info *queue_family_info;
|
|
||||||
VkQueue vk_queue;
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
ERR("Device lost observed, analyzing breadcrumbs ...\n");
|
|
||||||
|
|
||||||
if (device->vk_info.AMD_buffer_marker)
|
|
||||||
{
|
|
||||||
/* AMD path, buffer marker. */
|
|
||||||
for (i = 0; i < MAX_COMMAND_LISTS; i++)
|
|
||||||
vkd3d_breadcrumb_tracer_report_command_list_amd(tracer, i);
|
|
||||||
}
|
|
||||||
else if (device->vk_info.NV_device_diagnostic_checkpoints)
|
|
||||||
{
|
|
||||||
/* vkGetQueueCheckpointDataNV does not require us to synchronize access to the queue. */
|
|
||||||
queue_family_info = d3d12_device_get_vkd3d_queue_family(device, D3D12_COMMAND_LIST_TYPE_DIRECT);
|
|
||||||
for (i = 0; i < queue_family_info->queue_count; i++)
|
|
||||||
{
|
|
||||||
vk_queue = queue_family_info->queues[i]->vk_queue;
|
|
||||||
vkd3d_breadcrumb_tracer_report_queue_nv(tracer, device, vk_queue);
|
|
||||||
}
|
|
||||||
|
|
||||||
queue_family_info = d3d12_device_get_vkd3d_queue_family(device, D3D12_COMMAND_LIST_TYPE_COMPUTE);
|
|
||||||
for (i = 0; i < queue_family_info->queue_count; i++)
|
|
||||||
{
|
|
||||||
vk_queue = queue_family_info->queues[i]->vk_queue;
|
|
||||||
vkd3d_breadcrumb_tracer_report_queue_nv(tracer, device, vk_queue);
|
|
||||||
}
|
|
||||||
|
|
||||||
queue_family_info = d3d12_device_get_vkd3d_queue_family(device, D3D12_COMMAND_LIST_TYPE_COPY);
|
|
||||||
for (i = 0; i < queue_family_info->queue_count; i++)
|
|
||||||
{
|
|
||||||
vk_queue = queue_family_info->queues[i]->vk_queue;
|
|
||||||
vkd3d_breadcrumb_tracer_report_queue_nv(tracer, device, vk_queue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ERR("Done analyzing breadcrumbs ...\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void vkd3d_breadcrumb_tracer_begin_command_list(struct d3d12_command_list *list)
|
|
||||||
{
|
|
||||||
struct vkd3d_breadcrumb_tracer *breadcrumb_tracer = &list->device->breadcrumb_tracer;
|
|
||||||
const struct vkd3d_vk_device_procs *vk_procs = &list->device->vk_procs;
|
|
||||||
struct vkd3d_breadcrumb_command_list_trace_context *trace;
|
|
||||||
unsigned int context = list->breadcrumb_context_index;
|
|
||||||
struct vkd3d_breadcrumb_command cmd;
|
|
||||||
|
|
||||||
if (context == UINT32_MAX)
|
|
||||||
return;
|
|
||||||
|
|
||||||
trace = &breadcrumb_tracer->trace_contexts[context];
|
|
||||||
trace->counter++;
|
|
||||||
|
|
||||||
cmd.count = trace->counter;
|
|
||||||
cmd.type = VKD3D_BREADCRUMB_COMMAND_SET_TOP_MARKER;
|
|
||||||
vkd3d_breadcrumb_tracer_add_command(list, &cmd);
|
|
||||||
|
|
||||||
if (list->device->vk_info.AMD_buffer_marker)
|
|
||||||
{
|
|
||||||
VK_CALL(vkCmdWriteBufferMarkerAMD(list->vk_command_buffer,
|
|
||||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
|
||||||
breadcrumb_tracer->host_buffer,
|
|
||||||
context * sizeof(struct vkd3d_breadcrumb_counter) +
|
|
||||||
offsetof(struct vkd3d_breadcrumb_counter, begin_marker),
|
|
||||||
trace->counter));
|
|
||||||
}
|
|
||||||
else if (list->device->vk_info.NV_device_diagnostic_checkpoints)
|
|
||||||
{
|
|
||||||
/* A checkpoint is implicitly a top and bottom marker. */
|
|
||||||
cmd.count = trace->counter;
|
|
||||||
cmd.type = VKD3D_BREADCRUMB_COMMAND_SET_BOTTOM_MARKER;
|
|
||||||
vkd3d_breadcrumb_tracer_add_command(list, &cmd);
|
|
||||||
|
|
||||||
VK_CALL(vkCmdSetCheckpointNV(list->vk_command_buffer, NV_ENCODE_CHECKPOINT(context, trace->counter)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void vkd3d_breadcrumb_tracer_add_command(struct d3d12_command_list *list,
|
|
||||||
const struct vkd3d_breadcrumb_command *command)
|
|
||||||
{
|
|
||||||
struct vkd3d_breadcrumb_tracer *breadcrumb_tracer = &list->device->breadcrumb_tracer;
|
|
||||||
struct vkd3d_breadcrumb_command_list_trace_context *trace;
|
|
||||||
unsigned int context = list->breadcrumb_context_index;
|
|
||||||
|
|
||||||
if (context == UINT32_MAX)
|
|
||||||
return;
|
|
||||||
|
|
||||||
trace = &breadcrumb_tracer->trace_contexts[context];
|
|
||||||
|
|
||||||
TRACE("Adding command (%s) to context %u.\n",
|
|
||||||
vkd3d_breadcrumb_command_type_to_str(command->type), context);
|
|
||||||
|
|
||||||
vkd3d_array_reserve((void**)&trace->commands, &trace->command_size,
|
|
||||||
trace->command_count + 1, sizeof(*trace->commands));
|
|
||||||
trace->commands[trace->command_count++] = *command;
|
|
||||||
}
|
|
||||||
|
|
||||||
void vkd3d_breadcrumb_tracer_signal(struct d3d12_command_list *list)
|
|
||||||
{
|
|
||||||
struct vkd3d_breadcrumb_tracer *breadcrumb_tracer = &list->device->breadcrumb_tracer;
|
|
||||||
const struct vkd3d_vk_device_procs *vk_procs = &list->device->vk_procs;
|
|
||||||
struct vkd3d_breadcrumb_command_list_trace_context *trace;
|
|
||||||
unsigned int context = list->breadcrumb_context_index;
|
|
||||||
struct vkd3d_breadcrumb_command cmd;
|
|
||||||
|
|
||||||
if (context == UINT32_MAX)
|
|
||||||
return;
|
|
||||||
|
|
||||||
trace = &breadcrumb_tracer->trace_contexts[context];
|
|
||||||
|
|
||||||
if (list->device->vk_info.AMD_buffer_marker)
|
|
||||||
{
|
|
||||||
cmd.type = VKD3D_BREADCRUMB_COMMAND_SET_BOTTOM_MARKER;
|
|
||||||
cmd.count = trace->counter;
|
|
||||||
vkd3d_breadcrumb_tracer_add_command(list, &cmd);
|
|
||||||
TRACE("Breadcrumb signal bottom-of-pipe context %u -> %u\n", context, cmd.count);
|
|
||||||
|
|
||||||
VK_CALL(vkCmdWriteBufferMarkerAMD(list->vk_command_buffer,
|
|
||||||
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
|
|
||||||
breadcrumb_tracer->host_buffer,
|
|
||||||
context * sizeof(struct vkd3d_breadcrumb_counter) +
|
|
||||||
offsetof(struct vkd3d_breadcrumb_counter, end_marker),
|
|
||||||
trace->counter));
|
|
||||||
|
|
||||||
trace->counter++;
|
|
||||||
|
|
||||||
cmd.type = VKD3D_BREADCRUMB_COMMAND_SET_TOP_MARKER;
|
|
||||||
cmd.count = trace->counter;
|
|
||||||
vkd3d_breadcrumb_tracer_add_command(list, &cmd);
|
|
||||||
TRACE("Breadcrumb signal top-of-pipe context %u -> %u\n", context, cmd.count);
|
|
||||||
|
|
||||||
VK_CALL(vkCmdWriteBufferMarkerAMD(list->vk_command_buffer,
|
|
||||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
|
||||||
breadcrumb_tracer->host_buffer,
|
|
||||||
context * sizeof(struct vkd3d_breadcrumb_counter) +
|
|
||||||
offsetof(struct vkd3d_breadcrumb_counter, begin_marker),
|
|
||||||
trace->counter));
|
|
||||||
}
|
|
||||||
else if (list->device->vk_info.NV_device_diagnostic_checkpoints)
|
|
||||||
{
|
|
||||||
trace->counter++;
|
|
||||||
|
|
||||||
cmd.type = VKD3D_BREADCRUMB_COMMAND_SET_TOP_MARKER;
|
|
||||||
cmd.count = trace->counter;
|
|
||||||
vkd3d_breadcrumb_tracer_add_command(list, &cmd);
|
|
||||||
TRACE("Breadcrumb signal top-of-pipe context %u -> %u\n", context, cmd.count);
|
|
||||||
|
|
||||||
cmd.type = VKD3D_BREADCRUMB_COMMAND_SET_BOTTOM_MARKER;
|
|
||||||
cmd.count = trace->counter;
|
|
||||||
vkd3d_breadcrumb_tracer_add_command(list, &cmd);
|
|
||||||
TRACE("Breadcrumb signal bottom-of-pipe context %u -> %u\n", context, cmd.count);
|
|
||||||
|
|
||||||
VK_CALL(vkCmdSetCheckpointNV(list->vk_command_buffer, NV_ENCODE_CHECKPOINT(context, trace->counter)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void vkd3d_breadcrumb_tracer_end_command_list(struct d3d12_command_list *list)
|
|
||||||
{
|
|
||||||
struct vkd3d_breadcrumb_tracer *breadcrumb_tracer = &list->device->breadcrumb_tracer;
|
|
||||||
const struct vkd3d_vk_device_procs *vk_procs = &list->device->vk_procs;
|
|
||||||
struct vkd3d_breadcrumb_command_list_trace_context *trace;
|
|
||||||
unsigned int context = list->breadcrumb_context_index;
|
|
||||||
struct vkd3d_breadcrumb_command cmd;
|
|
||||||
|
|
||||||
if (context == UINT32_MAX)
|
|
||||||
return;
|
|
||||||
|
|
||||||
trace = &breadcrumb_tracer->trace_contexts[context];
|
|
||||||
trace->counter = UINT32_MAX;
|
|
||||||
|
|
||||||
if (list->device->vk_info.AMD_buffer_marker)
|
|
||||||
{
|
|
||||||
VK_CALL(vkCmdWriteBufferMarkerAMD(list->vk_command_buffer,
|
|
||||||
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
|
|
||||||
breadcrumb_tracer->host_buffer,
|
|
||||||
context * sizeof(struct vkd3d_breadcrumb_counter) +
|
|
||||||
offsetof(struct vkd3d_breadcrumb_counter, begin_marker),
|
|
||||||
trace->counter));
|
|
||||||
|
|
||||||
VK_CALL(vkCmdWriteBufferMarkerAMD(list->vk_command_buffer,
|
|
||||||
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
|
|
||||||
breadcrumb_tracer->host_buffer,
|
|
||||||
context * sizeof(struct vkd3d_breadcrumb_counter) +
|
|
||||||
offsetof(struct vkd3d_breadcrumb_counter, end_marker),
|
|
||||||
trace->counter));
|
|
||||||
}
|
|
||||||
else if (list->device->vk_info.NV_device_diagnostic_checkpoints)
|
|
||||||
{
|
|
||||||
VK_CALL(vkCmdSetCheckpointNV(list->vk_command_buffer, NV_ENCODE_CHECKPOINT(context, trace->counter)));
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd.count = trace->counter;
|
|
||||||
cmd.type = VKD3D_BREADCRUMB_COMMAND_SET_TOP_MARKER;
|
|
||||||
vkd3d_breadcrumb_tracer_add_command(list, &cmd);
|
|
||||||
cmd.type = VKD3D_BREADCRUMB_COMMAND_SET_BOTTOM_MARKER;
|
|
||||||
vkd3d_breadcrumb_tracer_add_command(list, &cmd);
|
|
||||||
}
|
|
1787
libs/vkd3d/bundle.c
1787
libs/vkd3d/bundle.c
File diff suppressed because it is too large
Load Diff
3001
libs/vkd3d/cache.c
3001
libs/vkd3d/cache.c
File diff suppressed because it is too large
Load Diff
8972
libs/vkd3d/command.c
8972
libs/vkd3d/command.c
File diff suppressed because it is too large
Load Diff
|
@ -459,12 +459,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_RSSetShadingRateImage_profiled(
|
||||||
COMMAND_LIST_PROFILED_CALL(RSSetShadingRateImage, iface, image);
|
COMMAND_LIST_PROFILED_CALL(RSSetShadingRateImage, iface, image);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void STDMETHODCALLTYPE d3d12_command_list_DispatchMesh_profiled(d3d12_command_list_iface *iface, UINT x, UINT y, UINT z)
|
static CONST_VTBL struct ID3D12GraphicsCommandList5Vtbl d3d12_command_list_vtbl_profiled =
|
||||||
{
|
|
||||||
COMMAND_LIST_PROFILED_CALL(DispatchMesh, iface, x, y, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
static CONST_VTBL struct ID3D12GraphicsCommandList6Vtbl d3d12_command_list_vtbl_profiled =
|
|
||||||
{
|
{
|
||||||
/* IUnknown methods */
|
/* IUnknown methods */
|
||||||
d3d12_command_list_QueryInterface,
|
d3d12_command_list_QueryInterface,
|
||||||
|
@ -474,7 +469,7 @@ static CONST_VTBL struct ID3D12GraphicsCommandList6Vtbl d3d12_command_list_vtbl_
|
||||||
d3d12_command_list_GetPrivateData,
|
d3d12_command_list_GetPrivateData,
|
||||||
d3d12_command_list_SetPrivateData,
|
d3d12_command_list_SetPrivateData,
|
||||||
d3d12_command_list_SetPrivateDataInterface,
|
d3d12_command_list_SetPrivateDataInterface,
|
||||||
(void *)d3d12_object_SetName,
|
d3d12_command_list_SetName,
|
||||||
/* ID3D12DeviceChild methods */
|
/* ID3D12DeviceChild methods */
|
||||||
d3d12_command_list_GetDevice,
|
d3d12_command_list_GetDevice,
|
||||||
/* ID3D12CommandList methods */
|
/* ID3D12CommandList methods */
|
||||||
|
@ -555,8 +550,6 @@ static CONST_VTBL struct ID3D12GraphicsCommandList6Vtbl d3d12_command_list_vtbl_
|
||||||
/* ID3D12GraphicsCommandList5 methods */
|
/* ID3D12GraphicsCommandList5 methods */
|
||||||
d3d12_command_list_RSSetShadingRate_profiled,
|
d3d12_command_list_RSSetShadingRate_profiled,
|
||||||
d3d12_command_list_RSSetShadingRateImage_profiled,
|
d3d12_command_list_RSSetShadingRateImage_profiled,
|
||||||
/* ID3D12GraphicsCommandList6 methods */
|
|
||||||
d3d12_command_list_DispatchMesh_profiled,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,116 +0,0 @@
|
||||||
/*
|
|
||||||
* * Copyright 2021 NVIDIA Corporation
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define VKD3D_DBG_CHANNEL VKD3D_DBG_CHANNEL_API
|
|
||||||
|
|
||||||
#include "vkd3d_private.h"
|
|
||||||
|
|
||||||
static inline struct d3d12_command_list *d3d12_command_list_from_ID3D12GraphicsCommandListExt(ID3D12GraphicsCommandListExt *iface)
|
|
||||||
{
|
|
||||||
return CONTAINING_RECORD(iface, struct d3d12_command_list, ID3D12GraphicsCommandListExt_iface);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern ULONG STDMETHODCALLTYPE d3d12_command_list_AddRef(d3d12_command_list_iface *iface);
|
|
||||||
|
|
||||||
ULONG STDMETHODCALLTYPE d3d12_command_list_vkd3d_ext_AddRef(ID3D12GraphicsCommandListExt *iface)
|
|
||||||
{
|
|
||||||
struct d3d12_command_list *command_list = d3d12_command_list_from_ID3D12GraphicsCommandListExt(iface);
|
|
||||||
return d3d12_command_list_AddRef(&command_list->ID3D12GraphicsCommandList_iface);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern ULONG STDMETHODCALLTYPE d3d12_command_list_Release(d3d12_command_list_iface *iface);
|
|
||||||
|
|
||||||
static ULONG STDMETHODCALLTYPE d3d12_command_list_vkd3d_ext_Release(ID3D12GraphicsCommandListExt *iface)
|
|
||||||
{
|
|
||||||
struct d3d12_command_list *command_list = d3d12_command_list_from_ID3D12GraphicsCommandListExt(iface);
|
|
||||||
return d3d12_command_list_Release(&command_list->ID3D12GraphicsCommandList_iface);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern HRESULT STDMETHODCALLTYPE d3d12_command_list_QueryInterface(d3d12_command_list_iface *iface,
|
|
||||||
REFIID iid, void **object);
|
|
||||||
|
|
||||||
static HRESULT STDMETHODCALLTYPE d3d12_command_list_vkd3d_ext_QueryInterface(ID3D12GraphicsCommandListExt *iface,
|
|
||||||
REFIID iid, void **out)
|
|
||||||
{
|
|
||||||
struct d3d12_command_list *command_list = d3d12_command_list_from_ID3D12GraphicsCommandListExt(iface);
|
|
||||||
TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
|
|
||||||
return d3d12_command_list_QueryInterface(&command_list->ID3D12GraphicsCommandList_iface, iid, out);
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT STDMETHODCALLTYPE d3d12_command_list_vkd3d_ext_GetVulkanHandle(ID3D12GraphicsCommandListExt *iface,
|
|
||||||
VkCommandBuffer *pVkCommandBuffer)
|
|
||||||
{
|
|
||||||
struct d3d12_command_list *command_list = d3d12_command_list_from_ID3D12GraphicsCommandListExt(iface);
|
|
||||||
TRACE("iface %p, pVkCommandBuffer %p.\n", iface, pVkCommandBuffer);
|
|
||||||
if (!pVkCommandBuffer)
|
|
||||||
return E_INVALIDARG;
|
|
||||||
|
|
||||||
*pVkCommandBuffer = command_list->vk_command_buffer;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define CU_LAUNCH_PARAM_BUFFER_POINTER (const void*)0x01
|
|
||||||
#define CU_LAUNCH_PARAM_BUFFER_SIZE (const void*)0x02
|
|
||||||
#define CU_LAUNCH_PARAM_END (const void*)0x00
|
|
||||||
|
|
||||||
static HRESULT STDMETHODCALLTYPE d3d12_command_list_vkd3d_ext_LaunchCubinShader(ID3D12GraphicsCommandListExt *iface, D3D12_CUBIN_DATA_HANDLE *handle, UINT32 block_x, UINT32 block_y, UINT32 block_z, const void *params, UINT32 param_size)
|
|
||||||
{
|
|
||||||
VkCuLaunchInfoNVX launchInfo = { VK_STRUCTURE_TYPE_CU_LAUNCH_INFO_NVX };
|
|
||||||
const struct vkd3d_vk_device_procs *vk_procs;
|
|
||||||
|
|
||||||
const void *config[] = {
|
|
||||||
CU_LAUNCH_PARAM_BUFFER_POINTER, params,
|
|
||||||
CU_LAUNCH_PARAM_BUFFER_SIZE, ¶m_size,
|
|
||||||
CU_LAUNCH_PARAM_END
|
|
||||||
};
|
|
||||||
|
|
||||||
struct d3d12_command_list *command_list = d3d12_command_list_from_ID3D12GraphicsCommandListExt(iface);
|
|
||||||
TRACE("iface %p, handle %p, block_x %u, block_y %u, block_z %u, params %p, param_size %u \n", iface, handle, block_x, block_y, block_z, params, param_size);
|
|
||||||
if (!handle || !block_x || !block_y || !block_z || !params || !param_size)
|
|
||||||
return E_INVALIDARG;
|
|
||||||
|
|
||||||
launchInfo.function = handle->vkCuFunction;
|
|
||||||
launchInfo.gridDimX = block_x;
|
|
||||||
launchInfo.gridDimY = block_y;
|
|
||||||
launchInfo.gridDimZ = block_z;
|
|
||||||
launchInfo.blockDimX = handle->blockX;
|
|
||||||
launchInfo.blockDimY = handle->blockY;
|
|
||||||
launchInfo.blockDimZ = handle->blockZ;
|
|
||||||
launchInfo.sharedMemBytes = 0;
|
|
||||||
launchInfo.paramCount = 0;
|
|
||||||
launchInfo.pParams = NULL;
|
|
||||||
launchInfo.extraCount = 1;
|
|
||||||
launchInfo.pExtras = config;
|
|
||||||
|
|
||||||
vk_procs = &command_list->device->vk_procs;
|
|
||||||
VK_CALL(vkCmdCuLaunchKernelNVX(command_list->vk_command_buffer, &launchInfo));
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
CONST_VTBL struct ID3D12GraphicsCommandListExtVtbl d3d12_command_list_vkd3d_ext_vtbl =
|
|
||||||
{
|
|
||||||
/* IUnknown methods */
|
|
||||||
d3d12_command_list_vkd3d_ext_QueryInterface,
|
|
||||||
d3d12_command_list_vkd3d_ext_AddRef,
|
|
||||||
d3d12_command_list_vkd3d_ext_Release,
|
|
||||||
|
|
||||||
/* ID3D12GraphicsCommandListExt methods */
|
|
||||||
d3d12_command_list_vkd3d_ext_GetVulkanHandle,
|
|
||||||
d3d12_command_list_vkd3d_ext_LaunchCubinShader
|
|
||||||
};
|
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
#include "vkd3d_private.h"
|
#include "vkd3d_private.h"
|
||||||
#include "vkd3d_debug.h"
|
#include "vkd3d_debug.h"
|
||||||
#include "vkd3d_common.h"
|
#include "vkd3d_common.h"
|
||||||
#include "vkd3d_platform.h"
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
void vkd3d_shader_debug_ring_init_spec_constant(struct d3d12_device *device,
|
void vkd3d_shader_debug_ring_init_spec_constant(struct d3d12_device *device,
|
||||||
|
@ -54,139 +53,68 @@ void vkd3d_shader_debug_ring_init_spec_constant(struct d3d12_device *device,
|
||||||
info->map_entries[3].size = sizeof(uint32_t);
|
info->map_entries[3].size = sizeof(uint32_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define READ_RING_WORD(off) ring->mapped_ring[(off) & ((ring->ring_size / sizeof(uint32_t)) - 1)]
|
void *vkd3d_shader_debug_ring_thread_main(void *arg)
|
||||||
#define READ_RING_WORD_ACQUIRE(off) \
|
|
||||||
vkd3d_atomic_uint32_load_explicit(&ring->mapped_ring[(off) & ((ring->ring_size / sizeof(uint32_t)) - 1)], \
|
|
||||||
vkd3d_memory_order_acquire)
|
|
||||||
#define DEBUG_CHANNEL_WORD_COOKIE 0xdeadca70u
|
|
||||||
#define DEBUG_CHANNEL_WORD_MASK 0xfffffff0u
|
|
||||||
|
|
||||||
static const char *vkd3d_patch_command_token_str(enum vkd3d_patch_command_token token)
|
|
||||||
{
|
{
|
||||||
switch (token)
|
uint32_t last_counter, new_counter, count, i, j, message_word_count, debug_instance, debug_thread_id[3], fmt;
|
||||||
{
|
struct vkd3d_shader_debug_ring *ring;
|
||||||
case VKD3D_PATCH_COMMAND_TOKEN_COPY_CONST_U32: return "RootConst";
|
struct d3d12_device *device = arg;
|
||||||
case VKD3D_PATCH_COMMAND_TOKEN_COPY_IBO_VA_LO: return "IBO VA LO";
|
const uint32_t *ring_counter;
|
||||||
case VKD3D_PATCH_COMMAND_TOKEN_COPY_IBO_VA_HI: return "IBO VA HI";
|
const uint32_t *ring_base;
|
||||||
case VKD3D_PATCH_COMMAND_TOKEN_COPY_IBO_SIZE: return "IBO Size";
|
|
||||||
case VKD3D_PATCH_COMMAND_TOKEN_COPY_INDEX_FORMAT: return "IBO Type";
|
|
||||||
case VKD3D_PATCH_COMMAND_TOKEN_COPY_VBO_VA_LO: return "VBO VA LO";
|
|
||||||
case VKD3D_PATCH_COMMAND_TOKEN_COPY_VBO_VA_HI: return "VBO VA HI";
|
|
||||||
case VKD3D_PATCH_COMMAND_TOKEN_COPY_VBO_SIZE: return "VBO Size";
|
|
||||||
case VKD3D_PATCH_COMMAND_TOKEN_COPY_VBO_STRIDE: return "VBO Stride";
|
|
||||||
case VKD3D_PATCH_COMMAND_TOKEN_COPY_ROOT_VA_LO: return "ROOT VA LO";
|
|
||||||
case VKD3D_PATCH_COMMAND_TOKEN_COPY_ROOT_VA_HI: return "ROOT VA HI";
|
|
||||||
case VKD3D_PATCH_COMMAND_TOKEN_COPY_VERTEX_COUNT: return "Vertex Count";
|
|
||||||
case VKD3D_PATCH_COMMAND_TOKEN_COPY_INDEX_COUNT: return "Index Count";
|
|
||||||
case VKD3D_PATCH_COMMAND_TOKEN_COPY_INSTANCE_COUNT: return "Instance Count";
|
|
||||||
case VKD3D_PATCH_COMMAND_TOKEN_COPY_FIRST_INDEX: return "First Index";
|
|
||||||
case VKD3D_PATCH_COMMAND_TOKEN_COPY_FIRST_VERTEX: return "First Vertex";
|
|
||||||
case VKD3D_PATCH_COMMAND_TOKEN_COPY_FIRST_INSTANCE: return "First Instance";
|
|
||||||
case VKD3D_PATCH_COMMAND_TOKEN_COPY_VERTEX_OFFSET: return "Vertex Offset";
|
|
||||||
default: return "???";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool vkd3d_patch_command_token_is_hex(enum vkd3d_patch_command_token token)
|
|
||||||
{
|
|
||||||
switch (token)
|
|
||||||
{
|
|
||||||
case VKD3D_PATCH_COMMAND_TOKEN_COPY_IBO_VA_LO:
|
|
||||||
case VKD3D_PATCH_COMMAND_TOKEN_COPY_IBO_VA_HI:
|
|
||||||
case VKD3D_PATCH_COMMAND_TOKEN_COPY_VBO_VA_LO:
|
|
||||||
case VKD3D_PATCH_COMMAND_TOKEN_COPY_VBO_VA_HI:
|
|
||||||
case VKD3D_PATCH_COMMAND_TOKEN_COPY_ROOT_VA_LO:
|
|
||||||
case VKD3D_PATCH_COMMAND_TOKEN_COPY_ROOT_VA_HI:
|
|
||||||
return true;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool vkd3d_shader_debug_ring_print_message(struct vkd3d_shader_debug_ring *ring,
|
|
||||||
uint32_t word_offset, uint32_t message_word_count)
|
|
||||||
{
|
|
||||||
uint32_t i, debug_instance, debug_thread_id[3], fmt;
|
|
||||||
char message_buffer[4096];
|
char message_buffer[4096];
|
||||||
|
bool is_active = true;
|
||||||
uint64_t shader_hash;
|
uint64_t shader_hash;
|
||||||
size_t len, avail;
|
size_t ring_mask;
|
||||||
|
|
||||||
if (message_word_count < 8)
|
ring = &device->debug_ring;
|
||||||
|
ring_mask = ring->ring_size - 1;
|
||||||
|
ring_counter = ring->mapped;
|
||||||
|
ring_base = ring_counter + (ring->ring_offset / sizeof(uint32_t));
|
||||||
|
last_counter = 0;
|
||||||
|
|
||||||
|
vkd3d_set_thread_name("debug-ring");
|
||||||
|
|
||||||
|
while (is_active)
|
||||||
{
|
{
|
||||||
ERR("Message word count %u is invalid.\n", message_word_count);
|
pthread_mutex_lock(&ring->ring_lock);
|
||||||
return false;
|
pthread_cond_wait(&ring->ring_cond, &ring->ring_lock);
|
||||||
|
is_active = ring->active;
|
||||||
|
pthread_mutex_unlock(&ring->ring_lock);
|
||||||
|
|
||||||
|
new_counter = *ring_counter;
|
||||||
|
if (last_counter != new_counter)
|
||||||
|
{
|
||||||
|
count = (new_counter - last_counter) & ring_mask;
|
||||||
|
|
||||||
|
/* Assume that each iteration can safely use 1/4th of the buffer to avoid WAR hazards. */
|
||||||
|
if ((new_counter - last_counter) > (ring->ring_size / 16))
|
||||||
|
{
|
||||||
|
ERR("Debug ring is probably too small (%u new words this iteration), increase size to avoid risk of dropping messages.\n",
|
||||||
|
new_counter - last_counter);
|
||||||
}
|
}
|
||||||
|
|
||||||
shader_hash = (uint64_t)READ_RING_WORD(word_offset + 1) | ((uint64_t)READ_RING_WORD(word_offset + 2) << 32);
|
for (i = 0; i < count; )
|
||||||
debug_instance = READ_RING_WORD(word_offset + 3);
|
|
||||||
for (i = 0; i < 3; i++)
|
|
||||||
debug_thread_id[i] = READ_RING_WORD(word_offset + 4 + i);
|
|
||||||
fmt = READ_RING_WORD(word_offset + 7);
|
|
||||||
|
|
||||||
word_offset += 8;
|
|
||||||
message_word_count -= 8;
|
|
||||||
|
|
||||||
if (shader_hash == 0)
|
|
||||||
{
|
{
|
||||||
/* We got this from our internal debug shaders. Pretty-print.
|
#define READ_RING_WORD(off) ring_base[((off) + i + last_counter) & ring_mask]
|
||||||
* Make sure the log is sortable for easier debug.
|
message_word_count = READ_RING_WORD(0);
|
||||||
* TODO: Might consider a callback system that listeners from different subsystems can listen to and print their own messages,
|
if (i + message_word_count > count)
|
||||||
* but that is overengineering at this time ... */
|
break;
|
||||||
snprintf(message_buffer, sizeof(message_buffer), "ExecuteIndirect: GlobalCommandIndex %010u, Debug tag %010u, DrawID %04u (ThreadID %04u): ",
|
if (message_word_count < 8 || message_word_count > 16 + 8)
|
||||||
debug_instance, debug_thread_id[0], debug_thread_id[1], debug_thread_id[2]);
|
break;
|
||||||
|
|
||||||
if (message_word_count == 2)
|
shader_hash = (uint64_t)READ_RING_WORD(1) | ((uint64_t)READ_RING_WORD(2) << 32);
|
||||||
{
|
debug_instance = READ_RING_WORD(3);
|
||||||
len = strlen(message_buffer);
|
for (j = 0; j < 3; j++)
|
||||||
avail = sizeof(message_buffer) - len;
|
debug_thread_id[j] = READ_RING_WORD(4 + j);
|
||||||
snprintf(message_buffer + len, avail, "DrawCount %u, MaxDrawCount %u",
|
fmt = READ_RING_WORD(7);
|
||||||
READ_RING_WORD(word_offset + 0),
|
|
||||||
READ_RING_WORD(word_offset + 1));
|
|
||||||
}
|
|
||||||
else if (message_word_count == 4)
|
|
||||||
{
|
|
||||||
union { uint32_t u32; float f32; int32_t s32; } value;
|
|
||||||
enum vkd3d_patch_command_token token;
|
|
||||||
uint32_t dst_offset;
|
|
||||||
uint32_t src_offset;
|
|
||||||
|
|
||||||
len = strlen(message_buffer);
|
snprintf(message_buffer, sizeof(message_buffer), "Shader: %"PRIx64": Instance %u, ID (%u, %u, %u):",
|
||||||
avail = sizeof(message_buffer) - len;
|
|
||||||
|
|
||||||
token = READ_RING_WORD(word_offset + 0);
|
|
||||||
dst_offset = READ_RING_WORD(word_offset + 1);
|
|
||||||
src_offset = READ_RING_WORD(word_offset + 2);
|
|
||||||
value.u32 = READ_RING_WORD(word_offset + 3);
|
|
||||||
|
|
||||||
if (vkd3d_patch_command_token_is_hex(token))
|
|
||||||
{
|
|
||||||
snprintf(message_buffer + len, avail, "%s <- #%08x",
|
|
||||||
vkd3d_patch_command_token_str(token), value.u32);
|
|
||||||
}
|
|
||||||
else if (token == VKD3D_PATCH_COMMAND_TOKEN_COPY_CONST_U32)
|
|
||||||
{
|
|
||||||
snprintf(message_buffer + len, avail, "%s <- {hex #%08x, s32 %d, f32 %f}",
|
|
||||||
vkd3d_patch_command_token_str(token), value.u32, value.s32, value.f32);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
snprintf(message_buffer + len, avail, "%s <- %d",
|
|
||||||
vkd3d_patch_command_token_str(token), value.s32);
|
|
||||||
}
|
|
||||||
|
|
||||||
len = strlen(message_buffer);
|
|
||||||
avail = sizeof(message_buffer) - len;
|
|
||||||
snprintf(message_buffer + len, avail, " (dst offset %u, src offset %u)", dst_offset, src_offset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
snprintf(message_buffer, sizeof(message_buffer), "Shader: %"PRIx64": Instance %010u, ID (%u, %u, %u):",
|
|
||||||
shader_hash, debug_instance,
|
shader_hash, debug_instance,
|
||||||
debug_thread_id[0], debug_thread_id[1], debug_thread_id[2]);
|
debug_thread_id[0], debug_thread_id[1], debug_thread_id[2]);
|
||||||
|
|
||||||
for (i = 0; i < message_word_count; i++)
|
i += 8;
|
||||||
|
message_word_count -= 8;
|
||||||
|
|
||||||
|
for (j = 0; j < message_word_count; j++)
|
||||||
{
|
{
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
|
@ -195,19 +123,20 @@ static bool vkd3d_shader_debug_ring_print_message(struct vkd3d_shader_debug_ring
|
||||||
int32_t i32;
|
int32_t i32;
|
||||||
} u;
|
} u;
|
||||||
const char *delim;
|
const char *delim;
|
||||||
u.u32 = READ_RING_WORD(word_offset + i);
|
size_t len, avail;
|
||||||
|
u.u32 = READ_RING_WORD(j);
|
||||||
|
|
||||||
len = strlen(message_buffer);
|
len = strlen(message_buffer);
|
||||||
if (len + 1 >= sizeof(message_buffer))
|
if (len + 1 >= sizeof(message_buffer))
|
||||||
break;
|
break;
|
||||||
avail = sizeof(message_buffer) - len;
|
avail = sizeof(message_buffer) - len;
|
||||||
|
|
||||||
delim = i == 0 ? " " : ", ";
|
delim = j == 0 ? " " : ", ";
|
||||||
|
|
||||||
#define VKD3D_DEBUG_CHANNEL_FMT_HEX 0u
|
#define VKD3D_DEBUG_CHANNEL_FMT_HEX 0u
|
||||||
#define VKD3D_DEBUG_CHANNEL_FMT_I32 1u
|
#define VKD3D_DEBUG_CHANNEL_FMT_I32 1u
|
||||||
#define VKD3D_DEBUG_CHANNEL_FMT_F32 2u
|
#define VKD3D_DEBUG_CHANNEL_FMT_F32 2u
|
||||||
switch ((fmt >> (2u * i)) & 3u)
|
switch ((fmt >> (2u * j)) & 3u)
|
||||||
{
|
{
|
||||||
case VKD3D_DEBUG_CHANNEL_FMT_HEX:
|
case VKD3D_DEBUG_CHANNEL_FMT_HEX:
|
||||||
snprintf(message_buffer + len, avail, "%s#%x", delim, u.u32);
|
snprintf(message_buffer + len, avail, "%s#%x", delim, u.u32);
|
||||||
|
@ -226,127 +155,14 @@ static bool vkd3d_shader_debug_ring_print_message(struct vkd3d_shader_debug_ring
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
INFO("%s\n", message_buffer);
|
INFO("%s\n", message_buffer);
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *vkd3d_shader_debug_ring_thread_main(void *arg)
|
#undef READ_RING_WORD
|
||||||
{
|
i += message_word_count;
|
||||||
uint32_t last_counter, new_counter, count, i, cookie_word_count;
|
|
||||||
volatile const uint32_t *ring_counter; /* Atomic updated by the GPU. */
|
|
||||||
struct vkd3d_shader_debug_ring *ring;
|
|
||||||
struct d3d12_device *device = arg;
|
|
||||||
bool is_active = true;
|
|
||||||
uint32_t *ring_base;
|
|
||||||
uint32_t word_count;
|
|
||||||
size_t ring_mask;
|
|
||||||
|
|
||||||
ring = &device->debug_ring;
|
|
||||||
ring_mask = (ring->ring_size / sizeof(uint32_t)) - 1;
|
|
||||||
ring_counter = ring->mapped_control_block;
|
|
||||||
ring_base = ring->mapped_ring;
|
|
||||||
last_counter = 0;
|
|
||||||
|
|
||||||
vkd3d_set_thread_name("debug-ring");
|
|
||||||
|
|
||||||
while (is_active)
|
|
||||||
{
|
|
||||||
pthread_mutex_lock(&ring->ring_lock);
|
|
||||||
if (ring->active)
|
|
||||||
pthread_cond_wait(&ring->ring_cond, &ring->ring_lock);
|
|
||||||
is_active = ring->active;
|
|
||||||
pthread_mutex_unlock(&ring->ring_lock);
|
|
||||||
|
|
||||||
new_counter = *ring_counter;
|
|
||||||
|
|
||||||
if (last_counter != new_counter)
|
|
||||||
{
|
|
||||||
count = (new_counter - last_counter) & ring_mask;
|
|
||||||
|
|
||||||
/* Assume that each iteration can safely use 1/4th of the buffer to avoid WAR hazards. */
|
|
||||||
if (count > (ring->ring_size / 16))
|
|
||||||
{
|
|
||||||
ERR("Debug ring is probably too small (%u new words this iteration), increase size to avoid risk of dropping messages.\n",
|
|
||||||
count);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < count; )
|
|
||||||
{
|
|
||||||
/* The debug ring shader has "release" semantics for the word count write,
|
|
||||||
* so just make sure the reads don't get reordered here. */
|
|
||||||
cookie_word_count = READ_RING_WORD_ACQUIRE(last_counter + i);
|
|
||||||
word_count = cookie_word_count & ~DEBUG_CHANNEL_WORD_MASK;
|
|
||||||
|
|
||||||
if (cookie_word_count == 0)
|
|
||||||
{
|
|
||||||
ERR("Message was allocated, but write did not complete. last_counter = %u, rewrite new_counter = %u -> %u\n",
|
|
||||||
last_counter, new_counter, last_counter + i);
|
|
||||||
/* Rewind the counter, and try again later. */
|
|
||||||
new_counter = last_counter + i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If something is written here, it must be a cookie. */
|
|
||||||
if ((cookie_word_count & DEBUG_CHANNEL_WORD_MASK) != DEBUG_CHANNEL_WORD_COOKIE)
|
|
||||||
{
|
|
||||||
ERR("Invalid message work cookie detected, 0x%x.\n", cookie_word_count);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i + word_count > count)
|
|
||||||
{
|
|
||||||
ERR("Message word count %u is out of bounds (i = %u, count = %u).\n",
|
|
||||||
word_count, i, count);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!vkd3d_shader_debug_ring_print_message(ring, last_counter + i, word_count))
|
|
||||||
break;
|
|
||||||
|
|
||||||
i += word_count;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
last_counter = new_counter;
|
||||||
/* Make sure to clear out any messages we read so that when the ring gets around to
|
|
||||||
* this point again, we can detect unwritten memory.
|
|
||||||
* This relies on having a ring that is large enough, but in practice, if we just make the ring
|
|
||||||
* large enough, there is nothing to worry about. */
|
|
||||||
while (last_counter != new_counter)
|
|
||||||
{
|
|
||||||
ring_base[last_counter & ring_mask] = 0;
|
|
||||||
last_counter++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ring->device_lost)
|
|
||||||
{
|
|
||||||
INFO("Device lost detected, attempting to fish for clues.\n");
|
|
||||||
new_counter = *ring_counter;
|
|
||||||
if (last_counter != new_counter)
|
|
||||||
{
|
|
||||||
count = (new_counter - last_counter) & ring_mask;
|
|
||||||
for (i = 0; i < count; )
|
|
||||||
{
|
|
||||||
cookie_word_count = READ_RING_WORD_ACQUIRE(last_counter + i);
|
|
||||||
word_count = cookie_word_count & ~DEBUG_CHANNEL_WORD_MASK;
|
|
||||||
|
|
||||||
/* This is considered a message if it has the marker and a word count that is in-range. */
|
|
||||||
if ((cookie_word_count & DEBUG_CHANNEL_WORD_MASK) == DEBUG_CHANNEL_WORD_COOKIE &&
|
|
||||||
i + word_count <= count &&
|
|
||||||
vkd3d_shader_debug_ring_print_message(ring, last_counter + i, word_count))
|
|
||||||
{
|
|
||||||
i += word_count;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Keep going. */
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
INFO("Done fishing for clues ...\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -357,21 +173,20 @@ HRESULT vkd3d_shader_debug_ring_init(struct vkd3d_shader_debug_ring *ring,
|
||||||
{
|
{
|
||||||
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
||||||
D3D12_HEAP_PROPERTIES heap_properties;
|
D3D12_HEAP_PROPERTIES heap_properties;
|
||||||
D3D12_RESOURCE_DESC1 resource_desc;
|
D3D12_RESOURCE_DESC resource_desc;
|
||||||
VkMemoryPropertyFlags memory_props;
|
const char *env;
|
||||||
char env[VKD3D_PATH_MAX];
|
|
||||||
|
|
||||||
memset(ring, 0, sizeof(*ring));
|
memset(ring, 0, sizeof(*ring));
|
||||||
|
if (!(env = getenv("VKD3D_SHADER_DEBUG_RING_SIZE_LOG2")))
|
||||||
if (!vkd3d_get_env_var("VKD3D_SHADER_DEBUG_RING_SIZE_LOG2", env, sizeof(env)))
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
|
||||||
ring->active = true;
|
ring->active = true;
|
||||||
|
|
||||||
ring->ring_size = (size_t)1 << strtoul(env, NULL, 0);
|
ring->ring_size = (size_t)1 << strtoul(env, NULL, 0);
|
||||||
ring->control_block_size = 4096;
|
// Reserve 4k to be used as a control block of some sort.
|
||||||
|
ring->ring_offset = 4096;
|
||||||
|
|
||||||
INFO("Enabling shader debug ring of size: %zu.\n", ring->ring_size);
|
WARN("Enabling shader debug ring of size: %zu.\n", ring->ring_size);
|
||||||
|
|
||||||
if (!device->device_info.buffer_device_address_features.bufferDeviceAddress)
|
if (!device->device_info.buffer_device_address_features.bufferDeviceAddress)
|
||||||
{
|
{
|
||||||
|
@ -385,7 +200,7 @@ HRESULT vkd3d_shader_debug_ring_init(struct vkd3d_shader_debug_ring *ring,
|
||||||
heap_properties.MemoryPoolPreference = D3D12_MEMORY_POOL_L0;
|
heap_properties.MemoryPoolPreference = D3D12_MEMORY_POOL_L0;
|
||||||
|
|
||||||
memset(&resource_desc, 0, sizeof(resource_desc));
|
memset(&resource_desc, 0, sizeof(resource_desc));
|
||||||
resource_desc.Width = ring->ring_size;
|
resource_desc.Width = ring->ring_offset + ring->ring_size;
|
||||||
resource_desc.Height = 1;
|
resource_desc.Height = 1;
|
||||||
resource_desc.DepthOrArraySize = 1;
|
resource_desc.DepthOrArraySize = 1;
|
||||||
resource_desc.MipLevels = 1;
|
resource_desc.MipLevels = 1;
|
||||||
|
@ -399,30 +214,13 @@ HRESULT vkd3d_shader_debug_ring_init(struct vkd3d_shader_debug_ring *ring,
|
||||||
&resource_desc, &ring->host_buffer)))
|
&resource_desc, &ring->host_buffer)))
|
||||||
goto err_free_buffers;
|
goto err_free_buffers;
|
||||||
|
|
||||||
memory_props = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
|
if (FAILED(vkd3d_allocate_buffer_memory(device, ring->host_buffer, NULL,
|
||||||
VK_MEMORY_PROPERTY_HOST_CACHED_BIT |
|
&heap_properties, D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS, &ring->host_buffer_memory, NULL, NULL)))
|
||||||
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
|
|
||||||
|
|
||||||
/* If we're doing breadcrumb debugging, we also need to be able to read debug ring messages
|
|
||||||
* from a crash, so we cannot rely on being able to copy the device payload back to host.
|
|
||||||
* Use PCI-e BAR + UNCACHED + DEVICE_COHERENT if we must. */
|
|
||||||
if (vkd3d_config_flags & VKD3D_CONFIG_FLAG_BREADCRUMBS)
|
|
||||||
{
|
|
||||||
INFO("Using debug ring with breadcrumbs, opting in to device uncached payload buffer.\n");
|
|
||||||
/* We use coherent in the debug_channel.h header, but not necessarily guaranteed to be coherent with
|
|
||||||
* host reads, so make extra sure. */
|
|
||||||
if (device->device_info.device_coherent_memory_features_amd.deviceCoherentMemory)
|
|
||||||
{
|
|
||||||
memory_props |= VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD | VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD;
|
|
||||||
INFO("Enabling uncached device memory for debug ring.\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FAILED(vkd3d_allocate_buffer_memory(device, ring->host_buffer,
|
|
||||||
memory_props, &ring->host_buffer_memory)))
|
|
||||||
goto err_free_buffers;
|
goto err_free_buffers;
|
||||||
|
|
||||||
resource_desc.Width = ring->control_block_size;
|
ring->ring_device_address = vkd3d_get_buffer_device_address(device, ring->host_buffer) + ring->ring_offset;
|
||||||
|
|
||||||
|
resource_desc.Width = ring->ring_offset;
|
||||||
memset(&heap_properties, 0, sizeof(heap_properties));
|
memset(&heap_properties, 0, sizeof(heap_properties));
|
||||||
heap_properties.Type = D3D12_HEAP_TYPE_DEFAULT;
|
heap_properties.Type = D3D12_HEAP_TYPE_DEFAULT;
|
||||||
|
|
||||||
|
@ -430,37 +228,15 @@ HRESULT vkd3d_shader_debug_ring_init(struct vkd3d_shader_debug_ring *ring,
|
||||||
&resource_desc, &ring->device_atomic_buffer)))
|
&resource_desc, &ring->device_atomic_buffer)))
|
||||||
goto err_free_buffers;
|
goto err_free_buffers;
|
||||||
|
|
||||||
memory_props = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
|
if (FAILED(vkd3d_allocate_buffer_memory(device, ring->device_atomic_buffer, NULL,
|
||||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
|
&heap_properties, D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS, &ring->device_atomic_buffer_memory, NULL, NULL)))
|
||||||
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
|
|
||||||
|
|
||||||
if (vkd3d_config_flags & VKD3D_CONFIG_FLAG_BREADCRUMBS)
|
|
||||||
{
|
|
||||||
/* Expect crashes since we won't have time to flush caches.
|
|
||||||
* We use coherent in the debug_channel.h header, but not necessarily guaranteed to be coherent with
|
|
||||||
* host reads, so make extra sure. */
|
|
||||||
if (device->device_info.device_coherent_memory_features_amd.deviceCoherentMemory)
|
|
||||||
memory_props |= VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD | VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FAILED(vkd3d_allocate_buffer_memory(device, ring->device_atomic_buffer,
|
|
||||||
memory_props, &ring->device_atomic_buffer_memory)))
|
|
||||||
goto err_free_buffers;
|
goto err_free_buffers;
|
||||||
|
|
||||||
if (VK_CALL(vkMapMemory(device->vk_device, ring->host_buffer_memory.vk_memory,
|
if (VK_CALL(vkMapMemory(device->vk_device, ring->host_buffer_memory, 0, VK_WHOLE_SIZE, 0, &ring->mapped)) != VK_SUCCESS)
|
||||||
0, VK_WHOLE_SIZE, 0, (void**)&ring->mapped_ring)) != VK_SUCCESS)
|
|
||||||
goto err_free_buffers;
|
goto err_free_buffers;
|
||||||
|
|
||||||
if (VK_CALL(vkMapMemory(device->vk_device, ring->device_atomic_buffer_memory.vk_memory,
|
|
||||||
0, VK_WHOLE_SIZE, 0, (void**)&ring->mapped_control_block)) != VK_SUCCESS)
|
|
||||||
goto err_free_buffers;
|
|
||||||
|
|
||||||
ring->ring_device_address = vkd3d_get_buffer_device_address(device, ring->host_buffer);
|
|
||||||
ring->atomic_device_address = vkd3d_get_buffer_device_address(device, ring->device_atomic_buffer);
|
ring->atomic_device_address = vkd3d_get_buffer_device_address(device, ring->device_atomic_buffer);
|
||||||
|
|
||||||
memset(ring->mapped_control_block, 0, ring->control_block_size);
|
|
||||||
memset(ring->mapped_ring, 0, ring->ring_size);
|
|
||||||
|
|
||||||
if (pthread_mutex_init(&ring->ring_lock, NULL) != 0)
|
if (pthread_mutex_init(&ring->ring_lock, NULL) != 0)
|
||||||
goto err_free_buffers;
|
goto err_free_buffers;
|
||||||
if (pthread_cond_init(&ring->ring_cond, NULL) != 0)
|
if (pthread_cond_init(&ring->ring_cond, NULL) != 0)
|
||||||
|
@ -481,8 +257,8 @@ err_destroy_cond:
|
||||||
err_free_buffers:
|
err_free_buffers:
|
||||||
VK_CALL(vkDestroyBuffer(device->vk_device, ring->host_buffer, NULL));
|
VK_CALL(vkDestroyBuffer(device->vk_device, ring->host_buffer, NULL));
|
||||||
VK_CALL(vkDestroyBuffer(device->vk_device, ring->device_atomic_buffer, NULL));
|
VK_CALL(vkDestroyBuffer(device->vk_device, ring->device_atomic_buffer, NULL));
|
||||||
vkd3d_free_device_memory(device, &ring->host_buffer_memory);
|
VK_CALL(vkFreeMemory(device->vk_device, ring->host_buffer_memory, NULL));
|
||||||
vkd3d_free_device_memory(device, &ring->device_atomic_buffer_memory);
|
VK_CALL(vkFreeMemory(device->vk_device, ring->device_atomic_buffer_memory, NULL));
|
||||||
memset(ring, 0, sizeof(*ring));
|
memset(ring, 0, sizeof(*ring));
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
|
@ -504,28 +280,38 @@ void vkd3d_shader_debug_ring_cleanup(struct vkd3d_shader_debug_ring *ring,
|
||||||
|
|
||||||
VK_CALL(vkDestroyBuffer(device->vk_device, ring->host_buffer, NULL));
|
VK_CALL(vkDestroyBuffer(device->vk_device, ring->host_buffer, NULL));
|
||||||
VK_CALL(vkDestroyBuffer(device->vk_device, ring->device_atomic_buffer, NULL));
|
VK_CALL(vkDestroyBuffer(device->vk_device, ring->device_atomic_buffer, NULL));
|
||||||
vkd3d_free_device_memory(device, &ring->host_buffer_memory);
|
VK_CALL(vkFreeMemory(device->vk_device, ring->host_buffer_memory, NULL));
|
||||||
vkd3d_free_device_memory(device, &ring->device_atomic_buffer_memory);
|
VK_CALL(vkFreeMemory(device->vk_device, ring->device_atomic_buffer_memory, NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
static pthread_mutex_t debug_ring_teardown_lock = PTHREAD_MUTEX_INITIALIZER;
|
void vkd3d_shader_debug_ring_end_command_buffer(struct d3d12_command_list *list)
|
||||||
|
|
||||||
void vkd3d_shader_debug_ring_kick(struct vkd3d_shader_debug_ring *ring, struct d3d12_device *device, bool device_lost)
|
|
||||||
{
|
{
|
||||||
if (device_lost)
|
const struct vkd3d_vk_device_procs *vk_procs = &list->device->vk_procs;
|
||||||
|
VkBufferCopy buffer_copy;
|
||||||
|
VkMemoryBarrier barrier;
|
||||||
|
|
||||||
|
if (list->device->debug_ring.active &&
|
||||||
|
list->has_replaced_shaders &&
|
||||||
|
(list->type == D3D12_COMMAND_LIST_TYPE_DIRECT || list->type == D3D12_COMMAND_LIST_TYPE_COMPUTE))
|
||||||
{
|
{
|
||||||
/* Need a global lock here since multiple threads can observe device lost at the same time. */
|
barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
|
||||||
pthread_mutex_lock(&debug_ring_teardown_lock);
|
barrier.pNext = NULL;
|
||||||
{
|
barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
|
||||||
ring->device_lost = true;
|
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
|
||||||
/* We're going to die or hang after this most likely, so make sure we get to see all messages the
|
|
||||||
* GPU had to write. Just cleanup now. */
|
VK_CALL(vkCmdPipelineBarrier(list->vk_command_buffer,
|
||||||
vkd3d_shader_debug_ring_cleanup(ring, device);
|
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0,
|
||||||
}
|
1, &barrier, 0, NULL, 0, NULL));
|
||||||
pthread_mutex_unlock(&debug_ring_teardown_lock);
|
|
||||||
}
|
buffer_copy.size = list->device->debug_ring.ring_offset;
|
||||||
else
|
buffer_copy.dstOffset = 0;
|
||||||
{
|
buffer_copy.srcOffset = 0;
|
||||||
pthread_cond_signal(&ring->ring_cond);
|
|
||||||
|
VK_CALL(vkCmdCopyBuffer(list->vk_command_buffer,
|
||||||
|
list->device->debug_ring.device_atomic_buffer,
|
||||||
|
list->device->debug_ring.host_buffer,
|
||||||
|
1, &buffer_copy));
|
||||||
|
|
||||||
|
/* Host barrier is taken care of automatically. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,530 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2020 Hans-Kristian Arntzen for Valve Corporation
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define VKD3D_DBG_CHANNEL VKD3D_DBG_CHANNEL_API
|
|
||||||
|
|
||||||
#include "vkd3d_descriptor_debug.h"
|
|
||||||
#include "vkd3d_threads.h"
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <inttypes.h>
|
|
||||||
|
|
||||||
static pthread_once_t debug_once = PTHREAD_ONCE_INIT;
|
|
||||||
static pthread_mutex_t debug_lock = PTHREAD_MUTEX_INITIALIZER;
|
|
||||||
static bool descriptor_debug_active_qa_checks;
|
|
||||||
static bool descriptor_debug_active_log;
|
|
||||||
static FILE *descriptor_debug_file;
|
|
||||||
|
|
||||||
struct vkd3d_descriptor_qa_global_info
|
|
||||||
{
|
|
||||||
struct vkd3d_descriptor_qa_global_buffer_data *data;
|
|
||||||
VkDescriptorBufferInfo descriptor;
|
|
||||||
VkBuffer vk_buffer;
|
|
||||||
struct vkd3d_device_memory_allocation device_allocation;
|
|
||||||
unsigned int num_cookies;
|
|
||||||
|
|
||||||
pthread_t ring_thread;
|
|
||||||
pthread_mutex_t ring_lock;
|
|
||||||
pthread_cond_t ring_cond;
|
|
||||||
bool active;
|
|
||||||
};
|
|
||||||
|
|
||||||
static const char *debug_descriptor_type(vkd3d_descriptor_qa_flags type_flags)
|
|
||||||
{
|
|
||||||
bool has_raw_va = !!(type_flags & VKD3D_DESCRIPTOR_QA_TYPE_RAW_VA_BIT);
|
|
||||||
|
|
||||||
switch (type_flags & ~VKD3D_DESCRIPTOR_QA_TYPE_RAW_VA_BIT)
|
|
||||||
{
|
|
||||||
case VKD3D_DESCRIPTOR_QA_TYPE_SAMPLER_BIT: return "SAMPLER";
|
|
||||||
case VKD3D_DESCRIPTOR_QA_TYPE_SAMPLED_IMAGE_BIT: return "SAMPLED_IMAGE";
|
|
||||||
case VKD3D_DESCRIPTOR_QA_TYPE_STORAGE_IMAGE_BIT: return "STORAGE_IMAGE";
|
|
||||||
case VKD3D_DESCRIPTOR_QA_TYPE_UNIFORM_BUFFER_BIT: return "UNIFORM_BUFFER";
|
|
||||||
case VKD3D_DESCRIPTOR_QA_TYPE_STORAGE_BUFFER_BIT: return "STORAGE_BUFFER";
|
|
||||||
case VKD3D_DESCRIPTOR_QA_TYPE_UNIFORM_TEXEL_BUFFER_BIT: return "UNIFORM_TEXEL_BUFFER";
|
|
||||||
case VKD3D_DESCRIPTOR_QA_TYPE_STORAGE_TEXEL_BUFFER_BIT: return "STORAGE_TEXEL_BUFFER";
|
|
||||||
|
|
||||||
case VKD3D_DESCRIPTOR_QA_TYPE_STORAGE_TEXEL_BUFFER_BIT | VKD3D_DESCRIPTOR_QA_TYPE_STORAGE_BUFFER_BIT:
|
|
||||||
return has_raw_va ? "STORAGE_TEXEL_BUFFER / STORAGE_BUFFER (w/ counter)" : "STORAGE_TEXEL_BUFFER / STORAGE_BUFFER";
|
|
||||||
|
|
||||||
case VKD3D_DESCRIPTOR_QA_TYPE_UNIFORM_TEXEL_BUFFER_BIT | VKD3D_DESCRIPTOR_QA_TYPE_STORAGE_BUFFER_BIT:
|
|
||||||
return has_raw_va ? "UNIFORM_TEXEL_BUFFER / STORAGE_BUFFER (w/ counter)" : "UNIFORM_TEXEL_BUFFER / STORAGE_BUFFER";
|
|
||||||
|
|
||||||
case VKD3D_DESCRIPTOR_QA_TYPE_RT_ACCELERATION_STRUCTURE_BIT:
|
|
||||||
return "RTAS";
|
|
||||||
|
|
||||||
case 0:
|
|
||||||
return "NONE";
|
|
||||||
|
|
||||||
default: return "?";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void vkd3d_descriptor_debug_init_once(void)
|
|
||||||
{
|
|
||||||
char env[VKD3D_PATH_MAX];
|
|
||||||
vkd3d_get_env_var("VKD3D_DESCRIPTOR_QA_LOG", env, sizeof(env));
|
|
||||||
|
|
||||||
if (strlen(env) > 0)
|
|
||||||
{
|
|
||||||
INFO("Enabling VKD3D_DESCRIPTOR_QA_LOG\n");
|
|
||||||
descriptor_debug_file = fopen(env, "w");
|
|
||||||
if (!descriptor_debug_file)
|
|
||||||
ERR("Failed to open file: %s.\n", env);
|
|
||||||
else
|
|
||||||
descriptor_debug_active_log = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vkd3d_config_flags & VKD3D_CONFIG_FLAG_DESCRIPTOR_QA_CHECKS)
|
|
||||||
{
|
|
||||||
INFO("Enabling descriptor QA checks!\n");
|
|
||||||
descriptor_debug_active_qa_checks = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void vkd3d_descriptor_debug_init(void)
|
|
||||||
{
|
|
||||||
pthread_once(&debug_once, vkd3d_descriptor_debug_init_once);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool vkd3d_descriptor_debug_active_log(void)
|
|
||||||
{
|
|
||||||
return descriptor_debug_active_log;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool vkd3d_descriptor_debug_active_qa_checks(void)
|
|
||||||
{
|
|
||||||
return descriptor_debug_active_qa_checks;
|
|
||||||
}
|
|
||||||
|
|
||||||
VkDeviceSize vkd3d_descriptor_debug_heap_info_size(unsigned int num_descriptors)
|
|
||||||
{
|
|
||||||
return offsetof(struct vkd3d_descriptor_qa_heap_buffer_data, desc) + num_descriptors *
|
|
||||||
sizeof(struct vkd3d_descriptor_qa_cookie_descriptor);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void vkd3d_descriptor_debug_set_live_status_bit(
|
|
||||||
struct vkd3d_descriptor_qa_global_info *global_info, uint64_t cookie)
|
|
||||||
{
|
|
||||||
if (!global_info || !global_info->active || !global_info->data)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (cookie < global_info->num_cookies)
|
|
||||||
{
|
|
||||||
vkd3d_atomic_uint32_or(&global_info->data->live_status_table[cookie / 32],
|
|
||||||
1u << (cookie & 31), vkd3d_memory_order_relaxed);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
INFO("Cookie index %"PRIu64" is out of range, cannot be tracked.\n", cookie);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void vkd3d_descriptor_debug_unset_live_status_bit(
|
|
||||||
struct vkd3d_descriptor_qa_global_info *global_info, uint64_t cookie)
|
|
||||||
{
|
|
||||||
if (!global_info || !global_info->active || !global_info->data)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (cookie < global_info->num_cookies)
|
|
||||||
{
|
|
||||||
vkd3d_atomic_uint32_and(&global_info->data->live_status_table[cookie / 32],
|
|
||||||
~(1u << (cookie & 31)), vkd3d_memory_order_relaxed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void vkd3d_descriptor_debug_qa_check_report_fault(
|
|
||||||
struct vkd3d_descriptor_qa_global_info *global_info);
|
|
||||||
|
|
||||||
static void *vkd3d_descriptor_debug_qa_check_entry(void *userdata)
|
|
||||||
{
|
|
||||||
struct vkd3d_descriptor_qa_global_info *global_info = userdata;
|
|
||||||
bool active = true;
|
|
||||||
|
|
||||||
while (active)
|
|
||||||
{
|
|
||||||
/* Don't spin endlessly, this thread is kicked after a successful fence wait. */
|
|
||||||
pthread_mutex_lock(&global_info->ring_lock);
|
|
||||||
if (global_info->active)
|
|
||||||
pthread_cond_wait(&global_info->ring_cond, &global_info->ring_lock);
|
|
||||||
active = global_info->active;
|
|
||||||
pthread_mutex_unlock(&global_info->ring_lock);
|
|
||||||
|
|
||||||
if (global_info->data->fault_type != 0)
|
|
||||||
{
|
|
||||||
vkd3d_descriptor_debug_qa_check_report_fault(global_info);
|
|
||||||
ERR("Num failed checks: %u\n", global_info->data->fault_atomic);
|
|
||||||
|
|
||||||
/* Reset the latch so we can get more reports. */
|
|
||||||
vkd3d_atomic_uint32_store_explicit(&global_info->data->fault_type, 0, vkd3d_memory_order_relaxed);
|
|
||||||
vkd3d_atomic_uint32_store_explicit(&global_info->data->fault_atomic, 0, vkd3d_memory_order_release);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void vkd3d_descriptor_debug_kick_qa_check(struct vkd3d_descriptor_qa_global_info *global_info)
|
|
||||||
{
|
|
||||||
if (global_info && global_info->active)
|
|
||||||
pthread_cond_signal(&global_info->ring_cond);
|
|
||||||
}
|
|
||||||
|
|
||||||
const VkDescriptorBufferInfo *vkd3d_descriptor_debug_get_global_info_descriptor(
|
|
||||||
struct vkd3d_descriptor_qa_global_info *global_info)
|
|
||||||
{
|
|
||||||
if (global_info)
|
|
||||||
return &global_info->descriptor;
|
|
||||||
else
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT vkd3d_descriptor_debug_alloc_global_info(
|
|
||||||
struct vkd3d_descriptor_qa_global_info **out_global_info, unsigned int num_cookies,
|
|
||||||
struct d3d12_device *device)
|
|
||||||
{
|
|
||||||
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
|
||||||
struct vkd3d_descriptor_qa_global_info *global_info;
|
|
||||||
D3D12_RESOURCE_DESC1 buffer_desc;
|
|
||||||
D3D12_HEAP_PROPERTIES heap_info;
|
|
||||||
D3D12_HEAP_FLAGS heap_flags;
|
|
||||||
VkResult vr;
|
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
global_info = vkd3d_calloc(1, sizeof(*global_info));
|
|
||||||
if (!global_info)
|
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
|
|
||||||
memset(&buffer_desc, 0, sizeof(buffer_desc));
|
|
||||||
buffer_desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
|
|
||||||
buffer_desc.Width = sizeof(uint32_t) * ((num_cookies + 31) / 32) +
|
|
||||||
offsetof(struct vkd3d_descriptor_qa_global_buffer_data, live_status_table);
|
|
||||||
buffer_desc.Height = 1;
|
|
||||||
buffer_desc.DepthOrArraySize = 1;
|
|
||||||
buffer_desc.MipLevels = 1;
|
|
||||||
buffer_desc.SampleDesc.Count = 1;
|
|
||||||
buffer_desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
|
|
||||||
buffer_desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
|
|
||||||
|
|
||||||
/* host-visible device memory */
|
|
||||||
memset(&heap_info, 0, sizeof(heap_info));
|
|
||||||
heap_info.Type = D3D12_HEAP_TYPE_UPLOAD;
|
|
||||||
|
|
||||||
heap_flags = D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS;
|
|
||||||
|
|
||||||
if (FAILED(hr = vkd3d_create_buffer(device, &heap_info, heap_flags, &buffer_desc, &global_info->vk_buffer)))
|
|
||||||
{
|
|
||||||
vkd3d_descriptor_debug_free_global_info(global_info, device);
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FAILED(hr = vkd3d_allocate_buffer_memory(device, global_info->vk_buffer,
|
|
||||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
|
|
||||||
&global_info->device_allocation)))
|
|
||||||
{
|
|
||||||
vkd3d_descriptor_debug_free_global_info(global_info, device);
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((vr = VK_CALL(vkMapMemory(device->vk_device, global_info->device_allocation.vk_memory,
|
|
||||||
0, VK_WHOLE_SIZE, 0, (void**)&global_info->data))))
|
|
||||||
{
|
|
||||||
ERR("Failed to map buffer, vr %d.\n", vr);
|
|
||||||
vkd3d_descriptor_debug_free_global_info(global_info, device);
|
|
||||||
return hresult_from_vk_result(vr);
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(global_info->data, 0, buffer_desc.Width);
|
|
||||||
|
|
||||||
/* The NULL descriptor has cookie 0, and is always considered live. */
|
|
||||||
global_info->data->live_status_table[0] = 1u << 0;
|
|
||||||
|
|
||||||
global_info->descriptor.buffer = global_info->vk_buffer;
|
|
||||||
global_info->descriptor.offset = 0;
|
|
||||||
global_info->descriptor.range = buffer_desc.Width;
|
|
||||||
global_info->num_cookies = num_cookies;
|
|
||||||
|
|
||||||
pthread_mutex_init(&global_info->ring_lock, NULL);
|
|
||||||
pthread_cond_init(&global_info->ring_cond, NULL);
|
|
||||||
global_info->active = true;
|
|
||||||
if (pthread_create(&global_info->ring_thread, NULL, vkd3d_descriptor_debug_qa_check_entry, global_info) != 0)
|
|
||||||
{
|
|
||||||
vkd3d_descriptor_debug_free_global_info(global_info, device);
|
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
*out_global_info = global_info;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void vkd3d_descriptor_debug_free_global_info(
|
|
||||||
struct vkd3d_descriptor_qa_global_info *global_info,
|
|
||||||
struct d3d12_device *device)
|
|
||||||
{
|
|
||||||
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
|
||||||
|
|
||||||
if (!global_info)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (global_info->active)
|
|
||||||
{
|
|
||||||
pthread_mutex_lock(&global_info->ring_lock);
|
|
||||||
global_info->active = false;
|
|
||||||
pthread_cond_signal(&global_info->ring_cond);
|
|
||||||
pthread_mutex_unlock(&global_info->ring_lock);
|
|
||||||
pthread_join(global_info->ring_thread, NULL);
|
|
||||||
pthread_mutex_destroy(&global_info->ring_lock);
|
|
||||||
pthread_cond_destroy(&global_info->ring_cond);
|
|
||||||
}
|
|
||||||
|
|
||||||
vkd3d_free_device_memory(device, &global_info->device_allocation);
|
|
||||||
VK_CALL(vkDestroyBuffer(device->vk_device, global_info->vk_buffer, NULL));
|
|
||||||
vkd3d_free(global_info);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define DECL_BUFFER() \
|
|
||||||
char buffer[4096]; \
|
|
||||||
char *ptr; \
|
|
||||||
ptr = buffer; \
|
|
||||||
*ptr = '\0'
|
|
||||||
|
|
||||||
#define FLUSH_BUFFER() do { \
|
|
||||||
pthread_mutex_lock(&debug_lock); \
|
|
||||||
fprintf(descriptor_debug_file, "%s\n", buffer); \
|
|
||||||
pthread_mutex_unlock(&debug_lock); \
|
|
||||||
fflush(descriptor_debug_file); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define APPEND_SNPRINTF(...) do { ptr += strlen(ptr); snprintf(ptr, (buffer + ARRAY_SIZE(buffer)) - ptr, __VA_ARGS__); } while(0)
|
|
||||||
|
|
||||||
static void vkd3d_descriptor_debug_qa_check_report_fault(
|
|
||||||
struct vkd3d_descriptor_qa_global_info *global_info)
|
|
||||||
{
|
|
||||||
DECL_BUFFER();
|
|
||||||
|
|
||||||
if (global_info->data->fault_type & VKD3D_DESCRIPTOR_FAULT_TYPE_HEAP_OF_OF_RANGE)
|
|
||||||
APPEND_SNPRINTF("Fault type: HEAP_OUT_OF_RANGE\n");
|
|
||||||
if (global_info->data->fault_type & VKD3D_DESCRIPTOR_FAULT_TYPE_MISMATCH_DESCRIPTOR_TYPE)
|
|
||||||
APPEND_SNPRINTF("Fault type: MISMATCH_DESCRIPTOR_TYPE\n");
|
|
||||||
if (global_info->data->fault_type & VKD3D_DESCRIPTOR_FAULT_TYPE_DESTROYED_RESOURCE)
|
|
||||||
APPEND_SNPRINTF("Fault type: DESTROYED_RESOURCE\n");
|
|
||||||
|
|
||||||
APPEND_SNPRINTF("CBV_SRV_UAV heap cookie: %u\n", global_info->data->failed_heap);
|
|
||||||
APPEND_SNPRINTF("Shader hash and instruction: %"PRIx64" (%u)\n",
|
|
||||||
global_info->data->failed_hash, global_info->data->failed_instruction);
|
|
||||||
APPEND_SNPRINTF("Accessed resource/view cookie: %u\n", global_info->data->failed_cookie);
|
|
||||||
APPEND_SNPRINTF("Shader desired descriptor type: %u (%s)\n",
|
|
||||||
global_info->data->failed_descriptor_type_mask,
|
|
||||||
debug_descriptor_type(global_info->data->failed_descriptor_type_mask));
|
|
||||||
APPEND_SNPRINTF("Found descriptor type in heap: %u (%s)\n",
|
|
||||||
global_info->data->actual_descriptor_type_mask,
|
|
||||||
debug_descriptor_type(global_info->data->actual_descriptor_type_mask));
|
|
||||||
APPEND_SNPRINTF("Failed heap index: %u\n", global_info->data->failed_offset);
|
|
||||||
ERR("\n============\n%s==========\n", buffer);
|
|
||||||
if (!vkd3d_descriptor_debug_active_log())
|
|
||||||
return;
|
|
||||||
FLUSH_BUFFER();
|
|
||||||
}
|
|
||||||
|
|
||||||
void vkd3d_descriptor_debug_register_heap(
|
|
||||||
struct vkd3d_descriptor_qa_heap_buffer_data *heap, uint64_t cookie,
|
|
||||||
const D3D12_DESCRIPTOR_HEAP_DESC *desc)
|
|
||||||
{
|
|
||||||
DECL_BUFFER();
|
|
||||||
|
|
||||||
if (heap)
|
|
||||||
{
|
|
||||||
heap->num_descriptors = desc->NumDescriptors;
|
|
||||||
heap->heap_index = cookie <= UINT32_MAX ? (uint32_t)cookie : 0u;
|
|
||||||
memset(heap->desc, 0, desc->NumDescriptors * sizeof(*heap->desc));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!vkd3d_descriptor_debug_active_log())
|
|
||||||
return;
|
|
||||||
|
|
||||||
APPEND_SNPRINTF("REGISTER HEAP %"PRIu64" || COUNT = %u", cookie, desc->NumDescriptors);
|
|
||||||
if (desc->Flags & D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE)
|
|
||||||
APPEND_SNPRINTF(" || SHADER");
|
|
||||||
|
|
||||||
switch (desc->Type)
|
|
||||||
{
|
|
||||||
case D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV:
|
|
||||||
APPEND_SNPRINTF(" || CBV_SRV_UAV");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER:
|
|
||||||
APPEND_SNPRINTF(" || SAMPLER");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case D3D12_DESCRIPTOR_HEAP_TYPE_RTV:
|
|
||||||
APPEND_SNPRINTF(" || RTV");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case D3D12_DESCRIPTOR_HEAP_TYPE_DSV:
|
|
||||||
APPEND_SNPRINTF(" || DSV");
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
APPEND_SNPRINTF(" || ?");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
FLUSH_BUFFER();
|
|
||||||
}
|
|
||||||
|
|
||||||
void vkd3d_descriptor_debug_unregister_heap(uint64_t cookie)
|
|
||||||
{
|
|
||||||
DECL_BUFFER();
|
|
||||||
if (!vkd3d_descriptor_debug_active_log())
|
|
||||||
return;
|
|
||||||
|
|
||||||
APPEND_SNPRINTF("DESTROY HEAP %"PRIu64, cookie);
|
|
||||||
FLUSH_BUFFER();
|
|
||||||
}
|
|
||||||
|
|
||||||
void vkd3d_descriptor_debug_register_resource_cookie(struct vkd3d_descriptor_qa_global_info *global_info,
|
|
||||||
uint64_t cookie, const D3D12_RESOURCE_DESC1 *desc)
|
|
||||||
{
|
|
||||||
const char *fmt;
|
|
||||||
DECL_BUFFER();
|
|
||||||
|
|
||||||
vkd3d_descriptor_debug_set_live_status_bit(global_info, cookie);
|
|
||||||
|
|
||||||
if (!vkd3d_descriptor_debug_active_log())
|
|
||||||
return;
|
|
||||||
|
|
||||||
APPEND_SNPRINTF("RESOURCE CREATE #%"PRIu64" || ", cookie);
|
|
||||||
|
|
||||||
fmt = debug_dxgi_format(desc->Format);
|
|
||||||
|
|
||||||
switch (desc->Dimension)
|
|
||||||
{
|
|
||||||
case D3D12_RESOURCE_DIMENSION_BUFFER:
|
|
||||||
APPEND_SNPRINTF("Buffer");
|
|
||||||
APPEND_SNPRINTF(" || Size = 0x%"PRIx64" bytes", desc->Width);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case D3D12_RESOURCE_DIMENSION_TEXTURE1D:
|
|
||||||
APPEND_SNPRINTF("Tex1D");
|
|
||||||
APPEND_SNPRINTF(" || Format = %s || Levels = %u || Layers = %u || Width = %"PRIu64,
|
|
||||||
fmt, desc->MipLevels, desc->DepthOrArraySize, desc->Width);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case D3D12_RESOURCE_DIMENSION_TEXTURE2D:
|
|
||||||
APPEND_SNPRINTF("Tex2D");
|
|
||||||
APPEND_SNPRINTF(" || Format = %s || Levels = %u || Layers = %u || Width = %"PRIu64" || Height = %u",
|
|
||||||
fmt, desc->MipLevels, desc->DepthOrArraySize, desc->Width, desc->Height);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case D3D12_RESOURCE_DIMENSION_TEXTURE3D:
|
|
||||||
APPEND_SNPRINTF("Tex3D");
|
|
||||||
APPEND_SNPRINTF(" || Format = %s || Levels = %u || Width = %"PRIu64" || Height = %u || Depth = %u",
|
|
||||||
fmt, desc->MipLevels, desc->Width, desc->Height, desc->DepthOrArraySize);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
APPEND_SNPRINTF("Unknown dimension");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (desc->Flags & D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS)
|
|
||||||
APPEND_SNPRINTF(" || UAV");
|
|
||||||
if (desc->Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET)
|
|
||||||
APPEND_SNPRINTF(" || RTV");
|
|
||||||
if (desc->Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL)
|
|
||||||
APPEND_SNPRINTF(" || DSV");
|
|
||||||
|
|
||||||
FLUSH_BUFFER();
|
|
||||||
}
|
|
||||||
|
|
||||||
void vkd3d_descriptor_debug_register_allocation_cookie(
|
|
||||||
struct vkd3d_descriptor_qa_global_info *global_info,
|
|
||||||
uint64_t cookie, const struct vkd3d_allocate_memory_info *info)
|
|
||||||
{
|
|
||||||
D3D12_RESOURCE_DESC1 desc;
|
|
||||||
|
|
||||||
memset(&desc, 0, sizeof(desc));
|
|
||||||
desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
|
|
||||||
desc.Width = info->memory_requirements.size;
|
|
||||||
vkd3d_descriptor_debug_register_resource_cookie(global_info, cookie, &desc);
|
|
||||||
}
|
|
||||||
|
|
||||||
void vkd3d_descriptor_debug_register_view_cookie(
|
|
||||||
struct vkd3d_descriptor_qa_global_info *global_info,
|
|
||||||
uint64_t cookie, uint64_t resource_cookie)
|
|
||||||
{
|
|
||||||
DECL_BUFFER();
|
|
||||||
|
|
||||||
vkd3d_descriptor_debug_set_live_status_bit(global_info, cookie);
|
|
||||||
|
|
||||||
if (!vkd3d_descriptor_debug_active_log())
|
|
||||||
return;
|
|
||||||
APPEND_SNPRINTF("VIEW CREATE #%"PRIu64" <- RESOURCE #%"PRIu64, cookie, resource_cookie);
|
|
||||||
FLUSH_BUFFER();
|
|
||||||
}
|
|
||||||
|
|
||||||
void vkd3d_descriptor_debug_unregister_cookie(
|
|
||||||
struct vkd3d_descriptor_qa_global_info *global_info,
|
|
||||||
uint64_t cookie)
|
|
||||||
{
|
|
||||||
DECL_BUFFER();
|
|
||||||
|
|
||||||
/* Don't unset the null descriptor by mistake. */
|
|
||||||
if (cookie != 0)
|
|
||||||
vkd3d_descriptor_debug_unset_live_status_bit(global_info, cookie);
|
|
||||||
|
|
||||||
if (!vkd3d_descriptor_debug_active_log())
|
|
||||||
return;
|
|
||||||
APPEND_SNPRINTF("COOKIE DESTROY #%"PRIu64, cookie);
|
|
||||||
FLUSH_BUFFER();
|
|
||||||
}
|
|
||||||
|
|
||||||
void vkd3d_descriptor_debug_write_descriptor(struct vkd3d_descriptor_qa_heap_buffer_data *heap, uint64_t heap_cookie,
|
|
||||||
uint32_t offset, vkd3d_descriptor_qa_flags type_flags, uint64_t cookie)
|
|
||||||
{
|
|
||||||
DECL_BUFFER();
|
|
||||||
|
|
||||||
if (heap && offset < heap->num_descriptors)
|
|
||||||
{
|
|
||||||
/* Should never overflow here except if game is literally spamming allocations every frame and we
|
|
||||||
* wait around for hours/days.
|
|
||||||
* This case will trigger warnings either way. */
|
|
||||||
heap->desc[offset].cookie = cookie <= UINT32_MAX ? (uint32_t)cookie : 0u;
|
|
||||||
heap->desc[offset].descriptor_type = type_flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!vkd3d_descriptor_debug_active_log())
|
|
||||||
return;
|
|
||||||
APPEND_SNPRINTF("WRITE HEAP %"PRIu64" || OFFSET = %u || TYPE = %s || COOKIE = #%"PRIu64,
|
|
||||||
heap_cookie, offset, debug_descriptor_type(type_flags), cookie);
|
|
||||||
FLUSH_BUFFER();
|
|
||||||
}
|
|
||||||
|
|
||||||
void vkd3d_descriptor_debug_copy_descriptor(
|
|
||||||
struct vkd3d_descriptor_qa_heap_buffer_data *dst_heap, uint64_t dst_heap_cookie, uint32_t dst_offset,
|
|
||||||
struct vkd3d_descriptor_qa_heap_buffer_data *src_heap, uint64_t src_heap_cookie, uint32_t src_offset,
|
|
||||||
uint64_t cookie)
|
|
||||||
{
|
|
||||||
DECL_BUFFER();
|
|
||||||
|
|
||||||
if (dst_heap && src_heap && dst_offset < dst_heap->num_descriptors && src_offset < src_heap->num_descriptors)
|
|
||||||
dst_heap->desc[dst_offset] = src_heap->desc[src_offset];
|
|
||||||
|
|
||||||
if (!vkd3d_descriptor_debug_active_log())
|
|
||||||
return;
|
|
||||||
APPEND_SNPRINTF("COPY DST HEAP %"PRIu64" || DST OFFSET = %u || COOKIE = #%"PRIu64" || SRC HEAP %"PRIu64" || SRC OFFSET = %u",
|
|
||||||
dst_heap_cookie, dst_offset, cookie, src_heap_cookie, src_offset);
|
|
||||||
FLUSH_BUFFER();
|
|
||||||
}
|
|
4515
libs/vkd3d/device.c
4515
libs/vkd3d/device.c
File diff suppressed because it is too large
Load Diff
|
@ -215,31 +215,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePipelineState_profiled(d3d12
|
||||||
DEVICE_PROFILED_CALL_HRESULT(CreatePipelineState, iface, desc, riid, pipeline_state);
|
DEVICE_PROFILED_CALL_HRESULT(CreatePipelineState, iface, desc, riid, pipeline_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommittedResource2_profiled(d3d12_device_iface *iface,
|
static CONST_VTBL struct ID3D12Device6Vtbl d3d12_device_vtbl_profiled =
|
||||||
const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags, const D3D12_RESOURCE_DESC1 *desc,
|
|
||||||
D3D12_RESOURCE_STATES initial_state, const D3D12_CLEAR_VALUE *optimized_clear_value,
|
|
||||||
ID3D12ProtectedResourceSession *protected_session, REFIID iid, void **resource)
|
|
||||||
{
|
|
||||||
DEVICE_PROFILED_CALL_HRESULT(CreateCommittedResource2, iface, heap_properties, heap_flags,
|
|
||||||
desc, initial_state, optimized_clear_value, protected_session, iid, resource);
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePlacedResource1_profiled(d3d12_device_iface *iface,
|
|
||||||
ID3D12Heap *heap, UINT64 heap_offset, const D3D12_RESOURCE_DESC1 *desc,
|
|
||||||
D3D12_RESOURCE_STATES initial_state, const D3D12_CLEAR_VALUE *optimized_clear_value,
|
|
||||||
REFIID iid, void **resource)
|
|
||||||
{
|
|
||||||
DEVICE_PROFILED_CALL_HRESULT(CreatePlacedResource1, iface, heap, heap_offset,
|
|
||||||
desc, initial_state, optimized_clear_value, iid, resource);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void STDMETHODCALLTYPE d3d12_device_CreateSamplerFeedbackUnorderedAccessView_profiled(d3d12_device_iface *iface,
|
|
||||||
ID3D12Resource *target_resource, ID3D12Resource *feedback_resource, D3D12_CPU_DESCRIPTOR_HANDLE descriptor)
|
|
||||||
{
|
|
||||||
DEVICE_PROFILED_CALL(CreateSamplerFeedbackUnorderedAccessView, iface, target_resource, feedback_resource, descriptor);
|
|
||||||
}
|
|
||||||
|
|
||||||
CONST_VTBL struct ID3D12Device9Vtbl d3d12_device_vtbl_profiled =
|
|
||||||
{
|
{
|
||||||
/* IUnknown methods */
|
/* IUnknown methods */
|
||||||
d3d12_device_QueryInterface,
|
d3d12_device_QueryInterface,
|
||||||
|
@ -249,7 +225,7 @@ CONST_VTBL struct ID3D12Device9Vtbl d3d12_device_vtbl_profiled =
|
||||||
d3d12_device_GetPrivateData,
|
d3d12_device_GetPrivateData,
|
||||||
d3d12_device_SetPrivateData,
|
d3d12_device_SetPrivateData,
|
||||||
d3d12_device_SetPrivateDataInterface,
|
d3d12_device_SetPrivateDataInterface,
|
||||||
(void *)d3d12_object_SetName,
|
d3d12_device_SetName,
|
||||||
/* ID3D12Device methods */
|
/* ID3D12Device methods */
|
||||||
d3d12_device_GetNodeCount,
|
d3d12_device_GetNodeCount,
|
||||||
d3d12_device_CreateCommandQueue,
|
d3d12_device_CreateCommandQueue,
|
||||||
|
@ -316,19 +292,6 @@ CONST_VTBL struct ID3D12Device9Vtbl d3d12_device_vtbl_profiled =
|
||||||
d3d12_device_CheckDriverMatchingIdentifier,
|
d3d12_device_CheckDriverMatchingIdentifier,
|
||||||
/* ID3D12Device6 methods */
|
/* ID3D12Device6 methods */
|
||||||
d3d12_device_SetBackgroundProcessingMode,
|
d3d12_device_SetBackgroundProcessingMode,
|
||||||
/* ID3D12Device7 methods */
|
|
||||||
d3d12_device_AddToStateObject,
|
|
||||||
d3d12_device_CreateProtectedResourceSession1,
|
|
||||||
/* ID3D12Device8 methods */
|
|
||||||
d3d12_device_GetResourceAllocationInfo2,
|
|
||||||
d3d12_device_CreateCommittedResource2_profiled,
|
|
||||||
d3d12_device_CreatePlacedResource1_profiled,
|
|
||||||
d3d12_device_CreateSamplerFeedbackUnorderedAccessView_profiled,
|
|
||||||
d3d12_device_GetCopyableFootprints1,
|
|
||||||
/* ID3D12Device9 methods */
|
|
||||||
d3d12_device_CreateShaderCacheSession,
|
|
||||||
d3d12_device_ShaderCacheControl,
|
|
||||||
d3d12_device_CreateCommandQueue1,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,234 +0,0 @@
|
||||||
/*
|
|
||||||
* * Copyright 2021 NVIDIA Corporation
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define VKD3D_DBG_CHANNEL VKD3D_DBG_CHANNEL_API
|
|
||||||
|
|
||||||
#include "vkd3d_private.h"
|
|
||||||
|
|
||||||
static inline struct d3d12_device *d3d12_device_from_ID3D12DeviceExt(ID3D12DeviceExt *iface)
|
|
||||||
{
|
|
||||||
return CONTAINING_RECORD(iface, struct d3d12_device, ID3D12DeviceExt_iface);
|
|
||||||
}
|
|
||||||
|
|
||||||
ULONG STDMETHODCALLTYPE d3d12_device_vkd3d_ext_AddRef(ID3D12DeviceExt *iface)
|
|
||||||
{
|
|
||||||
struct d3d12_device *device = d3d12_device_from_ID3D12DeviceExt(iface);
|
|
||||||
return d3d12_device_add_ref(device);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ULONG STDMETHODCALLTYPE d3d12_device_vkd3d_ext_Release(ID3D12DeviceExt *iface)
|
|
||||||
{
|
|
||||||
struct d3d12_device *device = d3d12_device_from_ID3D12DeviceExt(iface);
|
|
||||||
return d3d12_device_release(device);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern HRESULT STDMETHODCALLTYPE d3d12_device_QueryInterface(d3d12_device_iface *iface,
|
|
||||||
REFIID riid, void **object);
|
|
||||||
|
|
||||||
static HRESULT STDMETHODCALLTYPE d3d12_device_vkd3d_ext_QueryInterface(ID3D12DeviceExt *iface,
|
|
||||||
REFIID iid, void **out)
|
|
||||||
{
|
|
||||||
struct d3d12_device *device = d3d12_device_from_ID3D12DeviceExt(iface);
|
|
||||||
TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
|
|
||||||
return d3d12_device_QueryInterface(&device->ID3D12Device_iface, iid, out);
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT STDMETHODCALLTYPE d3d12_device_vkd3d_ext_GetVulkanHandles(ID3D12DeviceExt *iface, VkInstance *vk_instance, VkPhysicalDevice *vk_physical_device, VkDevice *vk_device)
|
|
||||||
{
|
|
||||||
struct d3d12_device *device = d3d12_device_from_ID3D12DeviceExt(iface);
|
|
||||||
TRACE("iface %p, vk_instance %p, vk_physical_device %u, vk_device %p \n", iface, vk_instance, vk_physical_device, vk_device);
|
|
||||||
if (!vk_device || !vk_instance || !vk_physical_device)
|
|
||||||
return E_INVALIDARG;
|
|
||||||
|
|
||||||
*vk_instance = device->vkd3d_instance->vk_instance;
|
|
||||||
*vk_physical_device = device->vk_physical_device;
|
|
||||||
*vk_device = device->vk_device;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static BOOL STDMETHODCALLTYPE d3d12_device_vkd3d_ext_GetExtensionSupport(ID3D12DeviceExt *iface, D3D12_VK_EXTENSION extension)
|
|
||||||
{
|
|
||||||
const struct d3d12_device *device = d3d12_device_from_ID3D12DeviceExt(iface);
|
|
||||||
bool ret_val = false;
|
|
||||||
|
|
||||||
TRACE("iface %p, extension %u \n", iface, extension);
|
|
||||||
switch (extension)
|
|
||||||
{
|
|
||||||
case D3D12_VK_NVX_BINARY_IMPORT:
|
|
||||||
ret_val = device->vk_info.NVX_binary_import;
|
|
||||||
break;
|
|
||||||
case D3D12_VK_NVX_IMAGE_VIEW_HANDLE:
|
|
||||||
ret_val = device->vk_info.NVX_image_view_handle;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
WARN("Invalid extension %x\n", extension);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret_val;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT STDMETHODCALLTYPE d3d12_device_vkd3d_ext_CreateCubinComputeShaderWithName(ID3D12DeviceExt *iface, const void *cubin_data,
|
|
||||||
UINT32 cubin_size, UINT32 block_x, UINT32 block_y, UINT32 block_z, const char *shader_name, D3D12_CUBIN_DATA_HANDLE **out_handle)
|
|
||||||
{
|
|
||||||
VkCuFunctionCreateInfoNVX functionCreateInfo = { VK_STRUCTURE_TYPE_CU_FUNCTION_CREATE_INFO_NVX };
|
|
||||||
VkCuModuleCreateInfoNVX moduleCreateInfo = { VK_STRUCTURE_TYPE_CU_MODULE_CREATE_INFO_NVX };
|
|
||||||
const struct vkd3d_vk_device_procs *vk_procs;
|
|
||||||
D3D12_CUBIN_DATA_HANDLE *handle;
|
|
||||||
struct d3d12_device *device;
|
|
||||||
VkDevice vk_device;
|
|
||||||
VkResult vr;
|
|
||||||
|
|
||||||
TRACE("iface %p, cubin_data %p, cubin_size %u, shader_name %s \n", iface, cubin_data, cubin_size, shader_name);
|
|
||||||
if (!cubin_data || !cubin_size || !shader_name)
|
|
||||||
return E_INVALIDARG;
|
|
||||||
|
|
||||||
device = d3d12_device_from_ID3D12DeviceExt(iface);
|
|
||||||
vk_device = device->vk_device;
|
|
||||||
handle = vkd3d_calloc(1, sizeof(D3D12_CUBIN_DATA_HANDLE));
|
|
||||||
handle->blockX = block_x;
|
|
||||||
handle->blockY = block_y;
|
|
||||||
handle->blockZ = block_z;
|
|
||||||
|
|
||||||
moduleCreateInfo.pData = cubin_data;
|
|
||||||
moduleCreateInfo.dataSize = cubin_size;
|
|
||||||
vk_procs = &device->vk_procs;
|
|
||||||
if ((vr = VK_CALL(vkCreateCuModuleNVX(vk_device, &moduleCreateInfo, NULL, &handle->vkCuModule))) < 0)
|
|
||||||
{
|
|
||||||
ERR("Failed to create cubin shader, vr %d.\n", vr);
|
|
||||||
vkd3d_free(handle);
|
|
||||||
return hresult_from_vk_result(vr);
|
|
||||||
}
|
|
||||||
|
|
||||||
functionCreateInfo.module = handle->vkCuModule;
|
|
||||||
functionCreateInfo.pName = shader_name;
|
|
||||||
|
|
||||||
if ((vr = VK_CALL(vkCreateCuFunctionNVX(vk_device, &functionCreateInfo, NULL, &handle->vkCuFunction))) < 0)
|
|
||||||
{
|
|
||||||
ERR("Failed to create cubin function module, vr %d.\n", vr);
|
|
||||||
VK_CALL(vkDestroyCuModuleNVX(vk_device, handle->vkCuModule, NULL));
|
|
||||||
vkd3d_free(handle);
|
|
||||||
return hresult_from_vk_result(vr);
|
|
||||||
}
|
|
||||||
|
|
||||||
*out_handle = handle;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT STDMETHODCALLTYPE d3d12_device_vkd3d_ext_DestroyCubinComputeShader(ID3D12DeviceExt *iface, D3D12_CUBIN_DATA_HANDLE *handle)
|
|
||||||
{
|
|
||||||
const struct vkd3d_vk_device_procs *vk_procs;
|
|
||||||
struct d3d12_device *device;
|
|
||||||
VkDevice vk_device;
|
|
||||||
|
|
||||||
TRACE("iface %p, handle %p \n", iface, handle);
|
|
||||||
if (!iface || !handle)
|
|
||||||
return E_INVALIDARG;
|
|
||||||
|
|
||||||
device = d3d12_device_from_ID3D12DeviceExt(iface);
|
|
||||||
vk_device = device->vk_device;
|
|
||||||
vk_procs = &device->vk_procs;
|
|
||||||
|
|
||||||
VK_CALL(vkDestroyCuFunctionNVX(vk_device, handle->vkCuFunction, NULL));
|
|
||||||
VK_CALL(vkDestroyCuModuleNVX(vk_device, handle->vkCuModule, NULL));
|
|
||||||
vkd3d_free(handle);
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT STDMETHODCALLTYPE d3d12_device_vkd3d_ext_GetCudaTextureObject(ID3D12DeviceExt *iface, D3D12_CPU_DESCRIPTOR_HANDLE srv_handle,
|
|
||||||
D3D12_CPU_DESCRIPTOR_HANDLE sampler_handle, UINT32 *cuda_texture_handle)
|
|
||||||
{
|
|
||||||
VkImageViewHandleInfoNVX imageViewHandleInfo = { VK_STRUCTURE_TYPE_IMAGE_VIEW_HANDLE_INFO_NVX };
|
|
||||||
const struct vkd3d_vk_device_procs *vk_procs;
|
|
||||||
struct d3d12_desc_split sampler_desc;
|
|
||||||
struct d3d12_desc_split srv_desc;
|
|
||||||
struct d3d12_device *device;
|
|
||||||
|
|
||||||
TRACE("iface %p, srv_handle %zu, sampler_handle %zu, cuda_texture_handle %p.\n",
|
|
||||||
iface, srv_handle.ptr, sampler_handle.ptr, cuda_texture_handle);
|
|
||||||
|
|
||||||
if (!cuda_texture_handle)
|
|
||||||
return E_INVALIDARG;
|
|
||||||
|
|
||||||
device = d3d12_device_from_ID3D12DeviceExt(iface);
|
|
||||||
srv_desc = d3d12_desc_decode_va(srv_handle.ptr);
|
|
||||||
sampler_desc = d3d12_desc_decode_va(sampler_handle.ptr);
|
|
||||||
|
|
||||||
imageViewHandleInfo.imageView = srv_desc.view->info.view->vk_image_view;
|
|
||||||
imageViewHandleInfo.sampler = sampler_desc.view->info.view->vk_sampler;
|
|
||||||
imageViewHandleInfo.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
|
||||||
|
|
||||||
vk_procs = &device->vk_procs;
|
|
||||||
*cuda_texture_handle = VK_CALL(vkGetImageViewHandleNVX(device->vk_device, &imageViewHandleInfo));
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT STDMETHODCALLTYPE d3d12_device_vkd3d_ext_GetCudaSurfaceObject(ID3D12DeviceExt *iface, D3D12_CPU_DESCRIPTOR_HANDLE uav_handle,
|
|
||||||
UINT32 *cuda_surface_handle)
|
|
||||||
{
|
|
||||||
VkImageViewHandleInfoNVX imageViewHandleInfo = { VK_STRUCTURE_TYPE_IMAGE_VIEW_HANDLE_INFO_NVX };
|
|
||||||
const struct vkd3d_vk_device_procs *vk_procs;
|
|
||||||
struct d3d12_desc_split uav_desc;
|
|
||||||
struct d3d12_device *device;
|
|
||||||
|
|
||||||
TRACE("iface %p, uav_handle %zu, cuda_surface_handle %p.\n", iface, uav_handle.ptr, cuda_surface_handle);
|
|
||||||
if (!cuda_surface_handle)
|
|
||||||
return E_INVALIDARG;
|
|
||||||
|
|
||||||
device = d3d12_device_from_ID3D12DeviceExt(iface);
|
|
||||||
uav_desc = d3d12_desc_decode_va(uav_handle.ptr);
|
|
||||||
|
|
||||||
imageViewHandleInfo.imageView = uav_desc.view->info.view->vk_image_view;
|
|
||||||
imageViewHandleInfo.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
|
|
||||||
|
|
||||||
vk_procs = &device->vk_procs;
|
|
||||||
*cuda_surface_handle = VK_CALL(vkGetImageViewHandleNVX(device->vk_device, &imageViewHandleInfo));
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern VKD3D_THREAD_LOCAL struct D3D12_UAV_INFO *d3d12_uav_info;
|
|
||||||
|
|
||||||
static HRESULT STDMETHODCALLTYPE d3d12_device_vkd3d_ext_CaptureUAVInfo(ID3D12DeviceExt *iface, D3D12_UAV_INFO *uav_info)
|
|
||||||
{
|
|
||||||
if (!uav_info)
|
|
||||||
return E_INVALIDARG;
|
|
||||||
|
|
||||||
TRACE("iface %p, uav_info %p.\n", iface, uav_info);
|
|
||||||
|
|
||||||
/* CaptureUAVInfo() supposed to capture the information from the next CreateUnorderedAccess() on the same thread.
|
|
||||||
We use d3d12_uav_info pointer to update the information in CreateUnorderedAccess() */
|
|
||||||
d3d12_uav_info = uav_info;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
CONST_VTBL struct ID3D12DeviceExtVtbl d3d12_device_vkd3d_ext_vtbl =
|
|
||||||
{
|
|
||||||
/* IUnknown methods */
|
|
||||||
d3d12_device_vkd3d_ext_QueryInterface,
|
|
||||||
d3d12_device_vkd3d_ext_AddRef,
|
|
||||||
d3d12_device_vkd3d_ext_Release,
|
|
||||||
|
|
||||||
/* ID3D12DeviceExt methods */
|
|
||||||
d3d12_device_vkd3d_ext_GetVulkanHandles,
|
|
||||||
d3d12_device_vkd3d_ext_GetExtensionSupport,
|
|
||||||
d3d12_device_vkd3d_ext_CreateCubinComputeShaderWithName,
|
|
||||||
d3d12_device_vkd3d_ext_DestroyCubinComputeShader,
|
|
||||||
d3d12_device_vkd3d_ext_GetCudaTextureObject,
|
|
||||||
d3d12_device_vkd3d_ext_GetCudaSurfaceObject,
|
|
||||||
d3d12_device_vkd3d_ext_CaptureUAVInfo
|
|
||||||
};
|
|
||||||
|
|
|
@ -1,278 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2016 Józef Kucia for CodeWeavers
|
|
||||||
* Copyright 2019 Conor McCarthy for CodeWeavers
|
|
||||||
* Copyright 2021 Philip Rebohle for Valve Corporation
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define VKD3D_DBG_CHANNEL VKD3D_DBG_CHANNEL_API
|
|
||||||
|
|
||||||
#include "vkd3d_private.h"
|
|
||||||
|
|
||||||
/* ID3D12Heap */
|
|
||||||
static HRESULT STDMETHODCALLTYPE d3d12_heap_QueryInterface(d3d12_heap_iface *iface,
|
|
||||||
REFIID iid, void **object)
|
|
||||||
{
|
|
||||||
TRACE("iface %p, iid %s, object %p.\n", iface, debugstr_guid(iid), object);
|
|
||||||
|
|
||||||
if (IsEqualGUID(iid, &IID_ID3D12Heap)
|
|
||||||
|| IsEqualGUID(iid, &IID_ID3D12Heap1)
|
|
||||||
|| IsEqualGUID(iid, &IID_ID3D12Pageable)
|
|
||||||
|| IsEqualGUID(iid, &IID_ID3D12DeviceChild)
|
|
||||||
|| IsEqualGUID(iid, &IID_ID3D12Object)
|
|
||||||
|| IsEqualGUID(iid, &IID_IUnknown))
|
|
||||||
{
|
|
||||||
ID3D12Heap_AddRef(iface);
|
|
||||||
*object = iface;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
|
|
||||||
|
|
||||||
*object = NULL;
|
|
||||||
return E_NOINTERFACE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ULONG STDMETHODCALLTYPE d3d12_heap_AddRef(d3d12_heap_iface *iface)
|
|
||||||
{
|
|
||||||
struct d3d12_heap *heap = impl_from_ID3D12Heap1(iface);
|
|
||||||
ULONG refcount = InterlockedIncrement(&heap->refcount);
|
|
||||||
|
|
||||||
TRACE("%p increasing refcount to %u.\n", heap, refcount);
|
|
||||||
return refcount;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void d3d12_heap_destroy(struct d3d12_heap *heap)
|
|
||||||
{
|
|
||||||
TRACE("Destroying heap %p.\n", heap);
|
|
||||||
|
|
||||||
vkd3d_free_memory(heap->device, &heap->device->memory_allocator, &heap->allocation);
|
|
||||||
vkd3d_private_store_destroy(&heap->private_store);
|
|
||||||
d3d12_device_release(heap->device);
|
|
||||||
vkd3d_free(heap);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void d3d12_heap_set_name(struct d3d12_heap *heap, const char *name)
|
|
||||||
{
|
|
||||||
if (!heap->allocation.chunk)
|
|
||||||
vkd3d_set_vk_object_name(heap->device, (uint64_t)heap->allocation.device_allocation.vk_memory,
|
|
||||||
VK_OBJECT_TYPE_DEVICE_MEMORY, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ULONG STDMETHODCALLTYPE d3d12_heap_Release(d3d12_heap_iface *iface)
|
|
||||||
{
|
|
||||||
struct d3d12_heap *heap = impl_from_ID3D12Heap1(iface);
|
|
||||||
ULONG refcount = InterlockedDecrement(&heap->refcount);
|
|
||||||
|
|
||||||
TRACE("%p decreasing refcount to %u.\n", heap, refcount);
|
|
||||||
|
|
||||||
if (!refcount)
|
|
||||||
d3d12_heap_destroy(heap);
|
|
||||||
|
|
||||||
return refcount;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT STDMETHODCALLTYPE d3d12_heap_GetPrivateData(d3d12_heap_iface *iface,
|
|
||||||
REFGUID guid, UINT *data_size, void *data)
|
|
||||||
{
|
|
||||||
struct d3d12_heap *heap = impl_from_ID3D12Heap1(iface);
|
|
||||||
|
|
||||||
TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
|
|
||||||
|
|
||||||
return vkd3d_get_private_data(&heap->private_store, guid, data_size, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT STDMETHODCALLTYPE d3d12_heap_SetPrivateData(d3d12_heap_iface *iface,
|
|
||||||
REFGUID guid, UINT data_size, const void *data)
|
|
||||||
{
|
|
||||||
struct d3d12_heap *heap = impl_from_ID3D12Heap1(iface);
|
|
||||||
|
|
||||||
TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
|
|
||||||
|
|
||||||
return vkd3d_set_private_data(&heap->private_store, guid, data_size, data,
|
|
||||||
(vkd3d_set_name_callback) d3d12_heap_set_name, heap);
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT STDMETHODCALLTYPE d3d12_heap_SetPrivateDataInterface(d3d12_heap_iface *iface,
|
|
||||||
REFGUID guid, const IUnknown *data)
|
|
||||||
{
|
|
||||||
struct d3d12_heap *heap = impl_from_ID3D12Heap1(iface);
|
|
||||||
|
|
||||||
TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
|
|
||||||
|
|
||||||
return vkd3d_set_private_data_interface(&heap->private_store, guid, data,
|
|
||||||
(vkd3d_set_name_callback) d3d12_heap_set_name, heap);
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT STDMETHODCALLTYPE d3d12_heap_GetDevice(d3d12_heap_iface *iface, REFIID iid, void **device)
|
|
||||||
{
|
|
||||||
struct d3d12_heap *heap = impl_from_ID3D12Heap1(iface);
|
|
||||||
|
|
||||||
TRACE("iface %p, iid %s, device %p.\n", iface, debugstr_guid(iid), device);
|
|
||||||
|
|
||||||
return d3d12_device_query_interface(heap->device, iid, device);
|
|
||||||
}
|
|
||||||
|
|
||||||
static D3D12_HEAP_DESC * STDMETHODCALLTYPE d3d12_heap_GetDesc(d3d12_heap_iface *iface,
|
|
||||||
D3D12_HEAP_DESC *desc)
|
|
||||||
{
|
|
||||||
struct d3d12_heap *heap = impl_from_ID3D12Heap1(iface);
|
|
||||||
|
|
||||||
TRACE("iface %p, desc %p.\n", iface, desc);
|
|
||||||
|
|
||||||
*desc = heap->desc;
|
|
||||||
return desc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT STDMETHODCALLTYPE d3d12_heap_GetProtectedResourceSession(d3d12_heap_iface *iface,
|
|
||||||
REFIID iid, void **protected_session)
|
|
||||||
{
|
|
||||||
FIXME("iface %p, iid %s, protected_session %p stub!", iface, debugstr_guid(iid), protected_session);
|
|
||||||
|
|
||||||
return E_NOTIMPL;
|
|
||||||
}
|
|
||||||
|
|
||||||
CONST_VTBL struct ID3D12Heap1Vtbl d3d12_heap_vtbl =
|
|
||||||
{
|
|
||||||
/* IUnknown methods */
|
|
||||||
d3d12_heap_QueryInterface,
|
|
||||||
d3d12_heap_AddRef,
|
|
||||||
d3d12_heap_Release,
|
|
||||||
/* ID3D12Object methods */
|
|
||||||
d3d12_heap_GetPrivateData,
|
|
||||||
d3d12_heap_SetPrivateData,
|
|
||||||
d3d12_heap_SetPrivateDataInterface,
|
|
||||||
(void *)d3d12_object_SetName,
|
|
||||||
/* ID3D12DeviceChild methods */
|
|
||||||
d3d12_heap_GetDevice,
|
|
||||||
/* ID3D12Heap methods */
|
|
||||||
d3d12_heap_GetDesc,
|
|
||||||
/* ID3D12Heap1 methods */
|
|
||||||
d3d12_heap_GetProtectedResourceSession,
|
|
||||||
};
|
|
||||||
|
|
||||||
HRESULT d3d12_device_validate_custom_heap_type(struct d3d12_device *device,
|
|
||||||
const D3D12_HEAP_PROPERTIES *heap_properties)
|
|
||||||
{
|
|
||||||
if (heap_properties->Type != D3D12_HEAP_TYPE_CUSTOM)
|
|
||||||
return S_OK;
|
|
||||||
|
|
||||||
if (heap_properties->MemoryPoolPreference == D3D12_MEMORY_POOL_UNKNOWN
|
|
||||||
|| (heap_properties->MemoryPoolPreference == D3D12_MEMORY_POOL_L1
|
|
||||||
&& (is_cpu_accessible_heap(heap_properties) || d3d12_device_is_uma(device, NULL))))
|
|
||||||
{
|
|
||||||
WARN("Invalid memory pool preference.\n");
|
|
||||||
return E_INVALIDARG;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (heap_properties->CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_UNKNOWN)
|
|
||||||
{
|
|
||||||
WARN("Must have explicit CPU page property for CUSTOM heap type.\n");
|
|
||||||
return E_INVALIDARG;
|
|
||||||
}
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT validate_heap_desc(struct d3d12_device *device, const D3D12_HEAP_DESC *desc)
|
|
||||||
{
|
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
if (!desc->SizeInBytes)
|
|
||||||
{
|
|
||||||
WARN("Invalid size %"PRIu64".\n", desc->SizeInBytes);
|
|
||||||
return E_INVALIDARG;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (desc->Alignment != D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT
|
|
||||||
&& desc->Alignment != D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT)
|
|
||||||
{
|
|
||||||
WARN("Invalid alignment %"PRIu64".\n", desc->Alignment);
|
|
||||||
return E_INVALIDARG;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (desc->Flags & D3D12_HEAP_FLAG_ALLOW_DISPLAY)
|
|
||||||
{
|
|
||||||
WARN("D3D12_HEAP_FLAG_ALLOW_DISPLAY is only for committed resources.\n");
|
|
||||||
return E_INVALIDARG;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FAILED(hr = d3d12_device_validate_custom_heap_type(device, &desc->Properties)))
|
|
||||||
return hr;
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT d3d12_heap_init(struct d3d12_heap *heap, struct d3d12_device *device,
|
|
||||||
const D3D12_HEAP_DESC *desc, void* host_address)
|
|
||||||
{
|
|
||||||
struct vkd3d_allocate_heap_memory_info alloc_info;
|
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
memset(heap, 0, sizeof(*heap));
|
|
||||||
heap->ID3D12Heap_iface.lpVtbl = &d3d12_heap_vtbl;
|
|
||||||
heap->refcount = 1;
|
|
||||||
heap->desc = *desc;
|
|
||||||
heap->device = device;
|
|
||||||
|
|
||||||
if (!heap->desc.Properties.CreationNodeMask)
|
|
||||||
heap->desc.Properties.CreationNodeMask = 1;
|
|
||||||
if (!heap->desc.Properties.VisibleNodeMask)
|
|
||||||
heap->desc.Properties.VisibleNodeMask = 1;
|
|
||||||
if (!heap->desc.Alignment)
|
|
||||||
heap->desc.Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
|
|
||||||
|
|
||||||
if (FAILED(hr = validate_heap_desc(device, &heap->desc)))
|
|
||||||
return hr;
|
|
||||||
|
|
||||||
alloc_info.heap_desc = heap->desc;
|
|
||||||
alloc_info.host_ptr = host_address;
|
|
||||||
alloc_info.extra_allocation_flags = 0;
|
|
||||||
|
|
||||||
if (FAILED(hr = vkd3d_private_store_init(&heap->private_store)))
|
|
||||||
return hr;
|
|
||||||
|
|
||||||
if (FAILED(hr = vkd3d_allocate_heap_memory(device,
|
|
||||||
&device->memory_allocator, &alloc_info, &heap->allocation)))
|
|
||||||
{
|
|
||||||
vkd3d_private_store_destroy(&heap->private_store);
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
d3d12_device_add_ref(heap->device);
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT d3d12_heap_create(struct d3d12_device *device, const D3D12_HEAP_DESC *desc,
|
|
||||||
void* host_address, struct d3d12_heap **heap)
|
|
||||||
{
|
|
||||||
struct d3d12_heap *object;
|
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
if (!(object = vkd3d_malloc(sizeof(*object))))
|
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
|
|
||||||
if (FAILED(hr = d3d12_heap_init(object, device, desc, host_address)))
|
|
||||||
{
|
|
||||||
vkd3d_free(object);
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
TRACE("Created heap %p.\n", object);
|
|
||||||
|
|
||||||
*heap = object;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
1595
libs/vkd3d/memory.c
1595
libs/vkd3d/memory.c
File diff suppressed because it is too large
Load Diff
|
@ -12,14 +12,9 @@ vkd3d_shaders =[
|
||||||
'shaders/cs_clear_uav_image_2d_uint.comp',
|
'shaders/cs_clear_uav_image_2d_uint.comp',
|
||||||
'shaders/cs_clear_uav_image_3d_float.comp',
|
'shaders/cs_clear_uav_image_3d_float.comp',
|
||||||
'shaders/cs_clear_uav_image_3d_uint.comp',
|
'shaders/cs_clear_uav_image_3d_uint.comp',
|
||||||
'shaders/cs_predicate_command.comp',
|
|
||||||
'shaders/cs_resolve_binary_queries.comp',
|
'shaders/cs_resolve_binary_queries.comp',
|
||||||
'shaders/cs_resolve_predicate.comp',
|
|
||||||
'shaders/cs_resolve_query.comp',
|
|
||||||
|
|
||||||
'shaders/fs_copy_image_float.frag',
|
'shaders/fs_copy_image_float.frag',
|
||||||
'shaders/fs_copy_image_uint.frag',
|
|
||||||
'shaders/fs_copy_image_stencil.frag',
|
|
||||||
|
|
||||||
'shaders/gs_fullscreen.geom',
|
'shaders/gs_fullscreen.geom',
|
||||||
'shaders/vs_fullscreen.vert',
|
'shaders/vs_fullscreen.vert',
|
||||||
|
@ -27,28 +22,19 @@ vkd3d_shaders =[
|
||||||
|
|
||||||
'shaders/vs_swapchain_fullscreen.vert',
|
'shaders/vs_swapchain_fullscreen.vert',
|
||||||
'shaders/fs_swapchain_fullscreen.frag',
|
'shaders/fs_swapchain_fullscreen.frag',
|
||||||
'shaders/cs_execute_indirect_patch.comp',
|
|
||||||
'shaders/cs_execute_indirect_patch_debug_ring.comp',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
vkd3d_src = [
|
vkd3d_src = [
|
||||||
'bundle.c',
|
|
||||||
'cache.c',
|
'cache.c',
|
||||||
'command.c',
|
'command.c',
|
||||||
'command_list_vkd3d_ext.c',
|
|
||||||
'device.c',
|
'device.c',
|
||||||
'device_vkd3d_ext.c',
|
|
||||||
'heap.c',
|
|
||||||
'memory.c',
|
|
||||||
'meta.c',
|
'meta.c',
|
||||||
|
'platform.c',
|
||||||
'resource.c',
|
'resource.c',
|
||||||
'state.c',
|
'state.c',
|
||||||
'utils.c',
|
'utils.c',
|
||||||
'debug_ring.c',
|
'debug_ring.c',
|
||||||
'va_map.c',
|
|
||||||
'vkd3d_main.c',
|
'vkd3d_main.c',
|
||||||
'raytracing_pipeline.c',
|
|
||||||
'acceleration_structure.c'
|
|
||||||
]
|
]
|
||||||
|
|
||||||
if enable_d3d12
|
if enable_d3d12
|
||||||
|
@ -59,24 +45,12 @@ if enable_renderdoc
|
||||||
vkd3d_src += ['renderdoc.c']
|
vkd3d_src += ['renderdoc.c']
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if enable_descriptor_qa
|
|
||||||
vkd3d_src += ['descriptor_debug.c']
|
|
||||||
endif
|
|
||||||
|
|
||||||
if enable_breadcrumbs
|
|
||||||
vkd3d_src += ['breadcrumbs.c']
|
|
||||||
endif
|
|
||||||
|
|
||||||
if vkd3d_platform == 'windows'
|
|
||||||
vkd3d_src += ['shared_metadata.c']
|
|
||||||
endif
|
|
||||||
|
|
||||||
if not enable_d3d12
|
if not enable_d3d12
|
||||||
vkd3d_lib = shared_library('vkd3d-proton', vkd3d_src, glsl_generator.process(vkd3d_shaders), vkd3d_build, vkd3d_version,
|
vkd3d_lib = shared_library('vkd3d-proton', vkd3d_src, glsl_generator.process(vkd3d_shaders), vkd3d_build, vkd3d_version,
|
||||||
dependencies : [ vkd3d_common_dep, vkd3d_shader_dep ] + vkd3d_extra_libs,
|
dependencies : [ vkd3d_common_dep, vkd3d_shader_dep ] + vkd3d_extra_libs,
|
||||||
include_directories : vkd3d_private_includes,
|
include_directories : vkd3d_private_includes,
|
||||||
install : true,
|
install : true,
|
||||||
version : '3.0.0',
|
version : '2.0.0',
|
||||||
c_args : '-DVKD3D_EXPORTS',
|
c_args : '-DVKD3D_EXPORTS',
|
||||||
override_options : [ 'c_std='+vkd3d_c_std ])
|
override_options : [ 'c_std='+vkd3d_c_std ])
|
||||||
else
|
else
|
||||||
|
|
|
@ -137,8 +137,68 @@ static VkResult vkd3d_meta_create_compute_pipeline(struct d3d12_device *device,
|
||||||
return vr;
|
return vr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VkResult vkd3d_meta_create_render_pass(struct d3d12_device *device, VkSampleCountFlagBits samples,
|
||||||
|
const struct vkd3d_format *format, VkRenderPass *vk_render_pass)
|
||||||
|
{
|
||||||
|
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
||||||
|
VkAttachmentDescription attachment_info;
|
||||||
|
VkAttachmentReference attachment_ref;
|
||||||
|
VkSubpassDescription subpass_info;
|
||||||
|
VkRenderPassCreateInfo pass_info;
|
||||||
|
bool has_depth_target;
|
||||||
|
VkImageLayout layout;
|
||||||
|
VkResult vr;
|
||||||
|
|
||||||
|
assert(format);
|
||||||
|
|
||||||
|
has_depth_target = (format->vk_aspect_mask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) != 0;
|
||||||
|
|
||||||
|
layout = has_depth_target
|
||||||
|
? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
|
||||||
|
: VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||||
|
|
||||||
|
attachment_info.flags = 0;
|
||||||
|
attachment_info.format = format->vk_format;
|
||||||
|
attachment_info.samples = samples;
|
||||||
|
attachment_info.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||||
|
attachment_info.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||||
|
attachment_info.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||||
|
attachment_info.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||||
|
attachment_info.initialLayout = layout;
|
||||||
|
attachment_info.finalLayout = layout;
|
||||||
|
|
||||||
|
attachment_ref.attachment = 0;
|
||||||
|
attachment_ref.layout = layout;
|
||||||
|
|
||||||
|
subpass_info.flags = 0;
|
||||||
|
subpass_info.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
||||||
|
subpass_info.inputAttachmentCount = 0;
|
||||||
|
subpass_info.pInputAttachments = NULL;
|
||||||
|
subpass_info.colorAttachmentCount = has_depth_target ? 0 : 1;
|
||||||
|
subpass_info.pColorAttachments = has_depth_target ? NULL : &attachment_ref;
|
||||||
|
subpass_info.pResolveAttachments = NULL;
|
||||||
|
subpass_info.pDepthStencilAttachment = has_depth_target ? &attachment_ref : NULL;
|
||||||
|
subpass_info.preserveAttachmentCount = 0;
|
||||||
|
subpass_info.pPreserveAttachments = NULL;
|
||||||
|
|
||||||
|
pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
|
||||||
|
pass_info.pNext = NULL;
|
||||||
|
pass_info.flags = 0;
|
||||||
|
pass_info.attachmentCount = 1;
|
||||||
|
pass_info.pAttachments = &attachment_info;
|
||||||
|
pass_info.subpassCount = 1;
|
||||||
|
pass_info.pSubpasses = &subpass_info;
|
||||||
|
pass_info.dependencyCount = 0;
|
||||||
|
pass_info.pDependencies = NULL;
|
||||||
|
|
||||||
|
if ((vr = VK_CALL(vkCreateRenderPass(device->vk_device, &pass_info, NULL, vk_render_pass))) < 0)
|
||||||
|
ERR("Failed to create render pass, vr %d.\n", vr);
|
||||||
|
|
||||||
|
return vr;
|
||||||
|
}
|
||||||
|
|
||||||
static VkResult vkd3d_meta_create_graphics_pipeline(struct vkd3d_meta_ops *meta_ops,
|
static VkResult vkd3d_meta_create_graphics_pipeline(struct vkd3d_meta_ops *meta_ops,
|
||||||
VkPipelineLayout layout, VkFormat color_format, VkFormat ds_format, VkImageAspectFlags vk_aspect_mask,
|
VkPipelineLayout layout, VkRenderPass render_pass,
|
||||||
VkShaderModule vs_module, VkShaderModule fs_module,
|
VkShaderModule vs_module, VkShaderModule fs_module,
|
||||||
VkSampleCountFlagBits samples, const VkPipelineDepthStencilStateCreateInfo *ds_state,
|
VkSampleCountFlagBits samples, const VkPipelineDepthStencilStateCreateInfo *ds_state,
|
||||||
const VkPipelineColorBlendStateCreateInfo *cb_state, const VkSpecializationInfo *spec_info,
|
const VkPipelineColorBlendStateCreateInfo *cb_state, const VkSpecializationInfo *spec_info,
|
||||||
|
@ -148,7 +208,6 @@ static VkResult vkd3d_meta_create_graphics_pipeline(struct vkd3d_meta_ops *meta_
|
||||||
VkPipelineShaderStageCreateInfo shader_stages[3];
|
VkPipelineShaderStageCreateInfo shader_stages[3];
|
||||||
VkPipelineInputAssemblyStateCreateInfo ia_state;
|
VkPipelineInputAssemblyStateCreateInfo ia_state;
|
||||||
VkPipelineRasterizationStateCreateInfo rs_state;
|
VkPipelineRasterizationStateCreateInfo rs_state;
|
||||||
VkPipelineRenderingCreateInfoKHR rendering_info;
|
|
||||||
VkPipelineVertexInputStateCreateInfo vi_state;
|
VkPipelineVertexInputStateCreateInfo vi_state;
|
||||||
VkPipelineMultisampleStateCreateInfo ms_state;
|
VkPipelineMultisampleStateCreateInfo ms_state;
|
||||||
VkPipelineViewportStateCreateInfo vp_state;
|
VkPipelineViewportStateCreateInfo vp_state;
|
||||||
|
@ -215,16 +274,8 @@ static VkResult vkd3d_meta_create_graphics_pipeline(struct vkd3d_meta_ops *meta_
|
||||||
dyn_state.dynamicStateCount = ARRAY_SIZE(dynamic_states);
|
dyn_state.dynamicStateCount = ARRAY_SIZE(dynamic_states);
|
||||||
dyn_state.pDynamicStates = dynamic_states;
|
dyn_state.pDynamicStates = dynamic_states;
|
||||||
|
|
||||||
rendering_info.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR;
|
|
||||||
rendering_info.pNext = NULL;
|
|
||||||
rendering_info.viewMask = 0;
|
|
||||||
rendering_info.colorAttachmentCount = color_format && (vk_aspect_mask & VK_IMAGE_ASPECT_COLOR_BIT) ? 1 : 0;
|
|
||||||
rendering_info.pColorAttachmentFormats = color_format ? &color_format : NULL;
|
|
||||||
rendering_info.depthAttachmentFormat = (vk_aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT) ? ds_format : VK_FORMAT_UNDEFINED;
|
|
||||||
rendering_info.stencilAttachmentFormat = (vk_aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT) ? ds_format : VK_FORMAT_UNDEFINED;
|
|
||||||
|
|
||||||
pipeline_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
|
pipeline_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
|
||||||
pipeline_info.pNext = &rendering_info;
|
pipeline_info.pNext = NULL;
|
||||||
pipeline_info.flags = 0;
|
pipeline_info.flags = 0;
|
||||||
pipeline_info.stageCount = 0;
|
pipeline_info.stageCount = 0;
|
||||||
pipeline_info.pStages = shader_stages;
|
pipeline_info.pStages = shader_stages;
|
||||||
|
@ -238,7 +289,7 @@ static VkResult vkd3d_meta_create_graphics_pipeline(struct vkd3d_meta_ops *meta_
|
||||||
pipeline_info.pColorBlendState = cb_state;
|
pipeline_info.pColorBlendState = cb_state;
|
||||||
pipeline_info.pDynamicState = &dyn_state;
|
pipeline_info.pDynamicState = &dyn_state;
|
||||||
pipeline_info.layout = layout;
|
pipeline_info.layout = layout;
|
||||||
pipeline_info.renderPass = VK_NULL_HANDLE;
|
pipeline_info.renderPass = render_pass;
|
||||||
pipeline_info.subpass = 0;
|
pipeline_info.subpass = 0;
|
||||||
pipeline_info.basePipelineHandle = VK_NULL_HANDLE;
|
pipeline_info.basePipelineHandle = VK_NULL_HANDLE;
|
||||||
pipeline_info.basePipelineIndex = -1;
|
pipeline_info.basePipelineIndex = -1;
|
||||||
|
@ -536,30 +587,12 @@ HRESULT vkd3d_copy_image_ops_init(struct vkd3d_copy_image_ops *meta_copy_image_o
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((vr = vkd3d_meta_create_shader_module(device, SPIRV_CODE(fs_copy_image_float),
|
if ((vr = vkd3d_meta_create_shader_module(device, SPIRV_CODE(fs_copy_image_float), &meta_copy_image_ops->vk_fs_module)) < 0)
|
||||||
&meta_copy_image_ops->vk_fs_float_module)) < 0)
|
|
||||||
{
|
{
|
||||||
ERR("Failed to create shader modules, vr %d.\n", vr);
|
ERR("Failed to create shader modules, vr %d.\n", vr);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((vr = vkd3d_meta_create_shader_module(device, SPIRV_CODE(fs_copy_image_uint),
|
|
||||||
&meta_copy_image_ops->vk_fs_uint_module)) < 0)
|
|
||||||
{
|
|
||||||
ERR("Failed to create shader modules, vr %d.\n", vr);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (device->vk_info.EXT_shader_stencil_export)
|
|
||||||
{
|
|
||||||
if ((vr = vkd3d_meta_create_shader_module(device, SPIRV_CODE(fs_copy_image_stencil),
|
|
||||||
&meta_copy_image_ops->vk_fs_stencil_module)) < 0)
|
|
||||||
{
|
|
||||||
ERR("Failed to create shader modules, vr %d.\n", vr);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
@ -577,28 +610,83 @@ void vkd3d_copy_image_ops_cleanup(struct vkd3d_copy_image_ops *meta_copy_image_o
|
||||||
{
|
{
|
||||||
struct vkd3d_copy_image_pipeline *pipeline = &meta_copy_image_ops->pipelines[i];
|
struct vkd3d_copy_image_pipeline *pipeline = &meta_copy_image_ops->pipelines[i];
|
||||||
|
|
||||||
|
VK_CALL(vkDestroyRenderPass(device->vk_device, pipeline->vk_render_pass, NULL));
|
||||||
VK_CALL(vkDestroyPipeline(device->vk_device, pipeline->vk_pipeline, NULL));
|
VK_CALL(vkDestroyPipeline(device->vk_device, pipeline->vk_pipeline, NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
VK_CALL(vkDestroyDescriptorSetLayout(device->vk_device, meta_copy_image_ops->vk_set_layout, NULL));
|
VK_CALL(vkDestroyDescriptorSetLayout(device->vk_device, meta_copy_image_ops->vk_set_layout, NULL));
|
||||||
VK_CALL(vkDestroyPipelineLayout(device->vk_device, meta_copy_image_ops->vk_pipeline_layout, NULL));
|
VK_CALL(vkDestroyPipelineLayout(device->vk_device, meta_copy_image_ops->vk_pipeline_layout, NULL));
|
||||||
VK_CALL(vkDestroyShaderModule(device->vk_device, meta_copy_image_ops->vk_fs_float_module, NULL));
|
VK_CALL(vkDestroyShaderModule(device->vk_device, meta_copy_image_ops->vk_fs_module, NULL));
|
||||||
VK_CALL(vkDestroyShaderModule(device->vk_device, meta_copy_image_ops->vk_fs_uint_module, NULL));
|
|
||||||
VK_CALL(vkDestroyShaderModule(device->vk_device, meta_copy_image_ops->vk_fs_stencil_module, NULL));
|
|
||||||
|
|
||||||
pthread_mutex_destroy(&meta_copy_image_ops->mutex);
|
pthread_mutex_destroy(&meta_copy_image_ops->mutex);
|
||||||
|
|
||||||
vkd3d_free(meta_copy_image_ops->pipelines);
|
vkd3d_free(meta_copy_image_ops->pipelines);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VkResult vkd3d_meta_create_swapchain_render_pass(struct d3d12_device *device,
|
||||||
|
const struct vkd3d_swapchain_pipeline_key *key, VkRenderPass *render_pass)
|
||||||
|
{
|
||||||
|
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
||||||
|
VkRenderPassCreateInfo render_pass_info;
|
||||||
|
VkAttachmentDescription attachment_desc;
|
||||||
|
VkAttachmentReference attachment_ref;
|
||||||
|
VkSubpassDescription subpass_desc;
|
||||||
|
VkSubpassDependency subpass_dep;
|
||||||
|
|
||||||
|
render_pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
|
||||||
|
render_pass_info.pNext = NULL;
|
||||||
|
render_pass_info.flags = 0;
|
||||||
|
render_pass_info.attachmentCount = 1;
|
||||||
|
render_pass_info.pAttachments = &attachment_desc;
|
||||||
|
render_pass_info.subpassCount = 1;
|
||||||
|
render_pass_info.pSubpasses = &subpass_desc;
|
||||||
|
render_pass_info.dependencyCount = 1;
|
||||||
|
render_pass_info.pDependencies = &subpass_dep;
|
||||||
|
|
||||||
|
attachment_desc.loadOp = key->load_op;
|
||||||
|
attachment_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||||
|
attachment_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||||
|
attachment_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||||
|
attachment_desc.format = key->format;
|
||||||
|
attachment_desc.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
|
attachment_desc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
|
attachment_desc.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||||
|
attachment_desc.flags = 0;
|
||||||
|
|
||||||
|
attachment_ref.attachment = 0;
|
||||||
|
attachment_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||||
|
|
||||||
|
memset(&subpass_desc, 0, sizeof(subpass_desc));
|
||||||
|
subpass_desc.colorAttachmentCount = 1;
|
||||||
|
subpass_desc.pColorAttachments = &attachment_ref;
|
||||||
|
subpass_desc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
||||||
|
|
||||||
|
subpass_dep.srcSubpass = VK_SUBPASS_EXTERNAL;
|
||||||
|
subpass_dep.dstSubpass = 0;
|
||||||
|
subpass_dep.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||||
|
subpass_dep.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||||
|
subpass_dep.srcAccessMask = 0;
|
||||||
|
subpass_dep.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||||
|
subpass_dep.dependencyFlags = 0;
|
||||||
|
|
||||||
|
return VK_CALL(vkCreateRenderPass(device->vk_device, &render_pass_info, NULL, render_pass));
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT vkd3d_meta_create_swapchain_pipeline(struct vkd3d_meta_ops *meta_ops,
|
static HRESULT vkd3d_meta_create_swapchain_pipeline(struct vkd3d_meta_ops *meta_ops,
|
||||||
const struct vkd3d_swapchain_pipeline_key *key, struct vkd3d_swapchain_pipeline *pipeline)
|
const struct vkd3d_swapchain_pipeline_key *key, struct vkd3d_swapchain_pipeline *pipeline)
|
||||||
{
|
{
|
||||||
|
const struct vkd3d_vk_device_procs *vk_procs = &meta_ops->device->vk_procs;
|
||||||
struct vkd3d_swapchain_ops *meta_swapchain_ops = &meta_ops->swapchain;
|
struct vkd3d_swapchain_ops *meta_swapchain_ops = &meta_ops->swapchain;
|
||||||
VkPipelineColorBlendAttachmentState blend_att;
|
VkPipelineColorBlendAttachmentState blend_att;
|
||||||
VkPipelineColorBlendStateCreateInfo cb_state;
|
VkPipelineColorBlendStateCreateInfo cb_state;
|
||||||
VkResult vr;
|
VkResult vr;
|
||||||
|
|
||||||
|
if ((vr = vkd3d_meta_create_swapchain_render_pass(meta_ops->device, key, &pipeline->vk_render_pass)))
|
||||||
|
{
|
||||||
|
ERR("Failed to create render pass, vr %d.\n", vr);
|
||||||
|
return hresult_from_vk_result(vr);
|
||||||
|
}
|
||||||
|
|
||||||
memset(&cb_state, 0, sizeof(cb_state));
|
memset(&cb_state, 0, sizeof(cb_state));
|
||||||
memset(&blend_att, 0, sizeof(blend_att));
|
memset(&blend_att, 0, sizeof(blend_att));
|
||||||
cb_state.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
|
cb_state.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
|
||||||
|
@ -611,11 +699,14 @@ static HRESULT vkd3d_meta_create_swapchain_pipeline(struct vkd3d_meta_ops *meta_
|
||||||
VK_COLOR_COMPONENT_A_BIT;
|
VK_COLOR_COMPONENT_A_BIT;
|
||||||
|
|
||||||
if ((vr = vkd3d_meta_create_graphics_pipeline(meta_ops,
|
if ((vr = vkd3d_meta_create_graphics_pipeline(meta_ops,
|
||||||
meta_swapchain_ops->vk_pipeline_layouts[key->filter], key->format, VK_FORMAT_UNDEFINED, VK_IMAGE_ASPECT_COLOR_BIT,
|
meta_swapchain_ops->vk_pipeline_layouts[key->filter], pipeline->vk_render_pass,
|
||||||
meta_swapchain_ops->vk_vs_module, meta_swapchain_ops->vk_fs_module, 1,
|
meta_swapchain_ops->vk_vs_module, meta_swapchain_ops->vk_fs_module, 1,
|
||||||
NULL, &cb_state,
|
NULL, &cb_state,
|
||||||
NULL, &pipeline->vk_pipeline)) < 0)
|
NULL, &pipeline->vk_pipeline)) < 0)
|
||||||
|
{
|
||||||
|
VK_CALL(vkDestroyRenderPass(meta_ops->device->vk_device, pipeline->vk_render_pass, NULL));
|
||||||
return hresult_from_vk_result(vr);
|
return hresult_from_vk_result(vr);
|
||||||
|
}
|
||||||
|
|
||||||
pipeline->key = *key;
|
pipeline->key = *key;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
@ -624,12 +715,12 @@ static HRESULT vkd3d_meta_create_swapchain_pipeline(struct vkd3d_meta_ops *meta_
|
||||||
static HRESULT vkd3d_meta_create_copy_image_pipeline(struct vkd3d_meta_ops *meta_ops,
|
static HRESULT vkd3d_meta_create_copy_image_pipeline(struct vkd3d_meta_ops *meta_ops,
|
||||||
const struct vkd3d_copy_image_pipeline_key *key, struct vkd3d_copy_image_pipeline *pipeline)
|
const struct vkd3d_copy_image_pipeline_key *key, struct vkd3d_copy_image_pipeline *pipeline)
|
||||||
{
|
{
|
||||||
|
const struct vkd3d_vk_device_procs *vk_procs = &meta_ops->device->vk_procs;
|
||||||
struct vkd3d_copy_image_ops *meta_copy_image_ops = &meta_ops->copy_image;
|
struct vkd3d_copy_image_ops *meta_copy_image_ops = &meta_ops->copy_image;
|
||||||
VkPipelineColorBlendAttachmentState blend_attachment;
|
VkPipelineColorBlendAttachmentState blend_attachment;
|
||||||
VkPipelineDepthStencilStateCreateInfo ds_state;
|
VkPipelineDepthStencilStateCreateInfo ds_state;
|
||||||
VkPipelineColorBlendStateCreateInfo cb_state;
|
VkPipelineColorBlendStateCreateInfo cb_state;
|
||||||
VkSpecializationInfo spec_info;
|
VkSpecializationInfo spec_info;
|
||||||
VkShaderModule vk_module;
|
|
||||||
bool has_depth_target;
|
bool has_depth_target;
|
||||||
VkResult vr;
|
VkResult vr;
|
||||||
|
|
||||||
|
@ -668,30 +759,13 @@ static HRESULT vkd3d_meta_create_copy_image_pipeline(struct vkd3d_meta_ops *meta
|
||||||
ds_state.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
|
ds_state.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
|
||||||
ds_state.pNext = NULL;
|
ds_state.pNext = NULL;
|
||||||
ds_state.flags = 0;
|
ds_state.flags = 0;
|
||||||
ds_state.depthTestEnable = (key->dst_aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT) ? VK_TRUE : VK_FALSE;
|
ds_state.depthTestEnable = VK_TRUE;
|
||||||
ds_state.depthWriteEnable = ds_state.depthTestEnable;
|
ds_state.depthWriteEnable = VK_TRUE;
|
||||||
ds_state.depthCompareOp = VK_COMPARE_OP_ALWAYS;
|
ds_state.depthCompareOp = VK_COMPARE_OP_ALWAYS;
|
||||||
ds_state.depthBoundsTestEnable = VK_FALSE;
|
ds_state.depthBoundsTestEnable = VK_FALSE;
|
||||||
|
|
||||||
if (key->dst_aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT)
|
|
||||||
{
|
|
||||||
ds_state.stencilTestEnable = VK_TRUE;
|
|
||||||
ds_state.front.reference = 0;
|
|
||||||
ds_state.front.writeMask = 0xff;
|
|
||||||
ds_state.front.compareMask = 0xff;
|
|
||||||
ds_state.front.passOp = VK_STENCIL_OP_REPLACE;
|
|
||||||
ds_state.front.failOp = VK_STENCIL_OP_KEEP;
|
|
||||||
ds_state.front.depthFailOp = VK_STENCIL_OP_KEEP;
|
|
||||||
ds_state.front.compareOp = VK_COMPARE_OP_ALWAYS;
|
|
||||||
ds_state.back = ds_state.front;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ds_state.stencilTestEnable = VK_FALSE;
|
ds_state.stencilTestEnable = VK_FALSE;
|
||||||
memset(&ds_state.front, 0, sizeof(ds_state.front));
|
memset(&ds_state.front, 0, sizeof(ds_state.front));
|
||||||
memset(&ds_state.back, 0, sizeof(ds_state.back));
|
memset(&ds_state.back, 0, sizeof(ds_state.back));
|
||||||
}
|
|
||||||
|
|
||||||
ds_state.minDepthBounds = 0.0f;
|
ds_state.minDepthBounds = 0.0f;
|
||||||
ds_state.maxDepthBounds = 1.0f;
|
ds_state.maxDepthBounds = 1.0f;
|
||||||
|
|
||||||
|
@ -710,32 +784,19 @@ static HRESULT vkd3d_meta_create_copy_image_pipeline(struct vkd3d_meta_ops *meta
|
||||||
cb_state.pAttachments = &blend_attachment;
|
cb_state.pAttachments = &blend_attachment;
|
||||||
memset(&cb_state.blendConstants, 0, sizeof(cb_state.blendConstants));
|
memset(&cb_state.blendConstants, 0, sizeof(cb_state.blendConstants));
|
||||||
|
|
||||||
/* Special path when copying stencil -> color. */
|
if ((vr = vkd3d_meta_create_render_pass(meta_ops->device,
|
||||||
if (key->format->vk_format == VK_FORMAT_R8_UINT)
|
key->sample_count, key->format, &pipeline->vk_render_pass)) < 0)
|
||||||
{
|
return hresult_from_vk_result(vr);
|
||||||
/* Special path when copying stencil -> color. */
|
|
||||||
vk_module = meta_copy_image_ops->vk_fs_uint_module;
|
|
||||||
}
|
|
||||||
else if (key->dst_aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT)
|
|
||||||
{
|
|
||||||
/* FragStencilRef path. */
|
|
||||||
vk_module = meta_copy_image_ops->vk_fs_stencil_module;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Depth or float color path. */
|
|
||||||
vk_module = meta_copy_image_ops->vk_fs_float_module;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((vr = vkd3d_meta_create_graphics_pipeline(meta_ops,
|
if ((vr = vkd3d_meta_create_graphics_pipeline(meta_ops,
|
||||||
meta_copy_image_ops->vk_pipeline_layout,
|
meta_copy_image_ops->vk_pipeline_layout, pipeline->vk_render_pass,
|
||||||
has_depth_target ? VK_FORMAT_UNDEFINED : key->format->vk_format,
|
VK_NULL_HANDLE, meta_copy_image_ops->vk_fs_module, key->sample_count,
|
||||||
has_depth_target ? key->format->vk_format : VK_FORMAT_UNDEFINED,
|
|
||||||
key->format->vk_aspect_mask,
|
|
||||||
VK_NULL_HANDLE, vk_module, key->sample_count,
|
|
||||||
has_depth_target ? &ds_state : NULL, has_depth_target ? NULL : &cb_state,
|
has_depth_target ? &ds_state : NULL, has_depth_target ? NULL : &cb_state,
|
||||||
&spec_info, &pipeline->vk_pipeline)) < 0)
|
&spec_info, &pipeline->vk_pipeline)) < 0)
|
||||||
|
{
|
||||||
|
VK_CALL(vkDestroyRenderPass(meta_ops->device->vk_device, pipeline->vk_render_pass, NULL));
|
||||||
return hresult_from_vk_result(vr);
|
return hresult_from_vk_result(vr);
|
||||||
|
}
|
||||||
|
|
||||||
pipeline->key = *key;
|
pipeline->key = *key;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
@ -765,6 +826,7 @@ HRESULT vkd3d_meta_get_copy_image_pipeline(struct vkd3d_meta_ops *meta_ops,
|
||||||
|
|
||||||
if (!memcmp(key, &pipeline->key, sizeof(*key)))
|
if (!memcmp(key, &pipeline->key, sizeof(*key)))
|
||||||
{
|
{
|
||||||
|
info->vk_render_pass = pipeline->vk_render_pass;
|
||||||
info->vk_pipeline = pipeline->vk_pipeline;
|
info->vk_pipeline = pipeline->vk_pipeline;
|
||||||
pthread_mutex_unlock(&meta_copy_image_ops->mutex);
|
pthread_mutex_unlock(&meta_copy_image_ops->mutex);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
@ -786,6 +848,7 @@ HRESULT vkd3d_meta_get_copy_image_pipeline(struct vkd3d_meta_ops *meta_ops,
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
info->vk_render_pass = pipeline->vk_render_pass;
|
||||||
info->vk_pipeline = pipeline->vk_pipeline;
|
info->vk_pipeline = pipeline->vk_pipeline;
|
||||||
|
|
||||||
pthread_mutex_unlock(&meta_copy_image_ops->mutex);
|
pthread_mutex_unlock(&meta_copy_image_ops->mutex);
|
||||||
|
@ -807,32 +870,23 @@ VkImageViewType vkd3d_meta_get_copy_image_view_type(D3D12_RESOURCE_DIMENSION dim
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct vkd3d_format *vkd3d_meta_get_copy_image_attachment_format(struct vkd3d_meta_ops *meta_ops,
|
const struct vkd3d_format *vkd3d_meta_get_copy_image_attachment_format(struct vkd3d_meta_ops *meta_ops,
|
||||||
const struct vkd3d_format *dst_format, const struct vkd3d_format *src_format,
|
const struct vkd3d_format *dst_format, const struct vkd3d_format *src_format)
|
||||||
VkImageAspectFlags dst_aspect, VkImageAspectFlags src_aspect)
|
|
||||||
{
|
{
|
||||||
DXGI_FORMAT dxgi_format = DXGI_FORMAT_UNKNOWN;
|
DXGI_FORMAT dxgi_format = DXGI_FORMAT_UNKNOWN;
|
||||||
|
|
||||||
if (dst_aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))
|
if (dst_format->vk_aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT)
|
||||||
return dst_format;
|
return dst_format;
|
||||||
|
|
||||||
assert(src_aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT));
|
assert(src_format->vk_aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT);
|
||||||
|
|
||||||
switch (src_format->vk_format)
|
switch (src_format->vk_format)
|
||||||
{
|
{
|
||||||
case VK_FORMAT_D16_UNORM:
|
case VK_FORMAT_D16_UNORM:
|
||||||
dxgi_format = DXGI_FORMAT_R16_UNORM;
|
dxgi_format = DXGI_FORMAT_R16_UNORM;
|
||||||
break;
|
break;
|
||||||
case VK_FORMAT_D16_UNORM_S8_UINT:
|
|
||||||
dxgi_format = (src_aspect & VK_IMAGE_ASPECT_DEPTH_BIT) ?
|
|
||||||
DXGI_FORMAT_R16_UNORM : DXGI_FORMAT_R8_UINT;
|
|
||||||
break;
|
|
||||||
case VK_FORMAT_D32_SFLOAT:
|
case VK_FORMAT_D32_SFLOAT:
|
||||||
dxgi_format = DXGI_FORMAT_R32_FLOAT;
|
dxgi_format = DXGI_FORMAT_R32_FLOAT;
|
||||||
break;
|
break;
|
||||||
case VK_FORMAT_D32_SFLOAT_S8_UINT:
|
|
||||||
dxgi_format = (src_aspect & VK_IMAGE_ASPECT_DEPTH_BIT) ?
|
|
||||||
DXGI_FORMAT_R32_FLOAT : DXGI_FORMAT_R8_UINT;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
ERR("Unhandled format %u.\n", src_format->vk_format);
|
ERR("Unhandled format %u.\n", src_format->vk_format);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -946,6 +1000,7 @@ void vkd3d_swapchain_ops_cleanup(struct vkd3d_swapchain_ops *meta_swapchain_ops,
|
||||||
{
|
{
|
||||||
struct vkd3d_swapchain_pipeline *pipeline = &meta_swapchain_ops->pipelines[i];
|
struct vkd3d_swapchain_pipeline *pipeline = &meta_swapchain_ops->pipelines[i];
|
||||||
|
|
||||||
|
VK_CALL(vkDestroyRenderPass(device->vk_device, pipeline->vk_render_pass, NULL));
|
||||||
VK_CALL(vkDestroyPipeline(device->vk_device, pipeline->vk_pipeline, NULL));
|
VK_CALL(vkDestroyPipeline(device->vk_device, pipeline->vk_pipeline, NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -986,6 +1041,7 @@ HRESULT vkd3d_meta_get_swapchain_pipeline(struct vkd3d_meta_ops *meta_ops,
|
||||||
|
|
||||||
if (!memcmp(key, &pipeline->key, sizeof(*key)))
|
if (!memcmp(key, &pipeline->key, sizeof(*key)))
|
||||||
{
|
{
|
||||||
|
info->vk_render_pass = pipeline->vk_render_pass;
|
||||||
info->vk_pipeline = pipeline->vk_pipeline;
|
info->vk_pipeline = pipeline->vk_pipeline;
|
||||||
pthread_mutex_unlock(&meta_swapchain_ops->mutex);
|
pthread_mutex_unlock(&meta_swapchain_ops->mutex);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
@ -1007,6 +1063,7 @@ HRESULT vkd3d_meta_get_swapchain_pipeline(struct vkd3d_meta_ops *meta_ops,
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
info->vk_render_pass = pipeline->vk_render_pass;
|
||||||
info->vk_pipeline = pipeline->vk_pipeline;
|
info->vk_pipeline = pipeline->vk_pipeline;
|
||||||
|
|
||||||
pthread_mutex_unlock(&meta_swapchain_ops->mutex);
|
pthread_mutex_unlock(&meta_swapchain_ops->mutex);
|
||||||
|
@ -1017,66 +1074,17 @@ HRESULT vkd3d_query_ops_init(struct vkd3d_query_ops *meta_query_ops,
|
||||||
struct d3d12_device *device)
|
struct d3d12_device *device)
|
||||||
{
|
{
|
||||||
VkPushConstantRange push_constant_range;
|
VkPushConstantRange push_constant_range;
|
||||||
VkSpecializationInfo spec_info;
|
|
||||||
uint32_t field_count;
|
|
||||||
VkResult vr;
|
VkResult vr;
|
||||||
|
|
||||||
static const VkDescriptorSetLayoutBinding gather_bindings[] =
|
|
||||||
{
|
|
||||||
{ 0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT },
|
|
||||||
{ 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT },
|
|
||||||
{ 2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT },
|
|
||||||
};
|
|
||||||
|
|
||||||
static const VkDescriptorSetLayoutBinding resolve_bindings[] =
|
|
||||||
{
|
|
||||||
{ 0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT },
|
|
||||||
{ 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT },
|
|
||||||
};
|
|
||||||
|
|
||||||
static const VkSpecializationMapEntry spec_map = { 0, 0, sizeof(uint32_t) };
|
|
||||||
|
|
||||||
if ((vr = vkd3d_meta_create_descriptor_set_layout(device,
|
|
||||||
ARRAY_SIZE(gather_bindings), gather_bindings,
|
|
||||||
&meta_query_ops->vk_gather_set_layout)) < 0)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
push_constant_range.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
|
push_constant_range.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
|
||||||
push_constant_range.offset = 0;
|
push_constant_range.offset = 0;
|
||||||
push_constant_range.size = sizeof(struct vkd3d_query_gather_args);
|
push_constant_range.size = sizeof(struct vkd3d_query_op_args);
|
||||||
|
|
||||||
if ((vr = vkd3d_meta_create_pipeline_layout(device, 1, &meta_query_ops->vk_gather_set_layout,
|
if ((vr = vkd3d_meta_create_pipeline_layout(device, 0, NULL, 1, &push_constant_range, &meta_query_ops->vk_pipeline_layout)) < 0)
|
||||||
1, &push_constant_range, &meta_query_ops->vk_gather_pipeline_layout)) < 0)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
spec_info.mapEntryCount = 1;
|
|
||||||
spec_info.pMapEntries = &spec_map;
|
|
||||||
spec_info.dataSize = sizeof(field_count);
|
|
||||||
spec_info.pData = &field_count;
|
|
||||||
|
|
||||||
field_count = 1;
|
|
||||||
if ((vr = vkd3d_meta_create_compute_pipeline(device, sizeof(cs_resolve_query), cs_resolve_query,
|
|
||||||
meta_query_ops->vk_gather_pipeline_layout, &spec_info, &meta_query_ops->vk_gather_occlusion_pipeline)) < 0)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
field_count = 2;
|
|
||||||
if ((vr = vkd3d_meta_create_compute_pipeline(device, sizeof(cs_resolve_query), cs_resolve_query,
|
|
||||||
meta_query_ops->vk_gather_pipeline_layout, &spec_info, &meta_query_ops->vk_gather_so_statistics_pipeline)) < 0)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
push_constant_range.size = sizeof(struct vkd3d_query_resolve_args);
|
|
||||||
|
|
||||||
if ((vr = vkd3d_meta_create_descriptor_set_layout(device,
|
|
||||||
ARRAY_SIZE(resolve_bindings), resolve_bindings,
|
|
||||||
&meta_query_ops->vk_resolve_set_layout)) < 0)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
if ((vr = vkd3d_meta_create_pipeline_layout(device, 1, &meta_query_ops->vk_resolve_set_layout,
|
|
||||||
1, &push_constant_range, &meta_query_ops->vk_resolve_pipeline_layout)) < 0)
|
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if ((vr = vkd3d_meta_create_compute_pipeline(device, sizeof(cs_resolve_binary_queries), cs_resolve_binary_queries,
|
if ((vr = vkd3d_meta_create_compute_pipeline(device, sizeof(cs_resolve_binary_queries), cs_resolve_binary_queries,
|
||||||
meta_query_ops->vk_resolve_pipeline_layout, NULL, &meta_query_ops->vk_resolve_binary_pipeline)) < 0)
|
meta_query_ops->vk_pipeline_layout, NULL, &meta_query_ops->vk_resolve_binary_pipeline)) < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
@ -1091,270 +1099,10 @@ void vkd3d_query_ops_cleanup(struct vkd3d_query_ops *meta_query_ops,
|
||||||
{
|
{
|
||||||
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
||||||
|
|
||||||
VK_CALL(vkDestroyPipeline(device->vk_device, meta_query_ops->vk_gather_occlusion_pipeline, NULL));
|
VK_CALL(vkDestroyPipelineLayout(device->vk_device, meta_query_ops->vk_pipeline_layout, NULL));
|
||||||
VK_CALL(vkDestroyPipeline(device->vk_device, meta_query_ops->vk_gather_so_statistics_pipeline, NULL));
|
|
||||||
|
|
||||||
VK_CALL(vkDestroyPipelineLayout(device->vk_device, meta_query_ops->vk_gather_pipeline_layout, NULL));
|
|
||||||
VK_CALL(vkDestroyDescriptorSetLayout(device->vk_device, meta_query_ops->vk_gather_set_layout, NULL));
|
|
||||||
|
|
||||||
VK_CALL(vkDestroyDescriptorSetLayout(device->vk_device, meta_query_ops->vk_resolve_set_layout, NULL));
|
|
||||||
VK_CALL(vkDestroyPipelineLayout(device->vk_device, meta_query_ops->vk_resolve_pipeline_layout, NULL));
|
|
||||||
VK_CALL(vkDestroyPipeline(device->vk_device, meta_query_ops->vk_resolve_binary_pipeline, NULL));
|
VK_CALL(vkDestroyPipeline(device->vk_device, meta_query_ops->vk_resolve_binary_pipeline, NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool vkd3d_meta_get_query_gather_pipeline(struct vkd3d_meta_ops *meta_ops,
|
|
||||||
D3D12_QUERY_HEAP_TYPE heap_type, struct vkd3d_query_gather_info *info)
|
|
||||||
{
|
|
||||||
const struct vkd3d_query_ops *query_ops = &meta_ops->query;
|
|
||||||
|
|
||||||
info->vk_set_layout = query_ops->vk_gather_set_layout;
|
|
||||||
info->vk_pipeline_layout = query_ops->vk_gather_pipeline_layout;
|
|
||||||
|
|
||||||
switch (heap_type)
|
|
||||||
{
|
|
||||||
case D3D12_QUERY_HEAP_TYPE_OCCLUSION:
|
|
||||||
info->vk_pipeline = query_ops->vk_gather_occlusion_pipeline;
|
|
||||||
return true;
|
|
||||||
case D3D12_QUERY_HEAP_TYPE_SO_STATISTICS:
|
|
||||||
info->vk_pipeline = query_ops->vk_gather_so_statistics_pipeline;
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
ERR("No pipeline for query heap type %u.\n", heap_type);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT vkd3d_predicate_ops_init(struct vkd3d_predicate_ops *meta_predicate_ops,
|
|
||||||
struct d3d12_device *device)
|
|
||||||
{
|
|
||||||
VkPushConstantRange push_constant_range;
|
|
||||||
VkSpecializationInfo spec_info;
|
|
||||||
VkResult vr;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
static const struct spec_data
|
|
||||||
{
|
|
||||||
uint32_t arg_count;
|
|
||||||
VkBool32 arg_indirect;
|
|
||||||
}
|
|
||||||
spec_data[] =
|
|
||||||
{
|
|
||||||
{ 4, VK_FALSE }, /* VKD3D_PREDICATE_OP_DRAW */
|
|
||||||
{ 5, VK_FALSE }, /* VKD3D_PREDICATE_OP_DRAW_INDEXED */
|
|
||||||
{ 1, VK_FALSE }, /* VKD3D_PREDICATE_OP_DRAW_INDIRECT */
|
|
||||||
{ 1, VK_TRUE }, /* VKD3D_PREDICATE_OP_DRAW_INDIRECT_COUNT */
|
|
||||||
{ 3, VK_FALSE }, /* VKD3D_PREDICATE_OP_DISPATCH */
|
|
||||||
{ 3, VK_TRUE }, /* VKD3D_PREDICATE_OP_DISPATCH_INDIRECT */
|
|
||||||
};
|
|
||||||
|
|
||||||
static const VkSpecializationMapEntry spec_map[] =
|
|
||||||
{
|
|
||||||
{ 0, offsetof(struct spec_data, arg_count), sizeof(uint32_t) },
|
|
||||||
{ 1, offsetof(struct spec_data, arg_indirect), sizeof(VkBool32) },
|
|
||||||
};
|
|
||||||
|
|
||||||
memset(meta_predicate_ops, 0, sizeof(*meta_predicate_ops));
|
|
||||||
push_constant_range.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
|
|
||||||
push_constant_range.offset = 0;
|
|
||||||
push_constant_range.size = sizeof(struct vkd3d_predicate_command_args);
|
|
||||||
|
|
||||||
if ((vr = vkd3d_meta_create_pipeline_layout(device, 0, NULL, 1,
|
|
||||||
&push_constant_range, &meta_predicate_ops->vk_command_pipeline_layout)) < 0)
|
|
||||||
return hresult_from_vk_result(vr);
|
|
||||||
|
|
||||||
push_constant_range.size = sizeof(struct vkd3d_predicate_resolve_args);
|
|
||||||
if ((vr = vkd3d_meta_create_pipeline_layout(device, 0, NULL, 1,
|
|
||||||
&push_constant_range, &meta_predicate_ops->vk_resolve_pipeline_layout)) < 0)
|
|
||||||
return hresult_from_vk_result(vr);
|
|
||||||
|
|
||||||
spec_info.mapEntryCount = ARRAY_SIZE(spec_map);
|
|
||||||
spec_info.pMapEntries = spec_map;
|
|
||||||
spec_info.dataSize = sizeof(struct spec_data);
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(spec_data); i++)
|
|
||||||
{
|
|
||||||
spec_info.pData = &spec_data[i];
|
|
||||||
|
|
||||||
if ((vr = vkd3d_meta_create_compute_pipeline(device, sizeof(cs_predicate_command), cs_predicate_command,
|
|
||||||
meta_predicate_ops->vk_command_pipeline_layout, &spec_info, &meta_predicate_ops->vk_command_pipelines[i])) < 0)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
meta_predicate_ops->data_sizes[i] = spec_data[i].arg_count * sizeof(uint32_t);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((vr = vkd3d_meta_create_compute_pipeline(device, sizeof(cs_resolve_predicate), cs_resolve_predicate,
|
|
||||||
meta_predicate_ops->vk_resolve_pipeline_layout, &spec_info, &meta_predicate_ops->vk_resolve_pipeline)) < 0)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
|
|
||||||
fail:
|
|
||||||
vkd3d_predicate_ops_cleanup(meta_predicate_ops, device);
|
|
||||||
return hresult_from_vk_result(vr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void vkd3d_predicate_ops_cleanup(struct vkd3d_predicate_ops *meta_predicate_ops,
|
|
||||||
struct d3d12_device *device)
|
|
||||||
{
|
|
||||||
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
for (i = 0; i < VKD3D_PREDICATE_COMMAND_COUNT; i++)
|
|
||||||
VK_CALL(vkDestroyPipeline(device->vk_device, meta_predicate_ops->vk_command_pipelines[i], NULL));
|
|
||||||
VK_CALL(vkDestroyPipeline(device->vk_device, meta_predicate_ops->vk_resolve_pipeline, NULL));
|
|
||||||
|
|
||||||
VK_CALL(vkDestroyPipelineLayout(device->vk_device, meta_predicate_ops->vk_command_pipeline_layout, NULL));
|
|
||||||
VK_CALL(vkDestroyPipelineLayout(device->vk_device, meta_predicate_ops->vk_resolve_pipeline_layout, NULL));
|
|
||||||
}
|
|
||||||
|
|
||||||
void vkd3d_meta_get_predicate_pipeline(struct vkd3d_meta_ops *meta_ops,
|
|
||||||
enum vkd3d_predicate_command_type command_type, struct vkd3d_predicate_command_info *info)
|
|
||||||
{
|
|
||||||
const struct vkd3d_predicate_ops *predicate_ops = &meta_ops->predicate;
|
|
||||||
|
|
||||||
info->vk_pipeline_layout = predicate_ops->vk_command_pipeline_layout;
|
|
||||||
info->vk_pipeline = predicate_ops->vk_command_pipelines[command_type];
|
|
||||||
info->data_size = predicate_ops->data_sizes[command_type];
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT vkd3d_execute_indirect_ops_init(struct vkd3d_execute_indirect_ops *meta_indirect_ops,
|
|
||||||
struct d3d12_device *device)
|
|
||||||
{
|
|
||||||
VkPushConstantRange push_constant_range;
|
|
||||||
VkResult vr;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
if ((rc = pthread_mutex_init(&meta_indirect_ops->mutex, NULL)))
|
|
||||||
return hresult_from_errno(rc);
|
|
||||||
|
|
||||||
push_constant_range.offset = 0;
|
|
||||||
push_constant_range.size = sizeof(struct vkd3d_execute_indirect_args);
|
|
||||||
push_constant_range.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
|
|
||||||
|
|
||||||
if ((vr = vkd3d_meta_create_pipeline_layout(device, 0, NULL, 1,
|
|
||||||
&push_constant_range, &meta_indirect_ops->vk_pipeline_layout)) < 0)
|
|
||||||
{
|
|
||||||
pthread_mutex_destroy(&meta_indirect_ops->mutex);
|
|
||||||
return hresult_from_vk_result(vr);
|
|
||||||
}
|
|
||||||
|
|
||||||
meta_indirect_ops->pipelines_count = 0;
|
|
||||||
meta_indirect_ops->pipelines_size = 0;
|
|
||||||
meta_indirect_ops->pipelines = NULL;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct vkd3d_meta_execute_indirect_spec_constant_data
|
|
||||||
{
|
|
||||||
struct vkd3d_shader_debug_ring_spec_constants constants;
|
|
||||||
uint32_t workgroup_size_x;
|
|
||||||
};
|
|
||||||
|
|
||||||
HRESULT vkd3d_meta_get_execute_indirect_pipeline(struct vkd3d_meta_ops *meta_ops,
|
|
||||||
uint32_t patch_command_count, struct vkd3d_execute_indirect_info *info)
|
|
||||||
{
|
|
||||||
struct vkd3d_meta_execute_indirect_spec_constant_data execute_indirect_spec_constants;
|
|
||||||
VkSpecializationMapEntry map_entry[VKD3D_SHADER_DEBUG_RING_SPEC_INFO_MAP_ENTRIES + 1];
|
|
||||||
struct vkd3d_execute_indirect_ops *meta_indirect_ops = &meta_ops->execute_indirect;
|
|
||||||
struct vkd3d_shader_debug_ring_spec_info debug_ring_info;
|
|
||||||
|
|
||||||
VkSpecializationInfo spec;
|
|
||||||
HRESULT hr = S_OK;
|
|
||||||
VkResult vr;
|
|
||||||
bool debug;
|
|
||||||
size_t i;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
if ((rc = pthread_mutex_lock(&meta_indirect_ops->mutex)))
|
|
||||||
{
|
|
||||||
ERR("Failed to lock mutex, error %d.\n", rc);
|
|
||||||
return hresult_from_errno(rc);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < meta_indirect_ops->pipelines_count; i++)
|
|
||||||
{
|
|
||||||
if (meta_indirect_ops->pipelines[i].workgroup_size_x == patch_command_count)
|
|
||||||
{
|
|
||||||
info->vk_pipeline_layout = meta_indirect_ops->vk_pipeline_layout;
|
|
||||||
info->vk_pipeline = meta_indirect_ops->pipelines[i].vk_pipeline;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
debug = meta_ops->device->debug_ring.active;
|
|
||||||
|
|
||||||
/* If we have debug ring, we can dump indirect command buffer data to the ring as well.
|
|
||||||
* Vital for debugging broken execute indirect data with templates. */
|
|
||||||
if (debug)
|
|
||||||
{
|
|
||||||
vkd3d_shader_debug_ring_init_spec_constant(meta_ops->device, &debug_ring_info,
|
|
||||||
0 /* Reserve this hash for internal debug streams. */);
|
|
||||||
|
|
||||||
memset(&execute_indirect_spec_constants, 0, sizeof(execute_indirect_spec_constants));
|
|
||||||
execute_indirect_spec_constants.constants = debug_ring_info.constants;
|
|
||||||
execute_indirect_spec_constants.workgroup_size_x = patch_command_count;
|
|
||||||
|
|
||||||
memcpy(map_entry, debug_ring_info.map_entries, sizeof(debug_ring_info.map_entries));
|
|
||||||
map_entry[VKD3D_SHADER_DEBUG_RING_SPEC_INFO_MAP_ENTRIES].constantID = 4;
|
|
||||||
map_entry[VKD3D_SHADER_DEBUG_RING_SPEC_INFO_MAP_ENTRIES].offset =
|
|
||||||
offsetof(struct vkd3d_meta_execute_indirect_spec_constant_data, workgroup_size_x);
|
|
||||||
map_entry[VKD3D_SHADER_DEBUG_RING_SPEC_INFO_MAP_ENTRIES].size = sizeof(patch_command_count);
|
|
||||||
|
|
||||||
spec.pMapEntries = map_entry;
|
|
||||||
spec.pData = &execute_indirect_spec_constants;
|
|
||||||
spec.mapEntryCount = ARRAY_SIZE(map_entry);
|
|
||||||
spec.dataSize = sizeof(execute_indirect_spec_constants);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
map_entry[0].constantID = 0;
|
|
||||||
map_entry[0].offset = 0;
|
|
||||||
map_entry[0].size = sizeof(patch_command_count);
|
|
||||||
|
|
||||||
spec.pMapEntries = map_entry;
|
|
||||||
spec.pData = &patch_command_count;
|
|
||||||
spec.mapEntryCount = 1;
|
|
||||||
spec.dataSize = sizeof(patch_command_count);
|
|
||||||
}
|
|
||||||
|
|
||||||
vkd3d_array_reserve((void**)&meta_indirect_ops->pipelines, &meta_indirect_ops->pipelines_size,
|
|
||||||
meta_indirect_ops->pipelines_count + 1, sizeof(*meta_indirect_ops->pipelines));
|
|
||||||
|
|
||||||
meta_indirect_ops->pipelines[meta_indirect_ops->pipelines_count].workgroup_size_x = patch_command_count;
|
|
||||||
|
|
||||||
vr = vkd3d_meta_create_compute_pipeline(meta_ops->device,
|
|
||||||
debug ? sizeof(cs_execute_indirect_patch_debug_ring) : sizeof(cs_execute_indirect_patch),
|
|
||||||
debug ? cs_execute_indirect_patch_debug_ring : cs_execute_indirect_patch,
|
|
||||||
meta_indirect_ops->vk_pipeline_layout, &spec,
|
|
||||||
&meta_indirect_ops->pipelines[meta_indirect_ops->pipelines_count].vk_pipeline);
|
|
||||||
|
|
||||||
if (vr)
|
|
||||||
{
|
|
||||||
hr = hresult_from_vk_result(vr);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
info->vk_pipeline_layout = meta_indirect_ops->vk_pipeline_layout;
|
|
||||||
info->vk_pipeline = meta_indirect_ops->pipelines[meta_indirect_ops->pipelines_count].vk_pipeline;
|
|
||||||
meta_indirect_ops->pipelines_count++;
|
|
||||||
|
|
||||||
out:
|
|
||||||
pthread_mutex_unlock(&meta_indirect_ops->mutex);
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void vkd3d_execute_indirect_ops_cleanup(struct vkd3d_execute_indirect_ops *meta_indirect_ops,
|
|
||||||
struct d3d12_device *device)
|
|
||||||
{
|
|
||||||
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
for (i = 0; i < meta_indirect_ops->pipelines_count; i++)
|
|
||||||
VK_CALL(vkDestroyPipeline(device->vk_device, meta_indirect_ops->pipelines[i].vk_pipeline, NULL));
|
|
||||||
VK_CALL(vkDestroyPipelineLayout(device->vk_device, meta_indirect_ops->vk_pipeline_layout, NULL));
|
|
||||||
pthread_mutex_destroy(&meta_indirect_ops->mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT vkd3d_meta_ops_init(struct vkd3d_meta_ops *meta_ops, struct d3d12_device *device)
|
HRESULT vkd3d_meta_ops_init(struct vkd3d_meta_ops *meta_ops, struct d3d12_device *device)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
@ -1377,18 +1125,8 @@ HRESULT vkd3d_meta_ops_init(struct vkd3d_meta_ops *meta_ops, struct d3d12_device
|
||||||
if (FAILED(hr = vkd3d_query_ops_init(&meta_ops->query, device)))
|
if (FAILED(hr = vkd3d_query_ops_init(&meta_ops->query, device)))
|
||||||
goto fail_query_ops;
|
goto fail_query_ops;
|
||||||
|
|
||||||
if (FAILED(hr = vkd3d_predicate_ops_init(&meta_ops->predicate, device)))
|
|
||||||
goto fail_predicate_ops;
|
|
||||||
|
|
||||||
if (FAILED(hr = vkd3d_execute_indirect_ops_init(&meta_ops->execute_indirect, device)))
|
|
||||||
goto fail_execute_indirect_ops;
|
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
|
||||||
fail_execute_indirect_ops:
|
|
||||||
vkd3d_predicate_ops_cleanup(&meta_ops->predicate, device);
|
|
||||||
fail_predicate_ops:
|
|
||||||
vkd3d_query_ops_cleanup(&meta_ops->query, device);
|
|
||||||
fail_query_ops:
|
fail_query_ops:
|
||||||
vkd3d_swapchain_ops_cleanup(&meta_ops->swapchain, device);
|
vkd3d_swapchain_ops_cleanup(&meta_ops->swapchain, device);
|
||||||
fail_swapchain_ops:
|
fail_swapchain_ops:
|
||||||
|
@ -1403,8 +1141,6 @@ fail_common:
|
||||||
|
|
||||||
HRESULT vkd3d_meta_ops_cleanup(struct vkd3d_meta_ops *meta_ops, struct d3d12_device *device)
|
HRESULT vkd3d_meta_ops_cleanup(struct vkd3d_meta_ops *meta_ops, struct d3d12_device *device)
|
||||||
{
|
{
|
||||||
vkd3d_execute_indirect_ops_cleanup(&meta_ops->execute_indirect, device);
|
|
||||||
vkd3d_predicate_ops_cleanup(&meta_ops->predicate, device);
|
|
||||||
vkd3d_query_ops_cleanup(&meta_ops->query, device);
|
vkd3d_query_ops_cleanup(&meta_ops->query, device);
|
||||||
vkd3d_swapchain_ops_cleanup(&meta_ops->swapchain, device);
|
vkd3d_swapchain_ops_cleanup(&meta_ops->swapchain, device);
|
||||||
vkd3d_copy_image_ops_cleanup(&meta_ops->copy_image, device);
|
vkd3d_copy_image_ops_cleanup(&meta_ops->copy_image, device);
|
||||||
|
|
|
@ -18,9 +18,6 @@
|
||||||
|
|
||||||
#include "vkd3d_platform.h"
|
#include "vkd3d_platform.h"
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
|
|
||||||
# include <dlfcn.h>
|
# include <dlfcn.h>
|
||||||
|
@ -156,43 +153,3 @@ bool vkd3d_get_program_name(char program_name[VKD3D_PATH_MAX])
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_WIN32)
|
|
||||||
|
|
||||||
bool vkd3d_get_env_var(const char *name, char *value, size_t value_size)
|
|
||||||
{
|
|
||||||
DWORD len;
|
|
||||||
|
|
||||||
assert(value);
|
|
||||||
assert(value_size > 0);
|
|
||||||
|
|
||||||
len = GetEnvironmentVariableA(name, value, value_size);
|
|
||||||
if (len > 0 && len <= value_size)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
value[0] = '\0';
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
bool vkd3d_get_env_var(const char *name, char *value, size_t value_size)
|
|
||||||
{
|
|
||||||
const char *env_value;
|
|
||||||
|
|
||||||
assert(value);
|
|
||||||
assert(value_size > 0);
|
|
||||||
|
|
||||||
if ((env_value = getenv(name)))
|
|
||||||
{
|
|
||||||
snprintf(value, value_size, "%s", env_value);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
value[0] = '\0';
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
File diff suppressed because it is too large
Load Diff
|
@ -42,7 +42,6 @@ static vkd3d_shader_hash_t renderdoc_capture_shader_hash;
|
||||||
static uint32_t *renderdoc_capture_counts;
|
static uint32_t *renderdoc_capture_counts;
|
||||||
static size_t renderdoc_capture_counts_count;
|
static size_t renderdoc_capture_counts_count;
|
||||||
static bool vkd3d_renderdoc_is_active;
|
static bool vkd3d_renderdoc_is_active;
|
||||||
static bool vkd3d_renderdoc_global_capture;
|
|
||||||
|
|
||||||
static void vkd3d_renderdoc_init_capture_count_list(const char *env)
|
static void vkd3d_renderdoc_init_capture_count_list(const char *env)
|
||||||
{
|
{
|
||||||
|
@ -50,13 +49,6 @@ static void vkd3d_renderdoc_init_capture_count_list(const char *env)
|
||||||
uint32_t count;
|
uint32_t count;
|
||||||
char *endp;
|
char *endp;
|
||||||
|
|
||||||
if (strcmp(env, "-1") == 0)
|
|
||||||
{
|
|
||||||
INFO("Doing one big capture of the entire lifetime of a device.\n");
|
|
||||||
vkd3d_renderdoc_global_capture = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (*env != '\0')
|
while (*env != '\0')
|
||||||
{
|
{
|
||||||
errno = 0;
|
errno = 0;
|
||||||
|
@ -100,9 +92,9 @@ static bool vkd3d_renderdoc_enable_submit_counter(uint32_t counter)
|
||||||
|
|
||||||
static void vkd3d_renderdoc_init_once(void)
|
static void vkd3d_renderdoc_init_once(void)
|
||||||
{
|
{
|
||||||
char counts[VKD3D_PATH_MAX];
|
|
||||||
pRENDERDOC_GetAPI get_api;
|
pRENDERDOC_GetAPI get_api;
|
||||||
char env[VKD3D_PATH_MAX];
|
const char *counts;
|
||||||
|
const char *env;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
HMODULE renderdoc;
|
HMODULE renderdoc;
|
||||||
|
@ -112,19 +104,19 @@ static void vkd3d_renderdoc_init_once(void)
|
||||||
void *fn_ptr;
|
void *fn_ptr;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
vkd3d_get_env_var("VKD3D_AUTO_CAPTURE_SHADER", env, sizeof(env));
|
env = getenv("VKD3D_AUTO_CAPTURE_SHADER");
|
||||||
vkd3d_get_env_var("VKD3D_AUTO_CAPTURE_COUNTS", counts, sizeof(counts));
|
counts = getenv("VKD3D_AUTO_CAPTURE_COUNTS");
|
||||||
|
|
||||||
if (strlen(env) == 0 && strlen(counts) == 0)
|
if (!env && !counts)
|
||||||
{
|
{
|
||||||
WARN("VKD3D_AUTO_CAPTURE_SHADER or VKD3D_AUTO_CAPTURE_COUNTS is not set, RenderDoc auto capture will not be enabled.\n");
|
WARN("VKD3D_AUTO_CAPTURE_SHADER or VKD3D_AUTO_CAPTURE_COUNTS is not set, RenderDoc auto capture will not be enabled.\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strlen(counts) == 0)
|
if (!counts)
|
||||||
WARN("VKD3D_AUTO_CAPTURE_COUNTS is not set, will assume that only the first submission is captured.\n");
|
WARN("VKD3D_AUTO_CAPTURE_COUNTS is not set, will assume that only the first submission is captured.\n");
|
||||||
|
|
||||||
if (strlen(env) > 0)
|
if (env)
|
||||||
renderdoc_capture_shader_hash = strtoull(env, NULL, 16);
|
renderdoc_capture_shader_hash = strtoull(env, NULL, 16);
|
||||||
|
|
||||||
if (renderdoc_capture_shader_hash)
|
if (renderdoc_capture_shader_hash)
|
||||||
|
@ -132,7 +124,7 @@ static void vkd3d_renderdoc_init_once(void)
|
||||||
else
|
else
|
||||||
INFO("Enabling RenderDoc capture for all shaders.\n");
|
INFO("Enabling RenderDoc capture for all shaders.\n");
|
||||||
|
|
||||||
if (strlen(counts) > 0)
|
if (counts)
|
||||||
vkd3d_renderdoc_init_capture_count_list(counts);
|
vkd3d_renderdoc_init_capture_count_list(counts);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -188,11 +180,6 @@ bool vkd3d_renderdoc_active(void)
|
||||||
return vkd3d_renderdoc_is_active;
|
return vkd3d_renderdoc_is_active;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool vkd3d_renderdoc_global_capture_enabled(void)
|
|
||||||
{
|
|
||||||
return vkd3d_renderdoc_global_capture;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool vkd3d_renderdoc_should_capture_shader_hash(vkd3d_shader_hash_t hash)
|
bool vkd3d_renderdoc_should_capture_shader_hash(vkd3d_shader_hash_t hash)
|
||||||
{
|
{
|
||||||
return (renderdoc_capture_shader_hash == hash) || (renderdoc_capture_shader_hash == 0);
|
return (renderdoc_capture_shader_hash == hash) || (renderdoc_capture_shader_hash == 0);
|
||||||
|
@ -203,12 +190,9 @@ bool vkd3d_renderdoc_begin_capture(void *instance)
|
||||||
static uint32_t overall_counter;
|
static uint32_t overall_counter;
|
||||||
uint32_t counter;
|
uint32_t counter;
|
||||||
|
|
||||||
if (!vkd3d_renderdoc_global_capture)
|
|
||||||
{
|
|
||||||
counter = vkd3d_atomic_uint32_increment(&overall_counter, vkd3d_memory_order_relaxed) - 1;
|
counter = vkd3d_atomic_uint32_increment(&overall_counter, vkd3d_memory_order_relaxed) - 1;
|
||||||
if (!vkd3d_renderdoc_enable_submit_counter(counter))
|
if (!vkd3d_renderdoc_enable_submit_counter(counter))
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
if (renderdoc_api)
|
if (renderdoc_api)
|
||||||
renderdoc_api->StartFrameCapture(RENDERDOC_DEVICEPOINTER_FROM_VKINSTANCE(instance), NULL);
|
renderdoc_api->StartFrameCapture(RENDERDOC_DEVICEPOINTER_FROM_VKINSTANCE(instance), NULL);
|
||||||
|
@ -231,14 +215,11 @@ void vkd3d_renderdoc_command_list_check_capture(struct d3d12_command_list *list,
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
if (vkd3d_renderdoc_global_capture_enabled())
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (vkd3d_renderdoc_active() && state)
|
if (vkd3d_renderdoc_active() && state)
|
||||||
{
|
{
|
||||||
if (state->vk_bind_point == VK_PIPELINE_BIND_POINT_COMPUTE)
|
if (state->vk_bind_point == VK_PIPELINE_BIND_POINT_COMPUTE)
|
||||||
{
|
{
|
||||||
if (vkd3d_renderdoc_should_capture_shader_hash(state->compute.code.meta.hash))
|
if (vkd3d_renderdoc_should_capture_shader_hash(state->compute.meta.hash))
|
||||||
{
|
{
|
||||||
WARN("Triggering RenderDoc capture for this command list.\n");
|
WARN("Triggering RenderDoc capture for this command list.\n");
|
||||||
list->debug_capture = true;
|
list->debug_capture = true;
|
||||||
|
@ -248,7 +229,7 @@ void vkd3d_renderdoc_command_list_check_capture(struct d3d12_command_list *list,
|
||||||
{
|
{
|
||||||
for (i = 0; i < state->graphics.stage_count; i++)
|
for (i = 0; i < state->graphics.stage_count; i++)
|
||||||
{
|
{
|
||||||
if (vkd3d_renderdoc_should_capture_shader_hash(state->graphics.code[i].meta.hash))
|
if (vkd3d_renderdoc_should_capture_shader_hash(state->graphics.stage_meta[i].hash))
|
||||||
{
|
{
|
||||||
WARN("Triggering RenderDoc capture for this command list.\n");
|
WARN("Triggering RenderDoc capture for this command list.\n");
|
||||||
list->debug_capture = true;
|
list->debug_capture = true;
|
||||||
|
@ -265,9 +246,6 @@ bool vkd3d_renderdoc_command_queue_begin_capture(struct d3d12_command_queue *com
|
||||||
VkDebugUtilsLabelEXT capture_label;
|
VkDebugUtilsLabelEXT capture_label;
|
||||||
bool debug_capture;
|
bool debug_capture;
|
||||||
|
|
||||||
if (vkd3d_renderdoc_global_capture_enabled())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
debug_capture = vkd3d_renderdoc_begin_capture(command_queue->device->vkd3d_instance->vk_instance);
|
debug_capture = vkd3d_renderdoc_begin_capture(command_queue->device->vkd3d_instance->vk_instance);
|
||||||
if (debug_capture && !vkd3d_renderdoc_loaded_api())
|
if (debug_capture && !vkd3d_renderdoc_loaded_api())
|
||||||
{
|
{
|
||||||
|
@ -295,9 +273,6 @@ void vkd3d_renderdoc_command_queue_end_capture(struct d3d12_command_queue *comma
|
||||||
const struct vkd3d_vk_device_procs *vk_procs = &command_queue->device->vk_procs;
|
const struct vkd3d_vk_device_procs *vk_procs = &command_queue->device->vk_procs;
|
||||||
VkDebugUtilsLabelEXT capture_label;
|
VkDebugUtilsLabelEXT capture_label;
|
||||||
|
|
||||||
if (vkd3d_renderdoc_global_capture_enabled())
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!vkd3d_renderdoc_loaded_api())
|
if (!vkd3d_renderdoc_loaded_api())
|
||||||
{
|
{
|
||||||
/* Magic fallback which lets us bridge the Wine barrier over to Linux RenderDoc. */
|
/* Magic fallback which lets us bridge the Wine barrier over to Linux RenderDoc. */
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,67 +0,0 @@
|
||||||
#version 450
|
|
||||||
#extension GL_EXT_buffer_reference : require
|
|
||||||
#extension GL_EXT_buffer_reference_uvec2 : require
|
|
||||||
|
|
||||||
layout(local_size_x_id = 0) in;
|
|
||||||
|
|
||||||
struct Command
|
|
||||||
{
|
|
||||||
uint type;
|
|
||||||
uint src_offset;
|
|
||||||
uint dst_offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
layout(buffer_reference, std430, buffer_reference_align = 4) readonly buffer Commands
|
|
||||||
{
|
|
||||||
Command commands[];
|
|
||||||
};
|
|
||||||
|
|
||||||
layout(buffer_reference, std430, buffer_reference_align = 4) readonly buffer SrcBuffer {
|
|
||||||
uint values[];
|
|
||||||
};
|
|
||||||
|
|
||||||
layout(buffer_reference, std430, buffer_reference_align = 4) writeonly buffer DstBuffer {
|
|
||||||
uint values[];
|
|
||||||
};
|
|
||||||
|
|
||||||
layout(buffer_reference, std430, buffer_reference_align = 4) readonly buffer IndirectCount {
|
|
||||||
uint count;
|
|
||||||
};
|
|
||||||
|
|
||||||
layout(buffer_reference, std430, buffer_reference_align = 4) writeonly buffer IndirectCountWrite {
|
|
||||||
uint count;
|
|
||||||
};
|
|
||||||
|
|
||||||
layout(push_constant) uniform Registers
|
|
||||||
{
|
|
||||||
Commands commands_va;
|
|
||||||
SrcBuffer src_buffer_va;
|
|
||||||
DstBuffer dst_buffer_va;
|
|
||||||
uvec2 indirect_count_va;
|
|
||||||
IndirectCountWrite dst_indirect_count_va;
|
|
||||||
uint src_stride;
|
|
||||||
uint dst_stride;
|
|
||||||
};
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
Command cmd = commands_va.commands[gl_LocalInvocationIndex];
|
|
||||||
|
|
||||||
uint draw_id = gl_WorkGroupID.x;
|
|
||||||
uint max_draws = gl_NumWorkGroups.x;
|
|
||||||
|
|
||||||
if (any(notEqual(indirect_count_va, uvec2(0))))
|
|
||||||
{
|
|
||||||
max_draws = min(max_draws, IndirectCount(indirect_count_va).count);
|
|
||||||
if (gl_WorkGroupID.x == 0u)
|
|
||||||
dst_indirect_count_va.count = max_draws;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (draw_id < max_draws)
|
|
||||||
{
|
|
||||||
uint src_offset = src_stride * draw_id + cmd.src_offset;
|
|
||||||
uint dst_offset = dst_stride * draw_id + cmd.dst_offset;
|
|
||||||
uint src_value = src_buffer_va.values[src_offset];
|
|
||||||
dst_buffer_va.values[dst_offset] = src_value;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,83 +0,0 @@
|
||||||
#version 450
|
|
||||||
#extension GL_EXT_buffer_reference : require
|
|
||||||
#extension GL_EXT_buffer_reference_uvec2 : require
|
|
||||||
#extension GL_GOOGLE_include_directive : require
|
|
||||||
#include "../../../include/shader-debug/debug_channel.h"
|
|
||||||
|
|
||||||
layout(local_size_x_id = 4) in;
|
|
||||||
|
|
||||||
struct Command
|
|
||||||
{
|
|
||||||
uint type;
|
|
||||||
uint src_offset;
|
|
||||||
uint dst_offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
layout(buffer_reference, std430, buffer_reference_align = 4) readonly buffer Commands
|
|
||||||
{
|
|
||||||
Command commands[];
|
|
||||||
};
|
|
||||||
|
|
||||||
layout(buffer_reference, std430, buffer_reference_align = 4) readonly buffer SrcBuffer {
|
|
||||||
uint values[];
|
|
||||||
};
|
|
||||||
|
|
||||||
layout(buffer_reference, std430, buffer_reference_align = 4) writeonly buffer DstBuffer {
|
|
||||||
uint values[];
|
|
||||||
};
|
|
||||||
|
|
||||||
layout(buffer_reference, std430, buffer_reference_align = 4) readonly buffer IndirectCount {
|
|
||||||
uint count;
|
|
||||||
};
|
|
||||||
|
|
||||||
layout(buffer_reference, std430, buffer_reference_align = 4) writeonly buffer IndirectCountWrite {
|
|
||||||
uint count;
|
|
||||||
};
|
|
||||||
|
|
||||||
layout(push_constant) uniform Registers
|
|
||||||
{
|
|
||||||
Commands commands_va;
|
|
||||||
SrcBuffer src_buffer_va;
|
|
||||||
DstBuffer dst_buffer_va;
|
|
||||||
uvec2 indirect_count_va;
|
|
||||||
IndirectCountWrite dst_indirect_count_va;
|
|
||||||
uint src_stride;
|
|
||||||
uint dst_stride;
|
|
||||||
|
|
||||||
// Debug metadata here
|
|
||||||
uint debug_tag;
|
|
||||||
uint implicit_instance;
|
|
||||||
};
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
if (debug_tag != 0u)
|
|
||||||
DEBUG_CHANNEL_INIT_IMPLICIT_INSTANCE(uvec3(debug_tag, gl_WorkGroupID.x, gl_LocalInvocationIndex), implicit_instance);
|
|
||||||
|
|
||||||
Command cmd = commands_va.commands[gl_LocalInvocationIndex];
|
|
||||||
|
|
||||||
uint draw_id = gl_WorkGroupID.x;
|
|
||||||
uint max_draws = gl_NumWorkGroups.x;
|
|
||||||
if (any(notEqual(indirect_count_va, uvec2(0))))
|
|
||||||
{
|
|
||||||
max_draws = min(max_draws, IndirectCount(indirect_count_va).count);
|
|
||||||
if (gl_WorkGroupID.x == 0u)
|
|
||||||
dst_indirect_count_va.count = max_draws;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (debug_tag != 0u && gl_WorkGroupID.x == 0)
|
|
||||||
DEBUG_CHANNEL_MSG_UNIFORM(int(max_draws), int(gl_NumWorkGroups.x));
|
|
||||||
|
|
||||||
if (draw_id < max_draws)
|
|
||||||
{
|
|
||||||
uint src_offset = src_stride * draw_id + cmd.src_offset;
|
|
||||||
uint dst_offset = dst_stride * draw_id + cmd.dst_offset;
|
|
||||||
|
|
||||||
uint src_value = src_buffer_va.values[src_offset];
|
|
||||||
|
|
||||||
if (debug_tag != 0u)
|
|
||||||
DEBUG_CHANNEL_MSG(cmd.type, dst_offset, src_offset, src_value);
|
|
||||||
|
|
||||||
dst_buffer_va.values[dst_offset] = src_value;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,40 +0,0 @@
|
||||||
#version 450
|
|
||||||
|
|
||||||
#extension GL_EXT_buffer_reference : require
|
|
||||||
|
|
||||||
layout(local_size_x = 1) in;
|
|
||||||
|
|
||||||
layout(constant_id = 0) const uint c_arg_count = 0;
|
|
||||||
layout(constant_id = 1) const bool c_arg_indirect = false;
|
|
||||||
|
|
||||||
layout(std430, buffer_reference, buffer_reference_align = 4)
|
|
||||||
readonly buffer predicate_t {
|
|
||||||
uint data;
|
|
||||||
};
|
|
||||||
|
|
||||||
layout(std430, buffer_reference, buffer_reference_align = 4)
|
|
||||||
readonly buffer src_args_t {
|
|
||||||
uint data[];
|
|
||||||
};
|
|
||||||
|
|
||||||
layout(std430, buffer_reference, buffer_reference_align = 4)
|
|
||||||
writeonly buffer dst_args_t {
|
|
||||||
uint data[];
|
|
||||||
};
|
|
||||||
|
|
||||||
layout(push_constant)
|
|
||||||
uniform u_info_t {
|
|
||||||
predicate_t predicate;
|
|
||||||
src_args_t src_args;
|
|
||||||
dst_args_t dst_args;
|
|
||||||
uint cmd_args[5];
|
|
||||||
};
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
bool do_exec = predicate.data != 0;
|
|
||||||
|
|
||||||
for (uint i = 0; i < c_arg_count; i++) {
|
|
||||||
uint arg = c_arg_indirect ? src_args.data[i] : cmd_args[i];
|
|
||||||
dst_args.data[i] = do_exec ? arg : 0u;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,29 +1,30 @@
|
||||||
#version 450
|
#version 450
|
||||||
|
|
||||||
#extension GL_ARB_gpu_shader_int64 : require
|
#extension GL_EXT_buffer_reference : require
|
||||||
|
|
||||||
layout(local_size_x = 64) in;
|
layout(local_size_x = 64) in;
|
||||||
|
|
||||||
layout(std430, binding = 0)
|
layout(buffer_reference, std430, buffer_reference_align = 8)
|
||||||
writeonly buffer dst_buffer_t {
|
buffer query_buffer_t {
|
||||||
uint64_t dst_queries[];
|
uvec2 data[];
|
||||||
};
|
|
||||||
|
|
||||||
layout(std430, binding = 1)
|
|
||||||
readonly buffer src_buffer_t {
|
|
||||||
uint64_t src_queries[];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
layout(push_constant)
|
layout(push_constant)
|
||||||
uniform u_info_t {
|
uniform u_info_t {
|
||||||
uint dst_index;
|
query_buffer_t src_queries;
|
||||||
uint src_index;
|
query_buffer_t dst_queries;
|
||||||
uint query_count;
|
uint query_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
uint thread_id = gl_GlobalInvocationID.x;
|
uint thread_id = gl_GlobalInvocationID.x;
|
||||||
|
|
||||||
if (thread_id < query_count)
|
if (thread_id < query_count) {
|
||||||
dst_queries[dst_index + thread_id] = min(src_queries[src_index + thread_id], uint64_t(1u));
|
uvec2 query_data = src_queries.data[thread_id];
|
||||||
|
|
||||||
|
if (any(greaterThan(query_data, uvec2(1, 0))))
|
||||||
|
query_data = uvec2(1, 0);
|
||||||
|
|
||||||
|
dst_queries.data[thread_id] = query_data;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
#version 450
|
|
||||||
|
|
||||||
#extension GL_EXT_buffer_reference : require
|
|
||||||
|
|
||||||
layout(local_size_x = 1) in;
|
|
||||||
|
|
||||||
layout(std430, buffer_reference, buffer_reference_align = 8)
|
|
||||||
readonly buffer src_predicate_t {
|
|
||||||
uvec2 data;
|
|
||||||
};
|
|
||||||
|
|
||||||
layout(std430, buffer_reference, buffer_reference_align = 4)
|
|
||||||
writeonly buffer dst_predicate_t {
|
|
||||||
uint data;
|
|
||||||
};
|
|
||||||
|
|
||||||
layout(push_constant)
|
|
||||||
uniform u_info_t {
|
|
||||||
src_predicate_t src;
|
|
||||||
dst_predicate_t dst;
|
|
||||||
bool invert;
|
|
||||||
};
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
dst.data = (all(equal(src.data, 0u.xx)) != invert) ? 0u : 1u;
|
|
||||||
}
|
|
|
@ -1,62 +0,0 @@
|
||||||
#version 450
|
|
||||||
|
|
||||||
#extension GL_ARB_gpu_shader_int64 : require
|
|
||||||
|
|
||||||
layout(local_size_x = 64) in;
|
|
||||||
|
|
||||||
layout(constant_id = 0) const uint c_field_count = 1;
|
|
||||||
|
|
||||||
layout(std430, binding = 0)
|
|
||||||
buffer dst_queries_t {
|
|
||||||
uint64_t dst_queries[];
|
|
||||||
};
|
|
||||||
|
|
||||||
layout(std430, binding = 1)
|
|
||||||
readonly buffer src_queries_t {
|
|
||||||
uint64_t src_queries[];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct query_map_entry_t {
|
|
||||||
uint dst_index;
|
|
||||||
uint src_index;
|
|
||||||
uint next;
|
|
||||||
};
|
|
||||||
|
|
||||||
layout(std430, binding = 2)
|
|
||||||
readonly buffer query_map_t {
|
|
||||||
query_map_entry_t entries[];
|
|
||||||
} map;
|
|
||||||
|
|
||||||
layout(push_constant)
|
|
||||||
uniform u_info_t {
|
|
||||||
uint query_count;
|
|
||||||
uint entry_offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
uint thread_id = gl_GlobalInvocationID.x;
|
|
||||||
|
|
||||||
if (thread_id >= query_count)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// The query map is an array of linked lists, with the
|
|
||||||
// first query_count entries guaranteed to be list heads
|
|
||||||
query_map_entry_t entry = map.entries[thread_id + entry_offset];
|
|
||||||
uint64_t dst_data[c_field_count];
|
|
||||||
|
|
||||||
// By copying the first query we get the reset for free
|
|
||||||
for (uint i = 0; i < c_field_count; i++)
|
|
||||||
dst_data[i] = src_queries[c_field_count * entry.src_index + i];
|
|
||||||
|
|
||||||
// Accumulate data from additional queries
|
|
||||||
while (entry.next != ~0u) {
|
|
||||||
entry = map.entries[entry.next + entry_offset];
|
|
||||||
|
|
||||||
for (uint i = 0; i < c_field_count; i++)
|
|
||||||
dst_data[i] += src_queries[c_field_count * entry.src_index + i];
|
|
||||||
}
|
|
||||||
|
|
||||||
// dst_index has the same value for all entries in the list
|
|
||||||
for (uint i = 0; i < c_field_count; i++)
|
|
||||||
dst_queries[c_field_count * entry.dst_index + i] = dst_data[i];
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
#version 450
|
|
||||||
|
|
||||||
#extension GL_EXT_samplerless_texture_functions : enable
|
|
||||||
#extension GL_ARB_shader_stencil_export : enable
|
|
||||||
|
|
||||||
#define MODE_1D 0
|
|
||||||
#define MODE_2D 1
|
|
||||||
#define MODE_MS 2
|
|
||||||
|
|
||||||
layout(constant_id = 0) const uint c_mode = MODE_2D;
|
|
||||||
|
|
||||||
layout(binding = 0) uniform utexture1DArray tex_1d;
|
|
||||||
layout(binding = 0) uniform utexture2DArray tex_2d;
|
|
||||||
layout(binding = 0) uniform utexture2DMSArray tex_ms;
|
|
||||||
|
|
||||||
layout(push_constant)
|
|
||||||
uniform u_info_t {
|
|
||||||
ivec2 offset;
|
|
||||||
} u_info;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
ivec3 coord = ivec3(u_info.offset + ivec2(gl_FragCoord.xy), gl_Layer);
|
|
||||||
uint value;
|
|
||||||
if (c_mode == MODE_1D) value = texelFetch(tex_1d, coord.xz, 0).r;
|
|
||||||
if (c_mode == MODE_2D) value = texelFetch(tex_2d, coord, 0).r;
|
|
||||||
if (c_mode == MODE_MS) value = texelFetch(tex_ms, coord, gl_SampleID).r;
|
|
||||||
gl_FragStencilRefARB = int(value);
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
#version 450
|
|
||||||
|
|
||||||
#extension GL_EXT_samplerless_texture_functions : enable
|
|
||||||
|
|
||||||
#define MODE_1D 0
|
|
||||||
#define MODE_2D 1
|
|
||||||
#define MODE_MS 2
|
|
||||||
|
|
||||||
layout(constant_id = 0) const uint c_mode = MODE_2D;
|
|
||||||
|
|
||||||
layout(binding = 0) uniform utexture1DArray tex_1d;
|
|
||||||
layout(binding = 0) uniform utexture2DArray tex_2d;
|
|
||||||
layout(binding = 0) uniform utexture2DMSArray tex_ms;
|
|
||||||
|
|
||||||
layout(location = 0) out uint o_color;
|
|
||||||
|
|
||||||
layout(push_constant)
|
|
||||||
uniform u_info_t {
|
|
||||||
ivec2 offset;
|
|
||||||
} u_info;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
ivec3 coord = ivec3(u_info.offset + ivec2(gl_FragCoord.xy), gl_Layer);
|
|
||||||
uint value;
|
|
||||||
if (c_mode == MODE_1D) value = texelFetch(tex_1d, coord.xz, 0).r;
|
|
||||||
if (c_mode == MODE_2D) value = texelFetch(tex_2d, coord, 0).r;
|
|
||||||
if (c_mode == MODE_MS) value = texelFetch(tex_ms, coord, gl_SampleID).r;
|
|
||||||
o_color = value;
|
|
||||||
}
|
|
|
@ -1,68 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2021 Derek Lesho for Codeweavers
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define VKD3D_DBG_CHANNEL VKD3D_DBG_CHANNEL_API
|
|
||||||
#include "vkd3d_private.h"
|
|
||||||
|
|
||||||
#include "winioctl.h"
|
|
||||||
|
|
||||||
#define IOCTL_SHARED_GPU_RESOURCE_SET_METADATA CTL_CODE(FILE_DEVICE_VIDEO, 4, METHOD_BUFFERED, FILE_WRITE_ACCESS)
|
|
||||||
#define IOCTL_SHARED_GPU_RESOURCE_GET_METADATA CTL_CODE(FILE_DEVICE_VIDEO, 5, METHOD_BUFFERED, FILE_READ_ACCESS)
|
|
||||||
#define IOCTL_SHARED_GPU_RESOURCE_OPEN CTL_CODE(FILE_DEVICE_VIDEO, 1, METHOD_BUFFERED, FILE_WRITE_ACCESS)
|
|
||||||
|
|
||||||
bool vkd3d_set_shared_metadata(HANDLE handle, void *buf, uint32_t buf_size)
|
|
||||||
{
|
|
||||||
DWORD ret_size;
|
|
||||||
|
|
||||||
return DeviceIoControl(handle, IOCTL_SHARED_GPU_RESOURCE_SET_METADATA, buf, buf_size, NULL, 0, &ret_size, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool vkd3d_get_shared_metadata(HANDLE handle, void *buf, uint32_t buf_size, uint32_t *metadata_size)
|
|
||||||
{
|
|
||||||
DWORD ret_size;
|
|
||||||
|
|
||||||
bool ret = DeviceIoControl(handle, IOCTL_SHARED_GPU_RESOURCE_GET_METADATA, NULL, 0, buf, buf_size, &ret_size, NULL);
|
|
||||||
|
|
||||||
if (metadata_size)
|
|
||||||
*metadata_size = ret_size;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
HANDLE vkd3d_open_kmt_handle(HANDLE kmt_handle)
|
|
||||||
{
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
unsigned int kmt_handle;
|
|
||||||
/* the following parameter represents a larger sized string for a dynamically allocated struct for use when opening an object by name */
|
|
||||||
WCHAR name[1];
|
|
||||||
} shared_resource_open;
|
|
||||||
|
|
||||||
HANDLE nt_handle = CreateFileA("\\\\.\\SharedGpuResource", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
||||||
if (nt_handle == INVALID_HANDLE_VALUE)
|
|
||||||
return nt_handle;
|
|
||||||
|
|
||||||
shared_resource_open.kmt_handle = (ULONG_PTR)kmt_handle;
|
|
||||||
shared_resource_open.name[0] = 0;
|
|
||||||
if (!DeviceIoControl(nt_handle, IOCTL_SHARED_GPU_RESOURCE_OPEN, &shared_resource_open, sizeof(shared_resource_open), NULL, 0, NULL, NULL))
|
|
||||||
{
|
|
||||||
CloseHandle(nt_handle);
|
|
||||||
return INVALID_HANDLE_VALUE;
|
|
||||||
}
|
|
||||||
return nt_handle;
|
|
||||||
}
|
|
2624
libs/vkd3d/state.c
2624
libs/vkd3d/state.c
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -22,8 +22,6 @@
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#define VKD3D_MAX_DXGI_FORMAT DXGI_FORMAT_B4G4R4A4_UNORM
|
|
||||||
|
|
||||||
#define COLOR (VK_IMAGE_ASPECT_COLOR_BIT)
|
#define COLOR (VK_IMAGE_ASPECT_COLOR_BIT)
|
||||||
#define DEPTH (VK_IMAGE_ASPECT_DEPTH_BIT)
|
#define DEPTH (VK_IMAGE_ASPECT_DEPTH_BIT)
|
||||||
#define STENCIL (VK_IMAGE_ASPECT_STENCIL_BIT)
|
#define STENCIL (VK_IMAGE_ASPECT_STENCIL_BIT)
|
||||||
|
@ -97,8 +95,6 @@ static const struct vkd3d_format vkd3d_formats[] =
|
||||||
{DXGI_FORMAT_B8G8R8X8_TYPELESS, VK_FORMAT_B8G8R8A8_UNORM, 4, 1, 1, 1, COLOR, 1},
|
{DXGI_FORMAT_B8G8R8X8_TYPELESS, VK_FORMAT_B8G8R8A8_UNORM, 4, 1, 1, 1, COLOR, 1},
|
||||||
{DXGI_FORMAT_B8G8R8X8_UNORM_SRGB, VK_FORMAT_B8G8R8A8_SRGB, 4, 1, 1, 1, COLOR, 1},
|
{DXGI_FORMAT_B8G8R8X8_UNORM_SRGB, VK_FORMAT_B8G8R8A8_SRGB, 4, 1, 1, 1, COLOR, 1},
|
||||||
{DXGI_FORMAT_R9G9B9E5_SHAREDEXP, VK_FORMAT_E5B9G9R9_UFLOAT_PACK32, 4, 1, 1, 1, COLOR, 1},
|
{DXGI_FORMAT_R9G9B9E5_SHAREDEXP, VK_FORMAT_E5B9G9R9_UFLOAT_PACK32, 4, 1, 1, 1, COLOR, 1},
|
||||||
{DXGI_FORMAT_B5G6R5_UNORM, VK_FORMAT_R5G6B5_UNORM_PACK16, 2, 1, 1, 1, COLOR, 1},
|
|
||||||
{DXGI_FORMAT_B5G5R5A1_UNORM, VK_FORMAT_A1R5G5B5_UNORM_PACK16, 2, 1, 1, 1, COLOR, 1},
|
|
||||||
{DXGI_FORMAT_BC1_TYPELESS, VK_FORMAT_BC1_RGBA_UNORM_BLOCK, 1, 4, 4, 8, COLOR, 1, TYPELESS},
|
{DXGI_FORMAT_BC1_TYPELESS, VK_FORMAT_BC1_RGBA_UNORM_BLOCK, 1, 4, 4, 8, COLOR, 1, TYPELESS},
|
||||||
{DXGI_FORMAT_BC1_UNORM, VK_FORMAT_BC1_RGBA_UNORM_BLOCK, 1, 4, 4, 8, COLOR, 1},
|
{DXGI_FORMAT_BC1_UNORM, VK_FORMAT_BC1_RGBA_UNORM_BLOCK, 1, 4, 4, 8, COLOR, 1},
|
||||||
{DXGI_FORMAT_BC1_UNORM_SRGB, VK_FORMAT_BC1_RGBA_SRGB_BLOCK, 1, 4, 4, 8, COLOR, 1},
|
{DXGI_FORMAT_BC1_UNORM_SRGB, VK_FORMAT_BC1_RGBA_SRGB_BLOCK, 1, 4, 4, 8, COLOR, 1},
|
||||||
|
@ -120,26 +116,19 @@ static const struct vkd3d_format vkd3d_formats[] =
|
||||||
{DXGI_FORMAT_BC7_TYPELESS, VK_FORMAT_BC7_UNORM_BLOCK, 1, 4, 4, 16, COLOR, 1, TYPELESS},
|
{DXGI_FORMAT_BC7_TYPELESS, VK_FORMAT_BC7_UNORM_BLOCK, 1, 4, 4, 16, COLOR, 1, TYPELESS},
|
||||||
{DXGI_FORMAT_BC7_UNORM, VK_FORMAT_BC7_UNORM_BLOCK, 1, 4, 4, 16, COLOR, 1},
|
{DXGI_FORMAT_BC7_UNORM, VK_FORMAT_BC7_UNORM_BLOCK, 1, 4, 4, 16, COLOR, 1},
|
||||||
{DXGI_FORMAT_BC7_UNORM_SRGB, VK_FORMAT_BC7_SRGB_BLOCK, 1, 4, 4, 16, COLOR, 1},
|
{DXGI_FORMAT_BC7_UNORM_SRGB, VK_FORMAT_BC7_SRGB_BLOCK, 1, 4, 4, 16, COLOR, 1},
|
||||||
{DXGI_FORMAT_B4G4R4A4_UNORM, VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT,2, 1, 1, 1, COLOR, 1},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct vkd3d_format_footprint depth_stencil_copy_footprints[] =
|
|
||||||
{
|
|
||||||
{ DXGI_FORMAT_R32_TYPELESS, 1, 1, 4, 0, 0 },
|
|
||||||
{ DXGI_FORMAT_R8_TYPELESS, 1, 1, 1, 0, 0 },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Each depth/stencil format is only compatible with itself in Vulkan. */
|
/* Each depth/stencil format is only compatible with itself in Vulkan. */
|
||||||
static const struct vkd3d_format vkd3d_depth_stencil_formats[] =
|
static const struct vkd3d_format vkd3d_depth_stencil_formats[] =
|
||||||
{
|
{
|
||||||
{DXGI_FORMAT_R32G8X24_TYPELESS, VK_FORMAT_D32_SFLOAT_S8_UINT, 8, 1, 1, 1, DEPTH_STENCIL, 2, TYPELESS, false, depth_stencil_copy_footprints},
|
{DXGI_FORMAT_R32G8X24_TYPELESS, VK_FORMAT_D32_SFLOAT_S8_UINT, 8, 1, 1, 1, DEPTH_STENCIL, 2, TYPELESS},
|
||||||
{DXGI_FORMAT_D32_FLOAT_S8X24_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT, 8, 1, 1, 1, DEPTH_STENCIL, 2, 0, false, depth_stencil_copy_footprints},
|
{DXGI_FORMAT_D32_FLOAT_S8X24_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT, 8, 1, 1, 1, DEPTH_STENCIL, 2},
|
||||||
{DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, VK_FORMAT_D32_SFLOAT_S8_UINT, 8, 1, 1, 1, DEPTH, 2},
|
{DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, VK_FORMAT_D32_SFLOAT_S8_UINT, 8, 1, 1, 1, DEPTH, 2},
|
||||||
{DXGI_FORMAT_X32_TYPELESS_G8X24_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT, 8, 1, 1, 1, STENCIL, 2},
|
{DXGI_FORMAT_X32_TYPELESS_G8X24_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT, 8, 1, 1, 1, STENCIL, 2},
|
||||||
{DXGI_FORMAT_R32_TYPELESS, VK_FORMAT_D32_SFLOAT, 4, 1, 1, 1, DEPTH, 1, TYPELESS},
|
{DXGI_FORMAT_R32_TYPELESS, VK_FORMAT_D32_SFLOAT, 4, 1, 1, 1, DEPTH, 1, TYPELESS},
|
||||||
{DXGI_FORMAT_R32_FLOAT, VK_FORMAT_D32_SFLOAT, 4, 1, 1, 1, DEPTH, 1},
|
{DXGI_FORMAT_R32_FLOAT, VK_FORMAT_D32_SFLOAT, 4, 1, 1, 1, DEPTH, 1},
|
||||||
{DXGI_FORMAT_R24G8_TYPELESS, VK_FORMAT_D24_UNORM_S8_UINT, 4, 1, 1, 1, DEPTH_STENCIL, 2, TYPELESS, false, depth_stencil_copy_footprints},
|
{DXGI_FORMAT_R24G8_TYPELESS, VK_FORMAT_D24_UNORM_S8_UINT, 4, 1, 1, 1, DEPTH_STENCIL, 2, TYPELESS},
|
||||||
{DXGI_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT, 4, 1, 1, 1, DEPTH_STENCIL, 2, 0, false, depth_stencil_copy_footprints},
|
{DXGI_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT, 4, 1, 1, 1, DEPTH_STENCIL, 2},
|
||||||
{DXGI_FORMAT_R24_UNORM_X8_TYPELESS, VK_FORMAT_D24_UNORM_S8_UINT, 4, 1, 1, 1, DEPTH, 2},
|
{DXGI_FORMAT_R24_UNORM_X8_TYPELESS, VK_FORMAT_D24_UNORM_S8_UINT, 4, 1, 1, 1, DEPTH, 2},
|
||||||
{DXGI_FORMAT_X24_TYPELESS_G8_UINT, VK_FORMAT_D24_UNORM_S8_UINT, 4, 1, 1, 1, STENCIL, 2},
|
{DXGI_FORMAT_X24_TYPELESS_G8_UINT, VK_FORMAT_D24_UNORM_S8_UINT, 4, 1, 1, 1, STENCIL, 2},
|
||||||
{DXGI_FORMAT_R16_TYPELESS, VK_FORMAT_D16_UNORM, 2, 1, 1, 1, DEPTH, 1, TYPELESS},
|
{DXGI_FORMAT_R16_TYPELESS, VK_FORMAT_D16_UNORM, 2, 1, 1, 1, DEPTH, 1, TYPELESS},
|
||||||
|
@ -153,258 +142,133 @@ static const struct vkd3d_format vkd3d_depth_stencil_formats[] =
|
||||||
#undef SINT
|
#undef SINT
|
||||||
#undef UINT
|
#undef UINT
|
||||||
|
|
||||||
static const struct dxgi_format_compatibility_list
|
static const struct vkd3d_format_compatibility_info
|
||||||
{
|
{
|
||||||
DXGI_FORMAT image_format;
|
DXGI_FORMAT format;
|
||||||
DXGI_FORMAT view_formats[VKD3D_MAX_COMPATIBLE_FORMAT_COUNT];
|
DXGI_FORMAT typeless_format;
|
||||||
DXGI_FORMAT uint_format; /* for ClearUAVUint */
|
|
||||||
}
|
}
|
||||||
dxgi_format_compatibility_list[] =
|
vkd3d_format_compatibility_info[] =
|
||||||
{
|
{
|
||||||
{DXGI_FORMAT_R32G32B32A32_TYPELESS,
|
/* DXGI_FORMAT_R32G32B32A32_TYPELESS */
|
||||||
{DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_R32G32B32A32_SINT},
|
{DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_R32G32B32A32_TYPELESS},
|
||||||
DXGI_FORMAT_R32G32B32A32_UINT},
|
{DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_R32G32B32A32_TYPELESS},
|
||||||
{DXGI_FORMAT_R32G32B32A32_FLOAT, {DXGI_FORMAT_UNKNOWN},
|
{DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_TYPELESS},
|
||||||
DXGI_FORMAT_R32G32B32A32_UINT},
|
/* DXGI_FORMAT_R32G32B32_TYPELESS */
|
||||||
{DXGI_FORMAT_R32G32B32A32_UINT,
|
{DXGI_FORMAT_R32G32B32_UINT, DXGI_FORMAT_R32G32B32_TYPELESS},
|
||||||
{DXGI_FORMAT_R32G32B32A32_SINT},
|
{DXGI_FORMAT_R32G32B32_SINT, DXGI_FORMAT_R32G32B32_TYPELESS},
|
||||||
DXGI_FORMAT_R32G32B32A32_UINT},
|
{DXGI_FORMAT_R32G32B32_FLOAT, DXGI_FORMAT_R32G32B32_TYPELESS},
|
||||||
{DXGI_FORMAT_R32G32B32A32_SINT,
|
/* DXGI_FORMAT_R16G16B16A16_TYPELESS */
|
||||||
{DXGI_FORMAT_R32G32B32A32_UINT},
|
{DXGI_FORMAT_R16G16B16A16_UNORM, DXGI_FORMAT_R16G16B16A16_TYPELESS},
|
||||||
DXGI_FORMAT_R32G32B32A32_UINT},
|
{DXGI_FORMAT_R16G16B16A16_SNORM, DXGI_FORMAT_R16G16B16A16_TYPELESS},
|
||||||
|
{DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_R16G16B16A16_TYPELESS},
|
||||||
{DXGI_FORMAT_R32G32B32_TYPELESS,
|
{DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_R16G16B16A16_TYPELESS},
|
||||||
{DXGI_FORMAT_R32G32B32_FLOAT, DXGI_FORMAT_R32G32B32_UINT, DXGI_FORMAT_R32G32B32_SINT},
|
{DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_TYPELESS},
|
||||||
DXGI_FORMAT_R32G32B32_UINT},
|
/* DXGI_FORMAT_R32G32_TYPELESS */
|
||||||
{DXGI_FORMAT_R32G32B32_FLOAT, {DXGI_FORMAT_UNKNOWN},
|
{DXGI_FORMAT_R32G32_UINT, DXGI_FORMAT_R32G32_TYPELESS},
|
||||||
DXGI_FORMAT_R32G32B32_UINT},
|
{DXGI_FORMAT_R32G32_SINT, DXGI_FORMAT_R32G32_TYPELESS},
|
||||||
{DXGI_FORMAT_R32G32B32_UINT,
|
{DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_R32G32_TYPELESS},
|
||||||
{DXGI_FORMAT_R32G32B32_SINT},
|
/* DXGI_FORMAT_R32G8X24_TYPELESS */
|
||||||
DXGI_FORMAT_R32G32B32_UINT},
|
{DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, DXGI_FORMAT_R32G8X24_TYPELESS},
|
||||||
{DXGI_FORMAT_R32G32B32_SINT,
|
{DXGI_FORMAT_X32_TYPELESS_G8X24_UINT, DXGI_FORMAT_R32G8X24_TYPELESS},
|
||||||
{DXGI_FORMAT_R32G32B32_UINT},
|
{DXGI_FORMAT_D32_FLOAT_S8X24_UINT, DXGI_FORMAT_R32G8X24_TYPELESS},
|
||||||
DXGI_FORMAT_R32G32B32_UINT},
|
/* DXGI_FORMAT_R10G10B10A2_TYPELESS */
|
||||||
|
{DXGI_FORMAT_R10G10B10A2_UINT, DXGI_FORMAT_R10G10B10A2_TYPELESS},
|
||||||
{DXGI_FORMAT_R16G16B16A16_TYPELESS,
|
{DXGI_FORMAT_R10G10B10A2_UNORM, DXGI_FORMAT_R10G10B10A2_TYPELESS},
|
||||||
{DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_UNORM, DXGI_FORMAT_R16G16B16A16_SNORM, DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_R16G16B16A16_SINT},
|
/* DXGI_FORMAT_R8G8B8A8_TYPELESS */
|
||||||
DXGI_FORMAT_R16G16B16A16_UINT},
|
{DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R8G8B8A8_TYPELESS},
|
||||||
{DXGI_FORMAT_R16G16B16A16_FLOAT, {DXGI_FORMAT_UNKNOWN},
|
{DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_R8G8B8A8_TYPELESS},
|
||||||
DXGI_FORMAT_R16G16B16A16_UINT},
|
{DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_R8G8B8A8_TYPELESS},
|
||||||
{DXGI_FORMAT_R16G16B16A16_UINT,
|
{DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_R8G8B8A8_TYPELESS},
|
||||||
{DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_R16G16B16A16_UNORM, DXGI_FORMAT_R16G16B16A16_SNORM},
|
{DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_TYPELESS},
|
||||||
DXGI_FORMAT_R16G16B16A16_UINT},
|
/* DXGI_FORMAT_R16G16_TYPELESS */
|
||||||
{DXGI_FORMAT_R16G16B16A16_SINT,
|
{DXGI_FORMAT_R16G16_UNORM, DXGI_FORMAT_R16G16_TYPELESS},
|
||||||
{DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_R16G16B16A16_UNORM, DXGI_FORMAT_R16G16B16A16_SNORM},
|
{DXGI_FORMAT_R16G16_SNORM, DXGI_FORMAT_R16G16_TYPELESS},
|
||||||
DXGI_FORMAT_R16G16B16A16_UINT},
|
{DXGI_FORMAT_R16G16_UINT, DXGI_FORMAT_R16G16_TYPELESS},
|
||||||
{DXGI_FORMAT_R16G16B16A16_UNORM,
|
{DXGI_FORMAT_R16G16_SINT, DXGI_FORMAT_R16G16_TYPELESS},
|
||||||
{DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_R16G16B16A16_SINT},
|
{DXGI_FORMAT_R16G16_FLOAT, DXGI_FORMAT_R16G16_TYPELESS},
|
||||||
DXGI_FORMAT_R16G16B16A16_UINT},
|
/* DXGI_FORMAT_R32_TYPELESS */
|
||||||
{DXGI_FORMAT_R16G16B16A16_SNORM,
|
{DXGI_FORMAT_D32_FLOAT, DXGI_FORMAT_R32_TYPELESS},
|
||||||
{DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_R16G16B16A16_SINT},
|
{DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_TYPELESS},
|
||||||
DXGI_FORMAT_R16G16B16A16_UINT},
|
{DXGI_FORMAT_R32_UINT, DXGI_FORMAT_R32_TYPELESS},
|
||||||
|
{DXGI_FORMAT_R32_SINT, DXGI_FORMAT_R32_TYPELESS},
|
||||||
{DXGI_FORMAT_R32G32_TYPELESS,
|
/* DXGI_FORMAT_R24G8_TYPELESS */
|
||||||
{DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_R32G32_UINT, DXGI_FORMAT_R32G32_SINT},
|
{DXGI_FORMAT_R24_UNORM_X8_TYPELESS, DXGI_FORMAT_R24G8_TYPELESS},
|
||||||
DXGI_FORMAT_R32G32_UINT},
|
{DXGI_FORMAT_X24_TYPELESS_G8_UINT, DXGI_FORMAT_R24G8_TYPELESS},
|
||||||
{DXGI_FORMAT_R32G32_FLOAT, {DXGI_FORMAT_UNKNOWN},
|
{DXGI_FORMAT_D24_UNORM_S8_UINT, DXGI_FORMAT_R24G8_TYPELESS},
|
||||||
DXGI_FORMAT_R32G32_UINT},
|
/* DXGI_FORMAT_R8G8_TYPELESS */
|
||||||
{DXGI_FORMAT_R32G32_UINT,
|
{DXGI_FORMAT_R8G8_SNORM, DXGI_FORMAT_R8G8_TYPELESS},
|
||||||
{DXGI_FORMAT_R32G32_SINT},
|
{DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_R8G8_TYPELESS},
|
||||||
DXGI_FORMAT_R32G32_UINT},
|
{DXGI_FORMAT_R8G8_UINT, DXGI_FORMAT_R8G8_TYPELESS},
|
||||||
{DXGI_FORMAT_R32G32_SINT,
|
{DXGI_FORMAT_R8G8_SINT, DXGI_FORMAT_R8G8_TYPELESS},
|
||||||
{DXGI_FORMAT_R32G32_UINT},
|
/* DXGI_FORMAT_R16_TYPELESS */
|
||||||
DXGI_FORMAT_R32G32_UINT},
|
{DXGI_FORMAT_D16_UNORM, DXGI_FORMAT_R16_TYPELESS},
|
||||||
|
{DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16_TYPELESS},
|
||||||
{DXGI_FORMAT_R10G10B10A2_TYPELESS,
|
{DXGI_FORMAT_R16_SNORM, DXGI_FORMAT_R16_TYPELESS},
|
||||||
{DXGI_FORMAT_R10G10B10A2_UNORM, DXGI_FORMAT_R10G10B10A2_UINT},
|
{DXGI_FORMAT_R16_UINT, DXGI_FORMAT_R16_TYPELESS},
|
||||||
DXGI_FORMAT_R10G10B10A2_UINT},
|
{DXGI_FORMAT_R16_SINT, DXGI_FORMAT_R16_TYPELESS},
|
||||||
{DXGI_FORMAT_R10G10B10A2_UINT,
|
{DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_R16_TYPELESS},
|
||||||
{DXGI_FORMAT_R10G10B10A2_UNORM},
|
/* DXGI_FORMAT_R8_TYPELESS */
|
||||||
DXGI_FORMAT_R10G10B10A2_UINT},
|
{DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_TYPELESS},
|
||||||
{DXGI_FORMAT_R10G10B10A2_UNORM,
|
{DXGI_FORMAT_R8_SNORM, DXGI_FORMAT_R8_TYPELESS},
|
||||||
{DXGI_FORMAT_R10G10B10A2_UINT},
|
{DXGI_FORMAT_R8_UINT, DXGI_FORMAT_R8_TYPELESS},
|
||||||
DXGI_FORMAT_R10G10B10A2_UINT},
|
{DXGI_FORMAT_R8_SINT, DXGI_FORMAT_R8_TYPELESS},
|
||||||
|
/* DXGI_FORMAT_BC1_TYPELESS */
|
||||||
{DXGI_FORMAT_R11G11B10_FLOAT, {DXGI_FORMAT_UNKNOWN},
|
{DXGI_FORMAT_BC1_UNORM_SRGB, DXGI_FORMAT_BC1_TYPELESS},
|
||||||
DXGI_FORMAT_R32_UINT},
|
{DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_TYPELESS},
|
||||||
|
/* DXGI_FORMAT_BC2_TYPELESS */
|
||||||
{DXGI_FORMAT_R8G8_TYPELESS,
|
{DXGI_FORMAT_BC2_UNORM_SRGB, DXGI_FORMAT_BC2_TYPELESS},
|
||||||
{DXGI_FORMAT_R8G8_UINT, DXGI_FORMAT_R8G8_SINT, DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_R8G8_SNORM},
|
{DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_BC2_TYPELESS},
|
||||||
DXGI_FORMAT_R8G8_UINT},
|
/* DXGI_FORMAT_BC3_TYPELESS */
|
||||||
{DXGI_FORMAT_R8G8_UINT,
|
{DXGI_FORMAT_BC3_UNORM_SRGB, DXGI_FORMAT_BC3_TYPELESS},
|
||||||
{DXGI_FORMAT_R8G8_SINT, DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_R8G8_SNORM},
|
{DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_BC3_TYPELESS},
|
||||||
DXGI_FORMAT_R8G8_UINT},
|
/* DXGI_FORMAT_BC4_TYPELESS */
|
||||||
{DXGI_FORMAT_R8G8_SINT,
|
{DXGI_FORMAT_BC4_UNORM, DXGI_FORMAT_BC4_TYPELESS},
|
||||||
{DXGI_FORMAT_R8G8_UINT, DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_R8G8_SNORM},
|
{DXGI_FORMAT_BC4_SNORM, DXGI_FORMAT_BC4_TYPELESS},
|
||||||
DXGI_FORMAT_R8G8_UINT},
|
/* DXGI_FORMAT_BC5_TYPELESS */
|
||||||
{DXGI_FORMAT_R8G8_UNORM,
|
{DXGI_FORMAT_BC5_UNORM, DXGI_FORMAT_BC5_TYPELESS},
|
||||||
{DXGI_FORMAT_R8G8_UINT, DXGI_FORMAT_R8G8_SINT},
|
{DXGI_FORMAT_BC5_SNORM, DXGI_FORMAT_BC5_TYPELESS},
|
||||||
DXGI_FORMAT_R8G8_UINT},
|
/* DXGI_FORMAT_BC6H_TYPELESS */
|
||||||
{DXGI_FORMAT_R8G8_SNORM,
|
{DXGI_FORMAT_BC6H_UF16, DXGI_FORMAT_BC6H_TYPELESS},
|
||||||
{DXGI_FORMAT_R8G8_UINT, DXGI_FORMAT_R8G8_SINT},
|
{DXGI_FORMAT_BC6H_SF16, DXGI_FORMAT_BC6H_TYPELESS},
|
||||||
DXGI_FORMAT_R8G8_UINT},
|
/* DXGI_FORMAT_BC7_TYPELESS */
|
||||||
|
{DXGI_FORMAT_BC7_UNORM_SRGB, DXGI_FORMAT_BC7_TYPELESS},
|
||||||
{DXGI_FORMAT_R8G8B8A8_TYPELESS,
|
{DXGI_FORMAT_BC7_UNORM, DXGI_FORMAT_BC7_TYPELESS},
|
||||||
{DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_R8G8B8A8_SNORM},
|
/* DXGI_FORMAT_B8G8R8A8_TYPELESS */
|
||||||
DXGI_FORMAT_R8G8B8A8_UINT},
|
{DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, DXGI_FORMAT_B8G8R8A8_TYPELESS},
|
||||||
{DXGI_FORMAT_R8G8B8A8_UINT,
|
{DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_TYPELESS},
|
||||||
{DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_R8G8B8A8_SNORM},
|
/* DXGI_FORMAT_B8G8R8X8_TYPELESS */
|
||||||
DXGI_FORMAT_R8G8B8A8_UINT},
|
{DXGI_FORMAT_B8G8R8X8_UNORM_SRGB, DXGI_FORMAT_B8G8R8X8_TYPELESS},
|
||||||
{DXGI_FORMAT_R8G8B8A8_SINT,
|
{DXGI_FORMAT_B8G8R8X8_UNORM, DXGI_FORMAT_B8G8R8X8_TYPELESS},
|
||||||
{DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_R8G8B8A8_SNORM},
|
|
||||||
DXGI_FORMAT_R8G8B8A8_UINT},
|
|
||||||
{DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
|
|
||||||
{DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_R8G8B8A8_UNORM},
|
|
||||||
DXGI_FORMAT_R8G8B8A8_UINT},
|
|
||||||
{DXGI_FORMAT_R8G8B8A8_UNORM,
|
|
||||||
{DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB},
|
|
||||||
DXGI_FORMAT_R8G8B8A8_UINT},
|
|
||||||
{DXGI_FORMAT_R8G8B8A8_SNORM,
|
|
||||||
{DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R8G8B8A8_SINT},
|
|
||||||
DXGI_FORMAT_R8G8B8A8_UINT},
|
|
||||||
|
|
||||||
{DXGI_FORMAT_R16G16_TYPELESS,
|
|
||||||
{DXGI_FORMAT_R16G16_FLOAT, DXGI_FORMAT_R16G16_UINT, DXGI_FORMAT_R16G16_SINT, DXGI_FORMAT_R16G16_UNORM, DXGI_FORMAT_R16G16_SNORM},
|
|
||||||
DXGI_FORMAT_R16G16_UINT},
|
|
||||||
{DXGI_FORMAT_R16G16_FLOAT, {DXGI_FORMAT_UNKNOWN},
|
|
||||||
DXGI_FORMAT_R16G16_UINT},
|
|
||||||
{DXGI_FORMAT_R16G16_UINT,
|
|
||||||
{DXGI_FORMAT_R16G16_SINT, DXGI_FORMAT_R16G16_UNORM, DXGI_FORMAT_R16G16_SNORM},
|
|
||||||
DXGI_FORMAT_R16G16_UINT},
|
|
||||||
{DXGI_FORMAT_R16G16_SINT,
|
|
||||||
{DXGI_FORMAT_R16G16_UINT, DXGI_FORMAT_R16G16_UNORM, DXGI_FORMAT_R16G16_SNORM},
|
|
||||||
DXGI_FORMAT_R16G16_UINT},
|
|
||||||
{DXGI_FORMAT_R16G16_UNORM,
|
|
||||||
{DXGI_FORMAT_R16G16_UINT, DXGI_FORMAT_R16G16_SINT},
|
|
||||||
DXGI_FORMAT_R16G16_UINT},
|
|
||||||
{DXGI_FORMAT_R16G16_SNORM,
|
|
||||||
{DXGI_FORMAT_R16G16_UINT, DXGI_FORMAT_R16G16_SINT},
|
|
||||||
DXGI_FORMAT_R16G16_UINT},
|
|
||||||
|
|
||||||
{DXGI_FORMAT_R32_TYPELESS,
|
|
||||||
{DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_UINT, DXGI_FORMAT_R32_SINT},
|
|
||||||
DXGI_FORMAT_R32_UINT},
|
|
||||||
{DXGI_FORMAT_R32_FLOAT, {DXGI_FORMAT_UNKNOWN},
|
|
||||||
DXGI_FORMAT_R32_UINT},
|
|
||||||
{DXGI_FORMAT_R32_UINT,
|
|
||||||
{DXGI_FORMAT_R32_SINT},
|
|
||||||
DXGI_FORMAT_R32_UINT},
|
|
||||||
{DXGI_FORMAT_R32_SINT,
|
|
||||||
{DXGI_FORMAT_R32_UINT},
|
|
||||||
DXGI_FORMAT_R32_UINT},
|
|
||||||
|
|
||||||
{DXGI_FORMAT_R16_TYPELESS,
|
|
||||||
{DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_R16_UINT, DXGI_FORMAT_R16_SINT, DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16_SNORM},
|
|
||||||
DXGI_FORMAT_R16_UINT},
|
|
||||||
{DXGI_FORMAT_R16_FLOAT, {DXGI_FORMAT_UNKNOWN},
|
|
||||||
DXGI_FORMAT_R16_UINT},
|
|
||||||
{DXGI_FORMAT_R16_UINT,
|
|
||||||
{DXGI_FORMAT_R16_SINT, DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16_SNORM},
|
|
||||||
DXGI_FORMAT_R16_UINT},
|
|
||||||
{DXGI_FORMAT_R16_SINT,
|
|
||||||
{DXGI_FORMAT_R16_UINT, DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16_SNORM},
|
|
||||||
DXGI_FORMAT_R16_UINT},
|
|
||||||
{DXGI_FORMAT_R16_UNORM,
|
|
||||||
{DXGI_FORMAT_R16_UINT, DXGI_FORMAT_R16_SINT},
|
|
||||||
DXGI_FORMAT_R16_UINT},
|
|
||||||
{DXGI_FORMAT_R16_SNORM,
|
|
||||||
{DXGI_FORMAT_R16_UINT, DXGI_FORMAT_R16_SINT},
|
|
||||||
DXGI_FORMAT_R16_UINT},
|
|
||||||
|
|
||||||
{DXGI_FORMAT_R8_TYPELESS,
|
|
||||||
{DXGI_FORMAT_R8_UINT, DXGI_FORMAT_R8_SINT, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_SNORM, DXGI_FORMAT_A8_UNORM},
|
|
||||||
DXGI_FORMAT_R8_UINT},
|
|
||||||
{DXGI_FORMAT_R8_UINT,
|
|
||||||
{DXGI_FORMAT_R8_SINT, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_SNORM, DXGI_FORMAT_A8_UNORM},
|
|
||||||
DXGI_FORMAT_R8_UINT},
|
|
||||||
{DXGI_FORMAT_R8_SINT,
|
|
||||||
{DXGI_FORMAT_R8_UINT, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_SNORM, DXGI_FORMAT_A8_UNORM},
|
|
||||||
DXGI_FORMAT_R8_UINT},
|
|
||||||
{DXGI_FORMAT_R8_UNORM,
|
|
||||||
{DXGI_FORMAT_R8_UINT, DXGI_FORMAT_R8_SINT, DXGI_FORMAT_A8_UNORM},
|
|
||||||
DXGI_FORMAT_R8_UINT},
|
|
||||||
{DXGI_FORMAT_R8_SNORM,
|
|
||||||
{DXGI_FORMAT_R8_UINT, DXGI_FORMAT_R8_SINT},
|
|
||||||
DXGI_FORMAT_R8_UINT},
|
|
||||||
{DXGI_FORMAT_A8_UNORM,
|
|
||||||
{DXGI_FORMAT_R8_UINT, DXGI_FORMAT_R8_SINT, DXGI_FORMAT_R8_UNORM},
|
|
||||||
DXGI_FORMAT_R8_UINT},
|
|
||||||
|
|
||||||
{DXGI_FORMAT_B8G8R8A8_TYPELESS,
|
|
||||||
{DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM_SRGB},
|
|
||||||
DXGI_FORMAT_R8G8B8A8_UINT},
|
|
||||||
{DXGI_FORMAT_B8G8R8A8_UNORM,
|
|
||||||
{DXGI_FORMAT_B8G8R8A8_UNORM_SRGB},
|
|
||||||
DXGI_FORMAT_R8G8B8A8_UINT},
|
|
||||||
{DXGI_FORMAT_B8G8R8A8_UNORM_SRGB,
|
|
||||||
{DXGI_FORMAT_B8G8R8A8_UNORM},
|
|
||||||
DXGI_FORMAT_R8G8B8A8_UINT},
|
|
||||||
|
|
||||||
{DXGI_FORMAT_B8G8R8X8_TYPELESS,
|
|
||||||
{DXGI_FORMAT_B8G8R8X8_UNORM, DXGI_FORMAT_B8G8R8X8_UNORM_SRGB},
|
|
||||||
DXGI_FORMAT_R8G8B8A8_UINT},
|
|
||||||
{DXGI_FORMAT_B8G8R8X8_UNORM,
|
|
||||||
{DXGI_FORMAT_B8G8R8X8_UNORM_SRGB},
|
|
||||||
DXGI_FORMAT_R8G8B8A8_UINT},
|
|
||||||
{DXGI_FORMAT_B8G8R8X8_UNORM_SRGB,
|
|
||||||
{DXGI_FORMAT_B8G8R8X8_UNORM},
|
|
||||||
DXGI_FORMAT_R8G8B8A8_UINT},
|
|
||||||
|
|
||||||
{DXGI_FORMAT_BC1_TYPELESS,
|
|
||||||
{DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM_SRGB}},
|
|
||||||
{DXGI_FORMAT_BC1_UNORM,
|
|
||||||
{DXGI_FORMAT_BC1_UNORM_SRGB}},
|
|
||||||
{DXGI_FORMAT_BC1_UNORM_SRGB,
|
|
||||||
{DXGI_FORMAT_BC1_UNORM}},
|
|
||||||
|
|
||||||
{DXGI_FORMAT_BC2_TYPELESS,
|
|
||||||
{DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_BC2_UNORM_SRGB}},
|
|
||||||
{DXGI_FORMAT_BC2_UNORM,
|
|
||||||
{DXGI_FORMAT_BC2_UNORM_SRGB}},
|
|
||||||
{DXGI_FORMAT_BC2_UNORM_SRGB,
|
|
||||||
{DXGI_FORMAT_BC2_UNORM}},
|
|
||||||
|
|
||||||
{DXGI_FORMAT_BC3_TYPELESS,
|
|
||||||
{DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_BC3_UNORM_SRGB}},
|
|
||||||
{DXGI_FORMAT_BC3_UNORM,
|
|
||||||
{DXGI_FORMAT_BC3_UNORM_SRGB}},
|
|
||||||
{DXGI_FORMAT_BC3_UNORM_SRGB,
|
|
||||||
{DXGI_FORMAT_BC3_UNORM}},
|
|
||||||
|
|
||||||
{DXGI_FORMAT_BC4_TYPELESS,
|
|
||||||
{DXGI_FORMAT_BC4_UNORM, DXGI_FORMAT_BC4_SNORM}},
|
|
||||||
{DXGI_FORMAT_BC5_TYPELESS,
|
|
||||||
{DXGI_FORMAT_BC5_UNORM, DXGI_FORMAT_BC5_SNORM}},
|
|
||||||
{DXGI_FORMAT_BC6H_TYPELESS,
|
|
||||||
{DXGI_FORMAT_BC6H_UF16, DXGI_FORMAT_BC6H_SF16}},
|
|
||||||
|
|
||||||
{DXGI_FORMAT_BC7_TYPELESS,
|
|
||||||
{DXGI_FORMAT_BC7_UNORM, DXGI_FORMAT_BC7_UNORM_SRGB}},
|
|
||||||
{DXGI_FORMAT_BC7_UNORM,
|
|
||||||
{DXGI_FORMAT_BC7_UNORM_SRGB}},
|
|
||||||
{DXGI_FORMAT_BC7_UNORM_SRGB,
|
|
||||||
{DXGI_FORMAT_BC7_UNORM}},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void vkd3d_format_compatibility_list_add_format(struct vkd3d_format_compatibility_list *list, VkFormat vk_format)
|
static bool dxgi_format_is_depth_stencil(DXGI_FORMAT dxgi_format)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
bool found = false;
|
|
||||||
|
|
||||||
for (i = 0; i < list->format_count && !found; i++)
|
for (i = 0; i < ARRAY_SIZE(vkd3d_formats); ++i)
|
||||||
found = list->vk_formats[i] == vk_format;
|
|
||||||
|
|
||||||
if (!found)
|
|
||||||
{
|
{
|
||||||
assert(list->format_count < ARRAY_SIZE(list->vk_formats));
|
const struct vkd3d_format *current = &vkd3d_formats[i];
|
||||||
list->vk_formats[list->format_count++] = vk_format;
|
|
||||||
|
if (current->dxgi_format == dxgi_format)
|
||||||
|
return current->vk_aspect_mask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(vkd3d_depth_stencil_formats); ++i)
|
||||||
|
{
|
||||||
|
if (vkd3d_depth_stencil_formats[i].dxgi_format == dxgi_format)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FIXME: This table should be generated at compile-time. */
|
||||||
static HRESULT vkd3d_init_format_compatibility_lists(struct d3d12_device *device)
|
static HRESULT vkd3d_init_format_compatibility_lists(struct d3d12_device *device)
|
||||||
{
|
{
|
||||||
struct vkd3d_format_compatibility_list *lists, *dst;
|
struct vkd3d_format_compatibility_list *lists, *current_list;
|
||||||
const struct dxgi_format_compatibility_list *src;
|
const struct vkd3d_format_compatibility_info *current;
|
||||||
|
DXGI_FORMAT dxgi_format;
|
||||||
|
VkFormat vk_format;
|
||||||
unsigned int count;
|
unsigned int count;
|
||||||
unsigned int i, j;
|
unsigned int i, j;
|
||||||
|
|
||||||
|
@ -414,25 +278,62 @@ static HRESULT vkd3d_init_format_compatibility_lists(struct d3d12_device *device
|
||||||
if (!device->vk_info.KHR_image_format_list)
|
if (!device->vk_info.KHR_image_format_list)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
|
||||||
count = 0;
|
count = 1;
|
||||||
for (i = 0; i < ARRAY_SIZE(dxgi_format_compatibility_list); ++i)
|
dxgi_format = vkd3d_format_compatibility_info[0].typeless_format;
|
||||||
count = max(count, dxgi_format_compatibility_list[i].image_format + 1);
|
for (i = 0; i < ARRAY_SIZE(vkd3d_format_compatibility_info); ++i)
|
||||||
|
{
|
||||||
|
DXGI_FORMAT typeless_format = vkd3d_format_compatibility_info[i].typeless_format;
|
||||||
|
|
||||||
|
if (dxgi_format != typeless_format)
|
||||||
|
{
|
||||||
|
++count;
|
||||||
|
dxgi_format = typeless_format;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!(lists = vkd3d_calloc(count, sizeof(*lists))))
|
if (!(lists = vkd3d_calloc(count, sizeof(*lists))))
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(dxgi_format_compatibility_list); ++i)
|
count = 0;
|
||||||
|
current_list = lists;
|
||||||
|
current_list->typeless_format = vkd3d_format_compatibility_info[0].typeless_format;
|
||||||
|
for (i = 0; i < ARRAY_SIZE(vkd3d_format_compatibility_info); ++i)
|
||||||
{
|
{
|
||||||
src = &dxgi_format_compatibility_list[i];
|
current = &vkd3d_format_compatibility_info[i];
|
||||||
dst = &lists[src->image_format];
|
|
||||||
|
|
||||||
dst->uint_format = src->uint_format;
|
if (current_list->typeless_format != current->typeless_format)
|
||||||
dst->vk_formats[dst->format_count++] = vkd3d_get_vk_format(src->image_format);
|
{
|
||||||
|
/* Avoid empty format lists. */
|
||||||
for (j = 0; j < ARRAY_SIZE(src->view_formats) && src->view_formats[j]; j++)
|
if (current_list->format_count)
|
||||||
vkd3d_format_compatibility_list_add_format(dst, vkd3d_get_vk_format(src->view_formats[j]));
|
{
|
||||||
|
++current_list;
|
||||||
|
++count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
current_list->typeless_format = current->typeless_format;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* In Vulkan, each depth-stencil format is only compatible with itself. */
|
||||||
|
if (dxgi_format_is_depth_stencil(current->format))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!(vk_format = vkd3d_get_vk_format(current->format)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (j = 0; j < current_list->format_count; ++j)
|
||||||
|
{
|
||||||
|
if (current_list->vk_formats[j] == vk_format)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (j >= current_list->format_count)
|
||||||
|
{
|
||||||
|
assert(current_list->format_count < VKD3D_MAX_COMPATIBLE_FORMAT_COUNT);
|
||||||
|
current_list->vk_formats[current_list->format_count++] = vk_format;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (current_list->format_count)
|
||||||
|
++count;
|
||||||
|
|
||||||
device->format_compatibility_list_count = count;
|
device->format_compatibility_list_count = count;
|
||||||
device->format_compatibility_lists = lists;
|
device->format_compatibility_lists = lists;
|
||||||
|
@ -449,74 +350,51 @@ static void vkd3d_cleanup_format_compatibility_lists(struct d3d12_device *device
|
||||||
|
|
||||||
static HRESULT vkd3d_init_depth_stencil_formats(struct d3d12_device *device)
|
static HRESULT vkd3d_init_depth_stencil_formats(struct d3d12_device *device)
|
||||||
{
|
{
|
||||||
|
const unsigned int count = ARRAY_SIZE(vkd3d_depth_stencil_formats);
|
||||||
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
||||||
struct vkd3d_format *formats, *format;
|
|
||||||
VkFormatProperties properties;
|
VkFormatProperties properties;
|
||||||
|
struct vkd3d_format *formats;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
if (!(formats = vkd3d_calloc(VKD3D_MAX_DXGI_FORMAT + 1, sizeof(*formats))))
|
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
|
|
||||||
VK_CALL(vkGetPhysicalDeviceFormatProperties(device->vk_physical_device,
|
VK_CALL(vkGetPhysicalDeviceFormatProperties(device->vk_physical_device,
|
||||||
VK_FORMAT_D24_UNORM_S8_UINT, &properties));
|
VK_FORMAT_D24_UNORM_S8_UINT, &properties));
|
||||||
|
|
||||||
if (!(properties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))
|
if (properties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)
|
||||||
|
{
|
||||||
|
device->depth_stencil_formats = vkd3d_depth_stencil_formats;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
/* AMD doesn't support VK_FORMAT_D24_UNORM_S8_UINT. */
|
/* AMD doesn't support VK_FORMAT_D24_UNORM_S8_UINT. */
|
||||||
WARN("Mapping VK_FORMAT_D24_UNORM_S8_UINT to VK_FORMAT_D32_SFLOAT_S8_UINT.\n");
|
WARN("Mapping VK_FORMAT_D24_UNORM_S8_UINT to VK_FORMAT_D32_SFLOAT_S8_UINT.\n");
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(vkd3d_depth_stencil_formats); ++i)
|
if (!(formats = vkd3d_calloc(count, sizeof(*formats))))
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
memcpy(formats, vkd3d_depth_stencil_formats, sizeof(vkd3d_depth_stencil_formats));
|
||||||
|
for (i = 0; i < count; ++i)
|
||||||
{
|
{
|
||||||
assert(vkd3d_depth_stencil_formats[i].dxgi_format <= VKD3D_MAX_DXGI_FORMAT);
|
if (formats[i].vk_format == VK_FORMAT_D24_UNORM_S8_UINT)
|
||||||
format = &formats[vkd3d_depth_stencil_formats[i].dxgi_format];
|
|
||||||
*format = vkd3d_depth_stencil_formats[i];
|
|
||||||
if (format->vk_format == VK_FORMAT_D24_UNORM_S8_UINT &&
|
|
||||||
!(properties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))
|
|
||||||
{
|
{
|
||||||
format->vk_format = VK_FORMAT_D32_SFLOAT_S8_UINT;
|
formats[i].vk_format = VK_FORMAT_D32_SFLOAT_S8_UINT;
|
||||||
format->is_emulated = true;
|
formats[i].is_emulated = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
device->depth_stencil_formats = formats;
|
device->depth_stencil_formats = formats;
|
||||||
|
}
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vkd3d_cleanup_depth_stencil_formats(struct d3d12_device *device)
|
static void vkd3d_cleanup_depth_stencil_formats(struct d3d12_device *device)
|
||||||
{
|
{
|
||||||
|
if (vkd3d_depth_stencil_formats != device->depth_stencil_formats)
|
||||||
vkd3d_free((void *)device->depth_stencil_formats);
|
vkd3d_free((void *)device->depth_stencil_formats);
|
||||||
|
|
||||||
device->depth_stencil_formats = NULL;
|
device->depth_stencil_formats = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT vkd3d_init_formats(struct d3d12_device *device)
|
|
||||||
{
|
|
||||||
struct vkd3d_format *formats;
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
if (!(formats = vkd3d_calloc(VKD3D_MAX_DXGI_FORMAT + 1, sizeof(*formats))))
|
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(vkd3d_formats); ++i)
|
|
||||||
{
|
|
||||||
assert(vkd3d_formats[i].dxgi_format <= VKD3D_MAX_DXGI_FORMAT);
|
|
||||||
formats[vkd3d_formats[i].dxgi_format] = vkd3d_formats[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
device->formats = formats;
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void vkd3d_cleanup_formats(struct d3d12_device *device)
|
|
||||||
{
|
|
||||||
vkd3d_free((void *)device->formats);
|
|
||||||
|
|
||||||
device->formats = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT vkd3d_init_format_info(struct d3d12_device *device)
|
HRESULT vkd3d_init_format_info(struct d3d12_device *device)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
@ -524,17 +402,8 @@ HRESULT vkd3d_init_format_info(struct d3d12_device *device)
|
||||||
if (FAILED(hr = vkd3d_init_depth_stencil_formats(device)))
|
if (FAILED(hr = vkd3d_init_depth_stencil_formats(device)))
|
||||||
return hr;
|
return hr;
|
||||||
|
|
||||||
if (FAILED(hr = vkd3d_init_format_compatibility_lists(device)))
|
if FAILED(hr = vkd3d_init_format_compatibility_lists(device))
|
||||||
{
|
|
||||||
vkd3d_cleanup_depth_stencil_formats(device);
|
vkd3d_cleanup_depth_stencil_formats(device);
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FAILED(hr = vkd3d_init_formats(device)))
|
|
||||||
{
|
|
||||||
vkd3d_cleanup_depth_stencil_formats(device);
|
|
||||||
vkd3d_cleanup_format_compatibility_lists(device);
|
|
||||||
}
|
|
||||||
|
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
@ -543,7 +412,6 @@ void vkd3d_cleanup_format_info(struct d3d12_device *device)
|
||||||
{
|
{
|
||||||
vkd3d_cleanup_depth_stencil_formats(device);
|
vkd3d_cleanup_depth_stencil_formats(device);
|
||||||
vkd3d_cleanup_format_compatibility_lists(device);
|
vkd3d_cleanup_format_compatibility_lists(device);
|
||||||
vkd3d_cleanup_formats(device);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We use overrides for depth/stencil formats. This is required in order to
|
/* We use overrides for depth/stencil formats. This is required in order to
|
||||||
|
@ -553,64 +421,79 @@ void vkd3d_cleanup_format_info(struct d3d12_device *device)
|
||||||
static const struct vkd3d_format *vkd3d_get_depth_stencil_format(const struct d3d12_device *device,
|
static const struct vkd3d_format *vkd3d_get_depth_stencil_format(const struct d3d12_device *device,
|
||||||
DXGI_FORMAT dxgi_format)
|
DXGI_FORMAT dxgi_format)
|
||||||
{
|
{
|
||||||
const struct vkd3d_format *format;
|
const struct vkd3d_format *formats;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
assert(device);
|
assert(device);
|
||||||
format = &device->depth_stencil_formats[dxgi_format];
|
formats = device->depth_stencil_formats;
|
||||||
|
|
||||||
return format->dxgi_format ? format : NULL;
|
for (i = 0; i < ARRAY_SIZE(vkd3d_depth_stencil_formats); ++i)
|
||||||
|
{
|
||||||
|
if (formats[i].dxgi_format == dxgi_format)
|
||||||
|
return &formats[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct vkd3d_format *vkd3d_get_format(const struct d3d12_device *device,
|
const struct vkd3d_format *vkd3d_get_format(const struct d3d12_device *device,
|
||||||
DXGI_FORMAT dxgi_format, bool depth_stencil)
|
DXGI_FORMAT dxgi_format, bool depth_stencil)
|
||||||
{
|
{
|
||||||
const struct vkd3d_format *format;
|
const struct vkd3d_format *format;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
if (dxgi_format > VKD3D_MAX_DXGI_FORMAT)
|
if (depth_stencil && (format = vkd3d_get_depth_stencil_format(device, dxgi_format)))
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/* If we request a depth-stencil format (or typeless variant) that is planar,
|
|
||||||
* there cannot be any ambiguity which format to select, we must choose a depth-stencil format.
|
|
||||||
* For single aspect formats,
|
|
||||||
* there are cases where we need to choose either COLOR or DEPTH aspect variants based on depth_stencil argument,
|
|
||||||
* but there cannot be any such issue for DEPTH_STENCIL types.
|
|
||||||
* This fixes issues where e.g. R24_UNORM_X8_TYPELESS format is used without ALLOW_DEPTH_STENCIL. */
|
|
||||||
format = vkd3d_get_depth_stencil_format(device, dxgi_format);
|
|
||||||
if (format && (depth_stencil || format->plane_count > 1))
|
|
||||||
return format;
|
return format;
|
||||||
|
|
||||||
format = &device->formats[dxgi_format];
|
for (i = 0; i < ARRAY_SIZE(vkd3d_formats); ++i)
|
||||||
|
{
|
||||||
|
if (vkd3d_formats[i].dxgi_format == dxgi_format)
|
||||||
|
return &vkd3d_formats[i];
|
||||||
|
}
|
||||||
|
|
||||||
return format->dxgi_format ? format : NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct vkd3d_format_footprint vkd3d_format_footprint_for_plane(const struct vkd3d_format *format, unsigned int plane_idx)
|
DXGI_FORMAT vkd3d_get_typeless_format(const struct d3d12_device *device, DXGI_FORMAT dxgi_format)
|
||||||
{
|
{
|
||||||
if (format->plane_footprints)
|
const struct vkd3d_format *format = vkd3d_get_format(device, dxgi_format, true);
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
if (!format)
|
||||||
|
return DXGI_FORMAT_UNKNOWN;
|
||||||
|
|
||||||
|
if (format->type == VKD3D_FORMAT_TYPE_TYPELESS)
|
||||||
|
return dxgi_format;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(vkd3d_format_compatibility_info); ++i)
|
||||||
{
|
{
|
||||||
return format->plane_footprints[plane_idx];
|
if (vkd3d_format_compatibility_info[i].format == dxgi_format)
|
||||||
}
|
return vkd3d_format_compatibility_info[i].typeless_format;
|
||||||
else
|
|
||||||
{
|
|
||||||
struct vkd3d_format_footprint footprint;
|
|
||||||
footprint.dxgi_format = format->dxgi_format;
|
|
||||||
footprint.block_width = format->block_width;
|
|
||||||
footprint.block_height = format->block_height;
|
|
||||||
footprint.subsample_x_log2 = 0;
|
|
||||||
footprint.subsample_y_log2 = 0;
|
|
||||||
footprint.block_byte_count = format->byte_count * format->block_byte_count;
|
|
||||||
return footprint;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return DXGI_FORMAT_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkFormat vkd3d_internal_get_vk_format(const struct d3d12_device *device, DXGI_FORMAT dxgi_format)
|
const struct vkd3d_format *vkd3d_find_uint_format(const struct d3d12_device *device, DXGI_FORMAT dxgi_format)
|
||||||
{
|
{
|
||||||
const struct vkd3d_format *format;
|
DXGI_FORMAT typeless_format = DXGI_FORMAT_UNKNOWN;
|
||||||
|
const struct vkd3d_format *vkd3d_format;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
if ((format = vkd3d_get_format(device, dxgi_format, false)))
|
if (!(typeless_format = vkd3d_get_typeless_format(device, dxgi_format)))
|
||||||
return format->vk_format;
|
return NULL;
|
||||||
|
|
||||||
return VK_FORMAT_UNDEFINED;
|
for (i = 0; i < ARRAY_SIZE(vkd3d_format_compatibility_info); ++i)
|
||||||
|
{
|
||||||
|
if (vkd3d_format_compatibility_info[i].typeless_format != typeless_format)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
vkd3d_format = vkd3d_get_format(device, vkd3d_format_compatibility_info[i].format, false);
|
||||||
|
if (vkd3d_format->type == VKD3D_FORMAT_TYPE_UINT)
|
||||||
|
return vkd3d_format;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void vkd3d_format_copy_data(const struct vkd3d_format *format, const uint8_t *src,
|
void vkd3d_format_copy_data(const struct vkd3d_format *format, const uint8_t *src,
|
||||||
|
@ -639,15 +522,12 @@ void vkd3d_format_copy_data(const struct vkd3d_format *format, const uint8_t *sr
|
||||||
|
|
||||||
VKD3D_EXPORT VkFormat vkd3d_get_vk_format(DXGI_FORMAT format)
|
VKD3D_EXPORT VkFormat vkd3d_get_vk_format(DXGI_FORMAT format)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
const struct vkd3d_format *vkd3d_format;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(vkd3d_formats); ++i)
|
|
||||||
{
|
|
||||||
if (vkd3d_formats[i].dxgi_format == format)
|
|
||||||
return vkd3d_formats[i].vk_format;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (!(vkd3d_format = vkd3d_get_format(NULL, format, false)))
|
||||||
return VK_FORMAT_UNDEFINED;
|
return VK_FORMAT_UNDEFINED;
|
||||||
|
|
||||||
|
return vkd3d_format->vk_format;
|
||||||
}
|
}
|
||||||
|
|
||||||
VKD3D_EXPORT DXGI_FORMAT vkd3d_get_dxgi_format(VkFormat format)
|
VKD3D_EXPORT DXGI_FORMAT vkd3d_get_dxgi_format(VkFormat format)
|
||||||
|
@ -672,7 +552,6 @@ bool is_valid_feature_level(D3D_FEATURE_LEVEL feature_level)
|
||||||
{
|
{
|
||||||
static const D3D_FEATURE_LEVEL valid_feature_levels[] =
|
static const D3D_FEATURE_LEVEL valid_feature_levels[] =
|
||||||
{
|
{
|
||||||
D3D_FEATURE_LEVEL_12_2,
|
|
||||||
D3D_FEATURE_LEVEL_12_1,
|
D3D_FEATURE_LEVEL_12_1,
|
||||||
D3D_FEATURE_LEVEL_12_0,
|
D3D_FEATURE_LEVEL_12_0,
|
||||||
D3D_FEATURE_LEVEL_11_1,
|
D3D_FEATURE_LEVEL_11_1,
|
||||||
|
@ -724,9 +603,7 @@ bool is_valid_resource_state(D3D12_RESOURCE_STATES state)
|
||||||
D3D12_RESOURCE_STATE_RESOLVE_SOURCE |
|
D3D12_RESOURCE_STATE_RESOLVE_SOURCE |
|
||||||
D3D12_RESOURCE_STATE_GENERIC_READ |
|
D3D12_RESOURCE_STATE_GENERIC_READ |
|
||||||
D3D12_RESOURCE_STATE_PRESENT |
|
D3D12_RESOURCE_STATE_PRESENT |
|
||||||
D3D12_RESOURCE_STATE_PREDICATION |
|
D3D12_RESOURCE_STATE_PREDICATION;
|
||||||
D3D12_RESOURCE_STATE_RAYTRACING_ACCELERATION_STRUCTURE |
|
|
||||||
D3D12_RESOURCE_STATE_SHADING_RATE_SOURCE;
|
|
||||||
|
|
||||||
if (state & ~valid_states)
|
if (state & ~valid_states)
|
||||||
{
|
{
|
||||||
|
@ -884,11 +761,6 @@ const char *debug_dxgi_format(DXGI_FORMAT format)
|
||||||
ENUM_NAME(DXGI_FORMAT_P8)
|
ENUM_NAME(DXGI_FORMAT_P8)
|
||||||
ENUM_NAME(DXGI_FORMAT_A8P8)
|
ENUM_NAME(DXGI_FORMAT_A8P8)
|
||||||
ENUM_NAME(DXGI_FORMAT_B4G4R4A4_UNORM)
|
ENUM_NAME(DXGI_FORMAT_B4G4R4A4_UNORM)
|
||||||
ENUM_NAME(DXGI_FORMAT_P208)
|
|
||||||
ENUM_NAME(DXGI_FORMAT_V208)
|
|
||||||
ENUM_NAME(DXGI_FORMAT_V408)
|
|
||||||
ENUM_NAME(DXGI_FORMAT_SAMPLER_FEEDBACK_MIN_MIP_OPAQUE)
|
|
||||||
ENUM_NAME(DXGI_FORMAT_SAMPLER_FEEDBACK_MIP_REGION_USED_OPAQUE)
|
|
||||||
ENUM_NAME(DXGI_FORMAT_FORCE_UINT)
|
ENUM_NAME(DXGI_FORMAT_FORCE_UINT)
|
||||||
}
|
}
|
||||||
#undef ENUM_NAME
|
#undef ENUM_NAME
|
||||||
|
@ -946,15 +818,16 @@ const char *debug_vk_extent_3d(VkExtent3D extent)
|
||||||
(unsigned int)extent.depth);
|
(unsigned int)extent.depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *debug_vk_queue_flags(VkQueueFlags flags, char buffer[VKD3D_DEBUG_FLAGS_BUFFER_SIZE])
|
const char *debug_vk_queue_flags(VkQueueFlags flags)
|
||||||
{
|
{
|
||||||
|
char buffer[120];
|
||||||
|
|
||||||
buffer[0] = '\0';
|
buffer[0] = '\0';
|
||||||
#define FLAG_TO_STR(f) if (flags & f) { strcat(buffer, " | "#f); flags &= ~f; }
|
#define FLAG_TO_STR(f) if (flags & f) { strcat(buffer, " | "#f); flags &= ~f; }
|
||||||
FLAG_TO_STR(VK_QUEUE_GRAPHICS_BIT)
|
FLAG_TO_STR(VK_QUEUE_GRAPHICS_BIT)
|
||||||
FLAG_TO_STR(VK_QUEUE_COMPUTE_BIT)
|
FLAG_TO_STR(VK_QUEUE_COMPUTE_BIT)
|
||||||
FLAG_TO_STR(VK_QUEUE_TRANSFER_BIT)
|
FLAG_TO_STR(VK_QUEUE_TRANSFER_BIT)
|
||||||
FLAG_TO_STR(VK_QUEUE_SPARSE_BINDING_BIT)
|
FLAG_TO_STR(VK_QUEUE_SPARSE_BINDING_BIT)
|
||||||
FLAG_TO_STR(VK_QUEUE_PROTECTED_BIT)
|
|
||||||
#undef FLAG_TO_STR
|
#undef FLAG_TO_STR
|
||||||
if (flags)
|
if (flags)
|
||||||
FIXME("Unrecognized flag(s) %#x.\n", flags);
|
FIXME("Unrecognized flag(s) %#x.\n", flags);
|
||||||
|
@ -964,12 +837,13 @@ const char *debug_vk_queue_flags(VkQueueFlags flags, char buffer[VKD3D_DEBUG_FLA
|
||||||
return vkd3d_dbg_sprintf("%s", &buffer[3]);
|
return vkd3d_dbg_sprintf("%s", &buffer[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *debug_vk_memory_heap_flags(VkMemoryHeapFlags flags, char buffer[VKD3D_DEBUG_FLAGS_BUFFER_SIZE])
|
const char *debug_vk_memory_heap_flags(VkMemoryHeapFlags flags)
|
||||||
{
|
{
|
||||||
|
char buffer[50];
|
||||||
|
|
||||||
buffer[0] = '\0';
|
buffer[0] = '\0';
|
||||||
#define FLAG_TO_STR(f) if (flags & f) { strcat(buffer, " | "#f); flags &= ~f; }
|
#define FLAG_TO_STR(f) if (flags & f) { strcat(buffer, " | "#f); flags &= ~f; }
|
||||||
FLAG_TO_STR(VK_MEMORY_HEAP_DEVICE_LOCAL_BIT)
|
FLAG_TO_STR(VK_MEMORY_HEAP_DEVICE_LOCAL_BIT)
|
||||||
FLAG_TO_STR(VK_MEMORY_HEAP_MULTI_INSTANCE_BIT)
|
|
||||||
#undef FLAG_TO_STR
|
#undef FLAG_TO_STR
|
||||||
if (flags)
|
if (flags)
|
||||||
FIXME("Unrecognized flag(s) %#x.\n", flags);
|
FIXME("Unrecognized flag(s) %#x.\n", flags);
|
||||||
|
@ -979,8 +853,10 @@ const char *debug_vk_memory_heap_flags(VkMemoryHeapFlags flags, char buffer[VKD3
|
||||||
return vkd3d_dbg_sprintf("%s", &buffer[3]);
|
return vkd3d_dbg_sprintf("%s", &buffer[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *debug_vk_memory_property_flags(VkMemoryPropertyFlags flags, char buffer[VKD3D_DEBUG_FLAGS_BUFFER_SIZE])
|
const char *debug_vk_memory_property_flags(VkMemoryPropertyFlags flags)
|
||||||
{
|
{
|
||||||
|
char buffer[200];
|
||||||
|
|
||||||
buffer[0] = '\0';
|
buffer[0] = '\0';
|
||||||
#define FLAG_TO_STR(f) if (flags & f) { strcat(buffer, " | "#f); flags &= ~f; }
|
#define FLAG_TO_STR(f) if (flags & f) { strcat(buffer, " | "#f); flags &= ~f; }
|
||||||
FLAG_TO_STR(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
|
FLAG_TO_STR(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
|
||||||
|
@ -988,9 +864,6 @@ const char *debug_vk_memory_property_flags(VkMemoryPropertyFlags flags, char buf
|
||||||
FLAG_TO_STR(VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)
|
FLAG_TO_STR(VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)
|
||||||
FLAG_TO_STR(VK_MEMORY_PROPERTY_HOST_CACHED_BIT)
|
FLAG_TO_STR(VK_MEMORY_PROPERTY_HOST_CACHED_BIT)
|
||||||
FLAG_TO_STR(VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT)
|
FLAG_TO_STR(VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT)
|
||||||
FLAG_TO_STR(VK_MEMORY_PROPERTY_PROTECTED_BIT)
|
|
||||||
FLAG_TO_STR(VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD)
|
|
||||||
FLAG_TO_STR(VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD)
|
|
||||||
#undef FLAG_TO_STR
|
#undef FLAG_TO_STR
|
||||||
if (flags)
|
if (flags)
|
||||||
FIXME("Unrecognized flag(s) %#x.\n", flags);
|
FIXME("Unrecognized flag(s) %#x.\n", flags);
|
||||||
|
@ -1018,16 +891,6 @@ HRESULT hresult_from_errno(int rc)
|
||||||
|
|
||||||
HRESULT hresult_from_vk_result(VkResult vr)
|
HRESULT hresult_from_vk_result(VkResult vr)
|
||||||
{
|
{
|
||||||
/* Wine tends to dispatch Vulkan calls to their own syscall stack.
|
|
||||||
* Crashes are captured and return this magic VkResult.
|
|
||||||
* Report it explicitly here so it's easier to debug when it happens. */
|
|
||||||
if (vr == -1073741819)
|
|
||||||
{
|
|
||||||
ERR("Detected segfault in Wine syscall handler.\n");
|
|
||||||
/* HACK: For ad-hoc debugging can also trigger backtrace printing here. */
|
|
||||||
return E_POINTER;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (vr)
|
switch (vr)
|
||||||
{
|
{
|
||||||
case VK_SUCCESS:
|
case VK_SUCCESS:
|
||||||
|
@ -1037,9 +900,6 @@ HRESULT hresult_from_vk_result(VkResult vr)
|
||||||
/* fall-through */
|
/* fall-through */
|
||||||
case VK_ERROR_OUT_OF_HOST_MEMORY:
|
case VK_ERROR_OUT_OF_HOST_MEMORY:
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
case VK_ERROR_VALIDATION_FAILED_EXT:
|
|
||||||
/* NV driver sometimes returns this on invalid API usage. */
|
|
||||||
return E_INVALIDARG;
|
|
||||||
default:
|
default:
|
||||||
FIXME("Unhandled VkResult %d.\n", vr);
|
FIXME("Unhandled VkResult %d.\n", vr);
|
||||||
/* fall-through */
|
/* fall-through */
|
||||||
|
@ -1158,7 +1018,7 @@ static struct vkd3d_private_data *vkd3d_private_store_get_private_data(
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT vkd3d_private_store_set_private_data(struct vkd3d_private_store *store,
|
static HRESULT vkd3d_private_store_set_private_data(struct vkd3d_private_store *store,
|
||||||
const GUID *tag, const void *data, unsigned int data_size, bool is_object)
|
const GUID *tag, const void *data, unsigned int data_size, bool is_object)
|
||||||
{
|
{
|
||||||
struct vkd3d_private_data *d, *old_data;
|
struct vkd3d_private_data *d, *old_data;
|
||||||
|
@ -1203,14 +1063,18 @@ HRESULT vkd3d_get_private_data(struct vkd3d_private_store *store,
|
||||||
const GUID *tag, unsigned int *out_size, void *out)
|
const GUID *tag, unsigned int *out_size, void *out)
|
||||||
{
|
{
|
||||||
const struct vkd3d_private_data *data;
|
const struct vkd3d_private_data *data;
|
||||||
|
HRESULT hr = S_OK;
|
||||||
unsigned int size;
|
unsigned int size;
|
||||||
HRESULT hr;
|
int rc;
|
||||||
|
|
||||||
if (!out_size)
|
if (!out_size)
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
|
|
||||||
if (FAILED(hr = vkd3d_private_data_lock(store)))
|
if ((rc = pthread_mutex_lock(&store->mutex)))
|
||||||
return hr;
|
{
|
||||||
|
ERR("Failed to lock mutex, error %d.\n", rc);
|
||||||
|
return hresult_from_errno(rc);
|
||||||
|
}
|
||||||
|
|
||||||
if (!(data = vkd3d_private_store_get_private_data(store, tag)))
|
if (!(data = vkd3d_private_store_get_private_data(store, tag)))
|
||||||
{
|
{
|
||||||
|
@ -1235,28 +1099,52 @@ HRESULT vkd3d_get_private_data(struct vkd3d_private_store *store,
|
||||||
memcpy(out, data->data, data->size);
|
memcpy(out, data->data, data->size);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
vkd3d_private_data_unlock(store);
|
pthread_mutex_unlock(&store->mutex);
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE d3d12_object_SetName(ID3D12Object *iface, const WCHAR *name)
|
HRESULT vkd3d_set_private_data(struct vkd3d_private_store *store,
|
||||||
|
const GUID *tag, unsigned int data_size, const void *data)
|
||||||
{
|
{
|
||||||
size_t size = 0;
|
HRESULT hr;
|
||||||
|
int rc;
|
||||||
|
|
||||||
TRACE("iface %p, name %s.\n", iface, debugstr_w(name));
|
if ((rc = pthread_mutex_lock(&store->mutex)))
|
||||||
|
{
|
||||||
|
ERR("Failed to lock mutex, error %d.\n", rc);
|
||||||
|
return hresult_from_errno(rc);
|
||||||
|
}
|
||||||
|
|
||||||
if (name)
|
hr = vkd3d_private_store_set_private_data(store, tag, data, data_size, false);
|
||||||
size = sizeof(WCHAR) * (vkd3d_wcslen(name) + 1);
|
|
||||||
|
|
||||||
return ID3D12Object_SetPrivateData(iface, &WKPDID_D3DDebugObjectNameW, size, name);
|
pthread_mutex_unlock(&store->mutex);
|
||||||
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT vkd3d_set_vk_object_name(struct d3d12_device *device, uint64_t vk_object,
|
HRESULT vkd3d_set_private_data_interface(struct vkd3d_private_store *store,
|
||||||
|
const GUID *tag, const IUnknown *object)
|
||||||
|
{
|
||||||
|
const void *data = object ? object : (void *)&object;
|
||||||
|
HRESULT hr;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if ((rc = pthread_mutex_lock(&store->mutex)))
|
||||||
|
{
|
||||||
|
ERR("Failed to lock mutex, error %d.\n", rc);
|
||||||
|
return hresult_from_errno(rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = vkd3d_private_store_set_private_data(store, tag, data, sizeof(object), !!object);
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&store->mutex);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkResult vkd3d_set_vk_object_name_utf8(struct d3d12_device *device, uint64_t vk_object,
|
||||||
VkObjectType vk_object_type, const char *name)
|
VkObjectType vk_object_type, const char *name)
|
||||||
{
|
{
|
||||||
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
||||||
VkDebugUtilsObjectNameInfoEXT info;
|
VkDebugUtilsObjectNameInfoEXT info;
|
||||||
VkResult vr;
|
|
||||||
|
|
||||||
if (!device->vk_info.EXT_debug_utils)
|
if (!device->vk_info.EXT_debug_utils)
|
||||||
return VK_SUCCESS;
|
return VK_SUCCESS;
|
||||||
|
@ -1266,8 +1154,28 @@ HRESULT vkd3d_set_vk_object_name(struct d3d12_device *device, uint64_t vk_object
|
||||||
info.objectType = vk_object_type;
|
info.objectType = vk_object_type;
|
||||||
info.objectHandle = vk_object;
|
info.objectHandle = vk_object;
|
||||||
info.pObjectName = name;
|
info.pObjectName = name;
|
||||||
|
return VK_CALL(vkSetDebugUtilsObjectNameEXT(device->vk_device, &info));
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT vkd3d_set_vk_object_name(struct d3d12_device *device, uint64_t vk_object,
|
||||||
|
VkObjectType vk_object_type, const WCHAR *name)
|
||||||
|
{
|
||||||
|
char *name_utf8;
|
||||||
|
VkResult vr;
|
||||||
|
|
||||||
|
if (!name)
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
if (!device->vk_info.EXT_debug_utils)
|
||||||
|
return S_OK;
|
||||||
|
|
||||||
|
if (!(name_utf8 = vkd3d_strdup_w_utf8(name, device->wchar_size, 0)))
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
vr = vkd3d_set_vk_object_name_utf8(device, vk_object, vk_object_type, name_utf8);
|
||||||
|
|
||||||
|
vkd3d_free(name_utf8);
|
||||||
|
|
||||||
vr = VK_CALL(vkSetDebugUtilsObjectNameEXT(device->vk_device, &info));
|
|
||||||
return hresult_from_vk_result(vr);
|
return hresult_from_vk_result(vr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,442 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2021 Philip Rebohle for Valve Software
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define VKD3D_DBG_CHANNEL VKD3D_DBG_CHANNEL_API
|
|
||||||
|
|
||||||
#include "vkd3d_private.h"
|
|
||||||
|
|
||||||
static inline VkDeviceAddress vkd3d_va_map_get_next_address(VkDeviceAddress va)
|
|
||||||
{
|
|
||||||
return va >> (VKD3D_VA_BLOCK_SIZE_BITS + VKD3D_VA_BLOCK_BITS);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline VkDeviceAddress vkd3d_va_map_get_block_address(VkDeviceAddress va)
|
|
||||||
{
|
|
||||||
return (va >> VKD3D_VA_BLOCK_SIZE_BITS) & VKD3D_VA_BLOCK_MASK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct vkd3d_va_block *vkd3d_va_map_find_block(struct vkd3d_va_map *va_map, VkDeviceAddress va)
|
|
||||||
{
|
|
||||||
VkDeviceAddress next_address = vkd3d_va_map_get_next_address(va);
|
|
||||||
struct vkd3d_va_tree *tree = &va_map->va_tree;
|
|
||||||
|
|
||||||
while (next_address && tree)
|
|
||||||
{
|
|
||||||
tree = vkd3d_atomic_ptr_load_explicit(&tree->next[next_address & VKD3D_VA_NEXT_MASK], vkd3d_memory_order_acquire);
|
|
||||||
next_address >>= VKD3D_VA_NEXT_BITS;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!tree)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return &tree->blocks[vkd3d_va_map_get_block_address(va)];
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct vkd3d_va_block *vkd3d_va_map_get_block(struct vkd3d_va_map *va_map, VkDeviceAddress va)
|
|
||||||
{
|
|
||||||
VkDeviceAddress next_address = vkd3d_va_map_get_next_address(va);
|
|
||||||
struct vkd3d_va_tree *tree, **tree_ptr;
|
|
||||||
|
|
||||||
tree = &va_map->va_tree;
|
|
||||||
|
|
||||||
while (next_address)
|
|
||||||
{
|
|
||||||
tree_ptr = &tree->next[next_address & VKD3D_VA_NEXT_MASK];
|
|
||||||
tree = vkd3d_atomic_ptr_load_explicit(tree_ptr, vkd3d_memory_order_acquire);
|
|
||||||
|
|
||||||
if (!tree)
|
|
||||||
{
|
|
||||||
void *orig;
|
|
||||||
tree = vkd3d_calloc(1, sizeof(*tree));
|
|
||||||
orig = vkd3d_atomic_ptr_compare_exchange(tree_ptr, NULL, tree, vkd3d_memory_order_release, vkd3d_memory_order_acquire);
|
|
||||||
|
|
||||||
if (orig)
|
|
||||||
{
|
|
||||||
vkd3d_free(tree);
|
|
||||||
tree = orig;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
next_address >>= VKD3D_VA_NEXT_BITS;
|
|
||||||
}
|
|
||||||
|
|
||||||
return &tree->blocks[vkd3d_va_map_get_block_address(va)];
|
|
||||||
}
|
|
||||||
|
|
||||||
static void vkd3d_va_map_cleanup_tree(struct vkd3d_va_tree *tree)
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(tree->next); i++)
|
|
||||||
{
|
|
||||||
if (tree->next[i])
|
|
||||||
{
|
|
||||||
vkd3d_va_map_cleanup_tree(tree->next[i]);
|
|
||||||
vkd3d_free(tree->next[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct vkd3d_unique_resource *vkd3d_va_map_find_small_entry(struct vkd3d_va_map *va_map,
|
|
||||||
VkDeviceAddress va, size_t *index)
|
|
||||||
{
|
|
||||||
struct vkd3d_unique_resource *resource = NULL;
|
|
||||||
size_t hi = va_map->small_entries_count;
|
|
||||||
size_t lo = 0;
|
|
||||||
|
|
||||||
while (lo < hi)
|
|
||||||
{
|
|
||||||
struct vkd3d_unique_resource *r;
|
|
||||||
size_t i = lo + (hi - lo) / 2;
|
|
||||||
|
|
||||||
r = va_map->small_entries[i];
|
|
||||||
|
|
||||||
if (va < r->va)
|
|
||||||
hi = i;
|
|
||||||
else if (va >= r->va + r->size)
|
|
||||||
lo = i + 1;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
lo = hi = i;
|
|
||||||
resource = r;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index)
|
|
||||||
*index = lo;
|
|
||||||
|
|
||||||
return resource;
|
|
||||||
}
|
|
||||||
|
|
||||||
void vkd3d_va_map_insert(struct vkd3d_va_map *va_map, struct vkd3d_unique_resource *resource)
|
|
||||||
{
|
|
||||||
VkDeviceAddress block_va, min_va, max_va;
|
|
||||||
struct vkd3d_va_block *block;
|
|
||||||
size_t index;
|
|
||||||
|
|
||||||
if (resource->size >= VKD3D_VA_BLOCK_SIZE)
|
|
||||||
{
|
|
||||||
min_va = resource->va;
|
|
||||||
max_va = resource->va + resource->size;
|
|
||||||
block_va = min_va & ~VKD3D_VA_LO_MASK;
|
|
||||||
|
|
||||||
while (block_va < max_va)
|
|
||||||
{
|
|
||||||
block = vkd3d_va_map_get_block(va_map, block_va);
|
|
||||||
|
|
||||||
if (block_va < min_va)
|
|
||||||
{
|
|
||||||
vkd3d_atomic_uint64_store_explicit(&block->r.va, min_va, vkd3d_memory_order_relaxed);
|
|
||||||
vkd3d_atomic_ptr_store_explicit(&block->r.resource, resource, vkd3d_memory_order_relaxed);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
vkd3d_atomic_uint64_store_explicit(&block->l.va, max_va, vkd3d_memory_order_relaxed);
|
|
||||||
vkd3d_atomic_ptr_store_explicit(&block->l.resource, resource, vkd3d_memory_order_relaxed);
|
|
||||||
}
|
|
||||||
|
|
||||||
block_va += VKD3D_VA_BLOCK_SIZE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pthread_mutex_lock(&va_map->mutex);
|
|
||||||
|
|
||||||
if (!vkd3d_va_map_find_small_entry(va_map, resource->va, &index))
|
|
||||||
{
|
|
||||||
vkd3d_array_reserve((void**)&va_map->small_entries, &va_map->small_entries_size,
|
|
||||||
va_map->small_entries_count + 1, sizeof(*va_map->small_entries));
|
|
||||||
|
|
||||||
memmove(&va_map->small_entries[index + 1], &va_map->small_entries[index],
|
|
||||||
sizeof(*va_map->small_entries) * (va_map->small_entries_count - index));
|
|
||||||
|
|
||||||
va_map->small_entries[index] = resource;
|
|
||||||
va_map->small_entries_count += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_mutex_unlock(&va_map->mutex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void vkd3d_va_map_remove(struct vkd3d_va_map *va_map, const struct vkd3d_unique_resource *resource)
|
|
||||||
{
|
|
||||||
VkDeviceAddress block_va, min_va, max_va;
|
|
||||||
struct vkd3d_va_block *block;
|
|
||||||
size_t index;
|
|
||||||
|
|
||||||
if (resource->size >= VKD3D_VA_BLOCK_SIZE)
|
|
||||||
{
|
|
||||||
min_va = resource->va;
|
|
||||||
max_va = resource->va + resource->size;
|
|
||||||
block_va = min_va & ~VKD3D_VA_LO_MASK;
|
|
||||||
|
|
||||||
while (block_va < max_va)
|
|
||||||
{
|
|
||||||
block = vkd3d_va_map_get_block(va_map, block_va);
|
|
||||||
|
|
||||||
if (vkd3d_atomic_ptr_load_explicit(&block->l.resource, vkd3d_memory_order_relaxed) == resource)
|
|
||||||
{
|
|
||||||
vkd3d_atomic_uint64_store_explicit(&block->l.va, 0, vkd3d_memory_order_relaxed);
|
|
||||||
vkd3d_atomic_ptr_store_explicit(&block->l.resource, NULL, vkd3d_memory_order_relaxed);
|
|
||||||
}
|
|
||||||
else if (vkd3d_atomic_ptr_load_explicit(&block->r.resource, vkd3d_memory_order_relaxed) == resource)
|
|
||||||
{
|
|
||||||
vkd3d_atomic_uint64_store_explicit(&block->r.va, 0, vkd3d_memory_order_relaxed);
|
|
||||||
vkd3d_atomic_ptr_store_explicit(&block->r.resource, NULL, vkd3d_memory_order_relaxed);
|
|
||||||
}
|
|
||||||
|
|
||||||
block_va += VKD3D_VA_BLOCK_SIZE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pthread_mutex_lock(&va_map->mutex);
|
|
||||||
|
|
||||||
if (vkd3d_va_map_find_small_entry(va_map, resource->va, &index) == resource)
|
|
||||||
{
|
|
||||||
va_map->small_entries_count -= 1;
|
|
||||||
|
|
||||||
memmove(&va_map->small_entries[index], &va_map->small_entries[index + 1],
|
|
||||||
sizeof(*va_map->small_entries) * (va_map->small_entries_count - index));
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_mutex_unlock(&va_map->mutex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct vkd3d_unique_resource *vkd3d_va_map_deref_mutable(struct vkd3d_va_map *va_map, VkDeviceAddress va)
|
|
||||||
{
|
|
||||||
struct vkd3d_va_block *block = vkd3d_va_map_find_block(va_map, va);
|
|
||||||
struct vkd3d_unique_resource *resource = NULL;
|
|
||||||
|
|
||||||
if (block)
|
|
||||||
{
|
|
||||||
if (va < vkd3d_atomic_uint64_load_explicit(&block->l.va, vkd3d_memory_order_relaxed))
|
|
||||||
resource = vkd3d_atomic_ptr_load_explicit(&block->l.resource, vkd3d_memory_order_relaxed);
|
|
||||||
else if (va >= vkd3d_atomic_uint64_load_explicit(&block->r.va, vkd3d_memory_order_relaxed))
|
|
||||||
resource = vkd3d_atomic_ptr_load_explicit(&block->r.resource, vkd3d_memory_order_relaxed);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!resource)
|
|
||||||
{
|
|
||||||
pthread_mutex_lock(&va_map->mutex);
|
|
||||||
resource = vkd3d_va_map_find_small_entry(va_map, va, NULL);
|
|
||||||
pthread_mutex_unlock(&va_map->mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
return resource;
|
|
||||||
}
|
|
||||||
|
|
||||||
const struct vkd3d_unique_resource *vkd3d_va_map_deref(struct vkd3d_va_map *va_map, VkDeviceAddress va)
|
|
||||||
{
|
|
||||||
return vkd3d_va_map_deref_mutable(va_map, va);
|
|
||||||
}
|
|
||||||
|
|
||||||
VkAccelerationStructureKHR vkd3d_va_map_place_acceleration_structure(struct vkd3d_va_map *va_map,
|
|
||||||
struct d3d12_device *device,
|
|
||||||
VkDeviceAddress va)
|
|
||||||
{
|
|
||||||
struct vkd3d_unique_resource *resource;
|
|
||||||
struct vkd3d_view_map *old_view_map;
|
|
||||||
struct vkd3d_view_map *view_map;
|
|
||||||
const struct vkd3d_view *view;
|
|
||||||
struct vkd3d_view_key key;
|
|
||||||
|
|
||||||
resource = vkd3d_va_map_deref_mutable(va_map, va);
|
|
||||||
if (!resource || !resource->va)
|
|
||||||
return VK_NULL_HANDLE;
|
|
||||||
|
|
||||||
view_map = vkd3d_atomic_ptr_load_explicit(&resource->view_map, vkd3d_memory_order_acquire);
|
|
||||||
if (!view_map)
|
|
||||||
{
|
|
||||||
/* This is the first time we attempt to place an AS on top of this allocation, so
|
|
||||||
* CAS in a pointer. */
|
|
||||||
view_map = vkd3d_malloc(sizeof(*view_map));
|
|
||||||
if (!view_map)
|
|
||||||
return VK_NULL_HANDLE;
|
|
||||||
|
|
||||||
if (FAILED(vkd3d_view_map_init(view_map)))
|
|
||||||
{
|
|
||||||
vkd3d_free(view_map);
|
|
||||||
return VK_NULL_HANDLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Need to release in case other RTASes are placed at the same time, so they observe
|
|
||||||
* the initialized view map, and need to acquire if some other thread placed it. */
|
|
||||||
old_view_map = vkd3d_atomic_ptr_compare_exchange(&resource->view_map, NULL, view_map,
|
|
||||||
vkd3d_memory_order_release, vkd3d_memory_order_acquire);
|
|
||||||
if (old_view_map)
|
|
||||||
{
|
|
||||||
vkd3d_view_map_destroy(view_map, device);
|
|
||||||
vkd3d_free(view_map);
|
|
||||||
view_map = old_view_map;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
key.view_type = VKD3D_VIEW_TYPE_ACCELERATION_STRUCTURE;
|
|
||||||
key.u.buffer.buffer = resource->vk_buffer;
|
|
||||||
key.u.buffer.offset = va - resource->va;
|
|
||||||
key.u.buffer.size = resource->size - key.u.buffer.offset;
|
|
||||||
key.u.buffer.format = NULL;
|
|
||||||
|
|
||||||
view = vkd3d_view_map_create_view(view_map, device, &key);
|
|
||||||
if (!view)
|
|
||||||
return VK_NULL_HANDLE;
|
|
||||||
return view->vk_acceleration_structure;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define VKD3D_FAKE_VA_ALIGNMENT (65536)
|
|
||||||
|
|
||||||
VkDeviceAddress vkd3d_va_map_alloc_fake_va(struct vkd3d_va_map *va_map, VkDeviceSize size)
|
|
||||||
{
|
|
||||||
struct vkd3d_va_allocator *allocator = &va_map->va_allocator;
|
|
||||||
struct vkd3d_va_range range;
|
|
||||||
VkDeviceAddress va;
|
|
||||||
size_t i;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
if ((rc = pthread_mutex_lock(&allocator->mutex)))
|
|
||||||
{
|
|
||||||
ERR("Failed to lock mutex, rc %d.\n", rc);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(&range, 0, sizeof(range));
|
|
||||||
size = align(size, VKD3D_FAKE_VA_ALIGNMENT);
|
|
||||||
|
|
||||||
/* The free list is ordered in such a way that the largest range
|
|
||||||
* is always first, so we don't have to iterate over the list */
|
|
||||||
if (allocator->free_range_count)
|
|
||||||
range = allocator->free_ranges[0];
|
|
||||||
|
|
||||||
if (range.size >= size)
|
|
||||||
{
|
|
||||||
va = range.base;
|
|
||||||
|
|
||||||
range.base += size;
|
|
||||||
range.size -= size;
|
|
||||||
|
|
||||||
for (i = 0; i < allocator->free_range_count - 1; i++)
|
|
||||||
{
|
|
||||||
if (allocator->free_ranges[i + 1].size > range.size)
|
|
||||||
allocator->free_ranges[i] = allocator->free_ranges[i + 1];
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (range.size)
|
|
||||||
allocator->free_ranges[i] = range;
|
|
||||||
else
|
|
||||||
allocator->free_range_count--;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
va = allocator->next_va;
|
|
||||||
allocator->next_va += size;
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_mutex_unlock(&allocator->mutex);
|
|
||||||
return va;
|
|
||||||
}
|
|
||||||
|
|
||||||
void vkd3d_va_map_free_fake_va(struct vkd3d_va_map *va_map, VkDeviceAddress va, VkDeviceSize size)
|
|
||||||
{
|
|
||||||
struct vkd3d_va_allocator *allocator = &va_map->va_allocator;
|
|
||||||
size_t range_idx, range_shift, i;
|
|
||||||
struct vkd3d_va_range new_range;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
if ((rc = pthread_mutex_lock(&allocator->mutex)))
|
|
||||||
{
|
|
||||||
ERR("Failed to lock mutex, rc %d.\n", rc);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
new_range.base = va;
|
|
||||||
new_range.size = align(size, VKD3D_FAKE_VA_ALIGNMENT);
|
|
||||||
|
|
||||||
range_idx = allocator->free_range_count;
|
|
||||||
range_shift = 0;
|
|
||||||
|
|
||||||
/* Find and effectively delete any free range adjacent to new_range */
|
|
||||||
for (i = 0; i < allocator->free_range_count; i++)
|
|
||||||
{
|
|
||||||
const struct vkd3d_va_range *cur_range = &allocator->free_ranges[i];
|
|
||||||
|
|
||||||
if (range_shift)
|
|
||||||
allocator->free_ranges[i - range_shift] = *cur_range;
|
|
||||||
|
|
||||||
if (cur_range->base == new_range.base + new_range.size || cur_range->base + cur_range->size == new_range.base)
|
|
||||||
{
|
|
||||||
if (range_idx == allocator->free_range_count)
|
|
||||||
range_idx = i;
|
|
||||||
else
|
|
||||||
range_shift++;
|
|
||||||
|
|
||||||
new_range.base = min(new_range.base, cur_range->base);
|
|
||||||
new_range.size += cur_range->size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (range_idx == allocator->free_range_count)
|
|
||||||
{
|
|
||||||
/* range_idx will be valid and point to the last element afterwards */
|
|
||||||
if (!(vkd3d_array_reserve((void **)&allocator->free_ranges, &allocator->free_ranges_size,
|
|
||||||
allocator->free_range_count + 1, sizeof(*allocator->free_ranges))))
|
|
||||||
{
|
|
||||||
ERR("Failed to add free range.\n");
|
|
||||||
pthread_mutex_unlock(&allocator->mutex);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
allocator->free_range_count += 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
allocator->free_range_count -= range_shift;
|
|
||||||
|
|
||||||
/* Move ranges smaller than our new free range back to keep the list ordered */
|
|
||||||
while (range_idx && allocator->free_ranges[range_idx - 1].size < new_range.size)
|
|
||||||
{
|
|
||||||
allocator->free_ranges[range_idx] = allocator->free_ranges[range_idx - 1];
|
|
||||||
range_idx--;
|
|
||||||
}
|
|
||||||
|
|
||||||
allocator->free_ranges[range_idx] = new_range;
|
|
||||||
pthread_mutex_unlock(&allocator->mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
void vkd3d_va_map_init(struct vkd3d_va_map *va_map)
|
|
||||||
{
|
|
||||||
memset(va_map, 0, sizeof(*va_map));
|
|
||||||
pthread_mutex_init(&va_map->mutex, NULL);
|
|
||||||
pthread_mutex_init(&va_map->va_allocator.mutex, NULL);
|
|
||||||
|
|
||||||
/* Make sure we never return 0 as a valid VA */
|
|
||||||
va_map->va_allocator.next_va = VKD3D_VA_BLOCK_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void vkd3d_va_map_cleanup(struct vkd3d_va_map *va_map)
|
|
||||||
{
|
|
||||||
vkd3d_va_map_cleanup_tree(&va_map->va_tree);
|
|
||||||
|
|
||||||
pthread_mutex_destroy(&va_map->va_allocator.mutex);
|
|
||||||
pthread_mutex_destroy(&va_map->mutex);
|
|
||||||
vkd3d_free(va_map->va_allocator.free_ranges);
|
|
||||||
vkd3d_free(va_map->small_entries);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,94 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2020 Hans-Kristian Arntzen for Valve Corporation
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __VKD3D_DESCRIPTOR_DEBUG_H
|
|
||||||
#define __VKD3D_DESCRIPTOR_DEBUG_H
|
|
||||||
|
|
||||||
#include "vkd3d_private.h"
|
|
||||||
#include "vkd3d_descriptor_qa_data.h"
|
|
||||||
|
|
||||||
/* Cost is 1 bit per cookie, and spending 256 MB of host memory on this is reasonable,
|
|
||||||
* and overflowing this pool should never happen. */
|
|
||||||
#define VKD3D_DESCRIPTOR_DEBUG_DEFAULT_NUM_COOKIES (2 * 1000 * 1000 * 1000)
|
|
||||||
#define VKD3D_DESCRIPTOR_DEBUG_NUM_PAD_DESCRIPTORS 1
|
|
||||||
|
|
||||||
#ifdef VKD3D_ENABLE_DESCRIPTOR_QA
|
|
||||||
HRESULT vkd3d_descriptor_debug_alloc_global_info(
|
|
||||||
struct vkd3d_descriptor_qa_global_info **global_info,
|
|
||||||
unsigned int num_cookies,
|
|
||||||
struct d3d12_device *device);
|
|
||||||
void vkd3d_descriptor_debug_free_global_info(
|
|
||||||
struct vkd3d_descriptor_qa_global_info *global_info,
|
|
||||||
struct d3d12_device *device);
|
|
||||||
|
|
||||||
void vkd3d_descriptor_debug_kick_qa_check(struct vkd3d_descriptor_qa_global_info *global_info);
|
|
||||||
|
|
||||||
const VkDescriptorBufferInfo *vkd3d_descriptor_debug_get_global_info_descriptor(
|
|
||||||
struct vkd3d_descriptor_qa_global_info *global_info);
|
|
||||||
|
|
||||||
void vkd3d_descriptor_debug_init(void);
|
|
||||||
bool vkd3d_descriptor_debug_active_log(void);
|
|
||||||
bool vkd3d_descriptor_debug_active_qa_checks(void);
|
|
||||||
|
|
||||||
void vkd3d_descriptor_debug_register_heap(
|
|
||||||
struct vkd3d_descriptor_qa_heap_buffer_data *heap, uint64_t cookie,
|
|
||||||
const D3D12_DESCRIPTOR_HEAP_DESC *desc);
|
|
||||||
void vkd3d_descriptor_debug_unregister_heap(uint64_t cookie);
|
|
||||||
|
|
||||||
void vkd3d_descriptor_debug_register_resource_cookie(
|
|
||||||
struct vkd3d_descriptor_qa_global_info *global_info,
|
|
||||||
uint64_t cookie, const D3D12_RESOURCE_DESC1 *desc);
|
|
||||||
void vkd3d_descriptor_debug_register_allocation_cookie(
|
|
||||||
struct vkd3d_descriptor_qa_global_info *global_info,
|
|
||||||
uint64_t cookie, const struct vkd3d_allocate_memory_info *info);
|
|
||||||
void vkd3d_descriptor_debug_register_view_cookie(
|
|
||||||
struct vkd3d_descriptor_qa_global_info *global_info,
|
|
||||||
uint64_t cookie, uint64_t resource_cookie);
|
|
||||||
void vkd3d_descriptor_debug_unregister_cookie(
|
|
||||||
struct vkd3d_descriptor_qa_global_info *global_info,
|
|
||||||
uint64_t cookie);
|
|
||||||
|
|
||||||
void vkd3d_descriptor_debug_write_descriptor(
|
|
||||||
struct vkd3d_descriptor_qa_heap_buffer_data *heap, uint64_t heap_cookie, uint32_t offset,
|
|
||||||
vkd3d_descriptor_qa_flags type_flags, uint64_t cookie);
|
|
||||||
void vkd3d_descriptor_debug_copy_descriptor(
|
|
||||||
struct vkd3d_descriptor_qa_heap_buffer_data *dst_heap, uint64_t dst_heap_cookie, uint32_t dst_offset,
|
|
||||||
struct vkd3d_descriptor_qa_heap_buffer_data *src_heap, uint64_t src_heap_cookie, uint32_t src_offset,
|
|
||||||
uint64_t cookie);
|
|
||||||
|
|
||||||
VkDeviceSize vkd3d_descriptor_debug_heap_info_size(unsigned int num_descriptors);
|
|
||||||
#else
|
|
||||||
#define vkd3d_descriptor_debug_alloc_global_info(global_info, num_cookies, device) (S_OK)
|
|
||||||
#define vkd3d_descriptor_debug_free_global_info(global_info, device) ((void)0)
|
|
||||||
#define vkd3d_descriptor_debug_kick_qa_check(global_info) ((void)0)
|
|
||||||
#define vkd3d_descriptor_debug_get_global_info_descriptor(global_info) ((const VkDescriptorBufferInfo *)NULL)
|
|
||||||
#define vkd3d_descriptor_debug_init() ((void)0)
|
|
||||||
#define vkd3d_descriptor_debug_active_log() ((void)0)
|
|
||||||
#define vkd3d_descriptor_debug_active_qa_checks() (false)
|
|
||||||
#define vkd3d_descriptor_debug_register_heap(heap, cookie, desc) ((void)0)
|
|
||||||
#define vkd3d_descriptor_debug_unregister_heap(cookie) ((void)0)
|
|
||||||
#define vkd3d_descriptor_debug_register_resource_cookie(global_info, cookie, desc) ((void)0)
|
|
||||||
#define vkd3d_descriptor_debug_register_allocation_cookie(global_info, cookie, info) ((void)0)
|
|
||||||
#define vkd3d_descriptor_debug_register_view_cookie(global_info, cookie, resource_cookie) ((void)0)
|
|
||||||
#define vkd3d_descriptor_debug_unregister_cookie(global_info, cookie) ((void)0)
|
|
||||||
#define vkd3d_descriptor_debug_write_descriptor(heap, heap_cookie, offset, type_flags, cookie) ((void)0)
|
|
||||||
#define vkd3d_descriptor_debug_copy_descriptor(dst_heap, dst_heap_cookie, dst_offset, src_heap, src_heap_cookie, src_offset, cookie) ((void)0)
|
|
||||||
#define vkd3d_descriptor_debug_heap_info_size(num_descriptors) 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -32,6 +32,11 @@ VKD3D_EXPORT HRESULT vkd3d_create_device(const struct vkd3d_device_create_info *
|
||||||
|
|
||||||
if (!create_info)
|
if (!create_info)
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
|
if (create_info->type != VKD3D_STRUCTURE_TYPE_DEVICE_CREATE_INFO)
|
||||||
|
{
|
||||||
|
WARN("Invalid structure type %#x.\n", create_info->type);
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
if (!create_info->instance && !create_info->instance_create_info)
|
if (!create_info->instance && !create_info->instance_create_info)
|
||||||
{
|
{
|
||||||
ERR("Instance or instance create info is required.\n");
|
ERR("Instance or instance create info is required.\n");
|
||||||
|
@ -163,43 +168,31 @@ static CONST_VTBL struct ID3D12RootSignatureDeserializerVtbl d3d12_root_signatur
|
||||||
d3d12_root_signature_deserializer_GetRootSignatureDesc,
|
d3d12_root_signature_deserializer_GetRootSignatureDesc,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int vkd3d_parse_root_signature_for_version(const struct vkd3d_shader_code *dxbc,
|
int vkd3d_parse_root_signature_v_1_0(const struct vkd3d_shader_code *dxbc,
|
||||||
struct vkd3d_versioned_root_signature_desc *out_desc,
|
struct vkd3d_versioned_root_signature_desc *out_desc)
|
||||||
enum vkd3d_root_signature_version target_version,
|
|
||||||
bool raw_payload,
|
|
||||||
vkd3d_shader_hash_t *compatibility_hash)
|
|
||||||
{
|
{
|
||||||
struct vkd3d_versioned_root_signature_desc desc, converted_desc;
|
struct vkd3d_versioned_root_signature_desc desc, converted_desc;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (raw_payload)
|
if ((ret = vkd3d_shader_parse_root_signature(dxbc, &desc)) < 0)
|
||||||
{
|
|
||||||
if ((ret = vkd3d_shader_parse_root_signature_raw(dxbc->code, dxbc->size, &desc, compatibility_hash)) < 0)
|
|
||||||
{
|
{
|
||||||
WARN("Failed to parse root signature, vkd3d result %d.\n", ret);
|
WARN("Failed to parse root signature, vkd3d result %d.\n", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ((ret = vkd3d_shader_parse_root_signature(dxbc, &desc, compatibility_hash)) < 0)
|
|
||||||
{
|
|
||||||
WARN("Failed to parse root signature, vkd3d result %d.\n", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (desc.version == target_version)
|
if (desc.version == VKD3D_ROOT_SIGNATURE_VERSION_1_0)
|
||||||
{
|
{
|
||||||
*out_desc = desc;
|
*out_desc = desc;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ret = vkd3d_shader_convert_root_signature(&converted_desc, target_version, &desc);
|
enum vkd3d_root_signature_version version = desc.version;
|
||||||
|
|
||||||
|
ret = vkd3d_shader_convert_root_signature(&converted_desc, VKD3D_ROOT_SIGNATURE_VERSION_1_0, &desc);
|
||||||
vkd3d_shader_free_root_signature(&desc);
|
vkd3d_shader_free_root_signature(&desc);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
WARN("Failed to convert from version %#x, vkd3d result %d.\n", desc.version, ret);
|
WARN("Failed to convert from version %#x, vkd3d result %d.\n", version, ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,30 +202,6 @@ static int vkd3d_parse_root_signature_for_version(const struct vkd3d_shader_code
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int vkd3d_parse_root_signature_v_1_0(const struct vkd3d_shader_code *dxbc,
|
|
||||||
struct vkd3d_versioned_root_signature_desc *out_desc,
|
|
||||||
vkd3d_shader_hash_t *compatibility_hash)
|
|
||||||
{
|
|
||||||
return vkd3d_parse_root_signature_for_version(dxbc, out_desc, VKD3D_ROOT_SIGNATURE_VERSION_1_0, false,
|
|
||||||
compatibility_hash);
|
|
||||||
}
|
|
||||||
|
|
||||||
int vkd3d_parse_root_signature_v_1_1(const struct vkd3d_shader_code *dxbc,
|
|
||||||
struct vkd3d_versioned_root_signature_desc *out_desc,
|
|
||||||
vkd3d_shader_hash_t *compatibility_hash)
|
|
||||||
{
|
|
||||||
return vkd3d_parse_root_signature_for_version(dxbc, out_desc, VKD3D_ROOT_SIGNATURE_VERSION_1_1, false,
|
|
||||||
compatibility_hash);
|
|
||||||
}
|
|
||||||
|
|
||||||
int vkd3d_parse_root_signature_v_1_1_from_raw_payload(const struct vkd3d_shader_code *dxbc,
|
|
||||||
struct vkd3d_versioned_root_signature_desc *out_desc,
|
|
||||||
vkd3d_shader_hash_t *compatibility_hash)
|
|
||||||
{
|
|
||||||
return vkd3d_parse_root_signature_for_version(dxbc, out_desc, VKD3D_ROOT_SIGNATURE_VERSION_1_1, true,
|
|
||||||
compatibility_hash);
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT d3d12_root_signature_deserializer_init(struct d3d12_root_signature_deserializer *deserializer,
|
static HRESULT d3d12_root_signature_deserializer_init(struct d3d12_root_signature_deserializer *deserializer,
|
||||||
const struct vkd3d_shader_code *dxbc)
|
const struct vkd3d_shader_code *dxbc)
|
||||||
{
|
{
|
||||||
|
@ -241,7 +210,7 @@ static HRESULT d3d12_root_signature_deserializer_init(struct d3d12_root_signatur
|
||||||
deserializer->ID3D12RootSignatureDeserializer_iface.lpVtbl = &d3d12_root_signature_deserializer_vtbl;
|
deserializer->ID3D12RootSignatureDeserializer_iface.lpVtbl = &d3d12_root_signature_deserializer_vtbl;
|
||||||
deserializer->refcount = 1;
|
deserializer->refcount = 1;
|
||||||
|
|
||||||
if ((ret = vkd3d_parse_root_signature_v_1_0(dxbc, &deserializer->desc.vkd3d, NULL)) < 0)
|
if ((ret = vkd3d_parse_root_signature_v_1_0(dxbc, &deserializer->desc.vkd3d)) < 0)
|
||||||
return hresult_from_vkd3d_result(ret);
|
return hresult_from_vkd3d_result(ret);
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
@ -419,7 +388,7 @@ static HRESULT d3d12_versioned_root_signature_deserializer_init(struct d3d12_ver
|
||||||
deserializer->ID3D12VersionedRootSignatureDeserializer_iface.lpVtbl = &d3d12_versioned_root_signature_deserializer_vtbl;
|
deserializer->ID3D12VersionedRootSignatureDeserializer_iface.lpVtbl = &d3d12_versioned_root_signature_deserializer_vtbl;
|
||||||
deserializer->refcount = 1;
|
deserializer->refcount = 1;
|
||||||
|
|
||||||
if ((ret = vkd3d_shader_parse_root_signature(dxbc, &deserializer->desc.vkd3d, NULL)) < 0)
|
if ((ret = vkd3d_shader_parse_root_signature(dxbc, &deserializer->desc.vkd3d)) < 0)
|
||||||
{
|
{
|
||||||
WARN("Failed to parse root signature, vkd3d result %d.\n", ret);
|
WARN("Failed to parse root signature, vkd3d result %d.\n", ret);
|
||||||
return hresult_from_vkd3d_result(ret);
|
return hresult_from_vkd3d_result(ret);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -26,7 +26,6 @@
|
||||||
bool vkd3d_renderdoc_active(void);
|
bool vkd3d_renderdoc_active(void);
|
||||||
bool vkd3d_renderdoc_loaded_api(void);
|
bool vkd3d_renderdoc_loaded_api(void);
|
||||||
bool vkd3d_renderdoc_should_capture_shader_hash(vkd3d_shader_hash_t hash);
|
bool vkd3d_renderdoc_should_capture_shader_hash(vkd3d_shader_hash_t hash);
|
||||||
bool vkd3d_renderdoc_global_capture_enabled(void);
|
|
||||||
|
|
||||||
bool vkd3d_renderdoc_begin_capture(void *instance);
|
bool vkd3d_renderdoc_begin_capture(void *instance);
|
||||||
void vkd3d_renderdoc_end_capture(void *instance);
|
void vkd3d_renderdoc_end_capture(void *instance);
|
||||||
|
|
|
@ -41,18 +41,11 @@ enum vkd3d_meta_copy_mode
|
||||||
#include <cs_clear_uav_image_2d_uint.h>
|
#include <cs_clear_uav_image_2d_uint.h>
|
||||||
#include <cs_clear_uav_image_3d_float.h>
|
#include <cs_clear_uav_image_3d_float.h>
|
||||||
#include <cs_clear_uav_image_3d_uint.h>
|
#include <cs_clear_uav_image_3d_uint.h>
|
||||||
#include <cs_predicate_command.h>
|
|
||||||
#include <cs_resolve_binary_queries.h>
|
#include <cs_resolve_binary_queries.h>
|
||||||
#include <cs_resolve_predicate.h>
|
|
||||||
#include <cs_resolve_query.h>
|
|
||||||
#include <cs_execute_indirect_patch.h>
|
|
||||||
#include <cs_execute_indirect_patch_debug_ring.h>
|
|
||||||
#include <vs_fullscreen_layer.h>
|
#include <vs_fullscreen_layer.h>
|
||||||
#include <vs_fullscreen.h>
|
#include <vs_fullscreen.h>
|
||||||
#include <gs_fullscreen.h>
|
#include <gs_fullscreen.h>
|
||||||
#include <fs_copy_image_float.h>
|
#include <fs_copy_image_float.h>
|
||||||
#include <fs_copy_image_uint.h>
|
|
||||||
#include <fs_copy_image_stencil.h>
|
|
||||||
#include <vs_swapchain_fullscreen.h>
|
#include <vs_swapchain_fullscreen.h>
|
||||||
#include <fs_swapchain_fullscreen.h>
|
#include <fs_swapchain_fullscreen.h>
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,6 @@ VK_INSTANCE_PFN(vkEnumeratePhysicalDevices)
|
||||||
VK_INSTANCE_PFN(vkGetDeviceProcAddr)
|
VK_INSTANCE_PFN(vkGetDeviceProcAddr)
|
||||||
VK_INSTANCE_PFN(vkGetPhysicalDeviceFeatures)
|
VK_INSTANCE_PFN(vkGetPhysicalDeviceFeatures)
|
||||||
VK_INSTANCE_PFN(vkGetPhysicalDeviceFormatProperties)
|
VK_INSTANCE_PFN(vkGetPhysicalDeviceFormatProperties)
|
||||||
VK_INSTANCE_PFN(vkGetPhysicalDeviceFormatProperties2)
|
|
||||||
VK_INSTANCE_PFN(vkGetPhysicalDeviceImageFormatProperties)
|
VK_INSTANCE_PFN(vkGetPhysicalDeviceImageFormatProperties)
|
||||||
VK_INSTANCE_PFN(vkGetPhysicalDeviceMemoryProperties)
|
VK_INSTANCE_PFN(vkGetPhysicalDeviceMemoryProperties)
|
||||||
VK_INSTANCE_PFN(vkGetPhysicalDeviceProperties)
|
VK_INSTANCE_PFN(vkGetPhysicalDeviceProperties)
|
||||||
|
@ -49,7 +48,6 @@ VK_INSTANCE_PFN(vkGetPhysicalDeviceQueueFamilyProperties)
|
||||||
VK_INSTANCE_PFN(vkGetPhysicalDeviceSparseImageFormatProperties)
|
VK_INSTANCE_PFN(vkGetPhysicalDeviceSparseImageFormatProperties)
|
||||||
VK_INSTANCE_PFN(vkGetPhysicalDeviceFeatures2)
|
VK_INSTANCE_PFN(vkGetPhysicalDeviceFeatures2)
|
||||||
VK_INSTANCE_PFN(vkGetPhysicalDeviceProperties2)
|
VK_INSTANCE_PFN(vkGetPhysicalDeviceProperties2)
|
||||||
VK_INSTANCE_PFN(vkGetPhysicalDeviceExternalSemaphoreProperties)
|
|
||||||
|
|
||||||
/* VK_EXT_debug_utils */
|
/* VK_EXT_debug_utils */
|
||||||
VK_INSTANCE_EXT_PFN(vkCreateDebugUtilsMessengerEXT)
|
VK_INSTANCE_EXT_PFN(vkCreateDebugUtilsMessengerEXT)
|
||||||
|
@ -62,14 +60,22 @@ VK_DEVICE_PFN(vkAllocateCommandBuffers)
|
||||||
VK_DEVICE_PFN(vkAllocateDescriptorSets)
|
VK_DEVICE_PFN(vkAllocateDescriptorSets)
|
||||||
VK_DEVICE_PFN(vkAllocateMemory)
|
VK_DEVICE_PFN(vkAllocateMemory)
|
||||||
VK_DEVICE_PFN(vkBeginCommandBuffer)
|
VK_DEVICE_PFN(vkBeginCommandBuffer)
|
||||||
|
VK_DEVICE_PFN(vkBindBufferMemory)
|
||||||
|
VK_DEVICE_PFN(vkBindImageMemory)
|
||||||
VK_DEVICE_PFN(vkCmdBeginQuery)
|
VK_DEVICE_PFN(vkCmdBeginQuery)
|
||||||
|
VK_DEVICE_PFN(vkCmdBeginRenderPass)
|
||||||
VK_DEVICE_PFN(vkCmdBindDescriptorSets)
|
VK_DEVICE_PFN(vkCmdBindDescriptorSets)
|
||||||
VK_DEVICE_PFN(vkCmdBindIndexBuffer)
|
VK_DEVICE_PFN(vkCmdBindIndexBuffer)
|
||||||
VK_DEVICE_PFN(vkCmdBindPipeline)
|
VK_DEVICE_PFN(vkCmdBindPipeline)
|
||||||
VK_DEVICE_PFN(vkCmdBindVertexBuffers)
|
VK_DEVICE_PFN(vkCmdBindVertexBuffers)
|
||||||
|
VK_DEVICE_PFN(vkCmdBlitImage)
|
||||||
VK_DEVICE_PFN(vkCmdClearAttachments)
|
VK_DEVICE_PFN(vkCmdClearAttachments)
|
||||||
VK_DEVICE_PFN(vkCmdClearColorImage)
|
VK_DEVICE_PFN(vkCmdClearColorImage)
|
||||||
VK_DEVICE_PFN(vkCmdClearDepthStencilImage)
|
VK_DEVICE_PFN(vkCmdClearDepthStencilImage)
|
||||||
|
VK_DEVICE_PFN(vkCmdCopyBuffer)
|
||||||
|
VK_DEVICE_PFN(vkCmdCopyBufferToImage)
|
||||||
|
VK_DEVICE_PFN(vkCmdCopyImage)
|
||||||
|
VK_DEVICE_PFN(vkCmdCopyImageToBuffer)
|
||||||
VK_DEVICE_PFN(vkCmdCopyQueryPoolResults)
|
VK_DEVICE_PFN(vkCmdCopyQueryPoolResults)
|
||||||
VK_DEVICE_PFN(vkCmdDispatch)
|
VK_DEVICE_PFN(vkCmdDispatch)
|
||||||
VK_DEVICE_PFN(vkCmdDispatchIndirect)
|
VK_DEVICE_PFN(vkCmdDispatchIndirect)
|
||||||
|
@ -78,6 +84,7 @@ VK_DEVICE_PFN(vkCmdDrawIndexed)
|
||||||
VK_DEVICE_PFN(vkCmdDrawIndexedIndirect)
|
VK_DEVICE_PFN(vkCmdDrawIndexedIndirect)
|
||||||
VK_DEVICE_PFN(vkCmdDrawIndirect)
|
VK_DEVICE_PFN(vkCmdDrawIndirect)
|
||||||
VK_DEVICE_PFN(vkCmdEndQuery)
|
VK_DEVICE_PFN(vkCmdEndQuery)
|
||||||
|
VK_DEVICE_PFN(vkCmdEndRenderPass)
|
||||||
VK_DEVICE_PFN(vkCmdExecuteCommands)
|
VK_DEVICE_PFN(vkCmdExecuteCommands)
|
||||||
VK_DEVICE_PFN(vkCmdFillBuffer)
|
VK_DEVICE_PFN(vkCmdFillBuffer)
|
||||||
VK_DEVICE_PFN(vkCmdNextSubpass)
|
VK_DEVICE_PFN(vkCmdNextSubpass)
|
||||||
|
@ -85,6 +92,7 @@ VK_DEVICE_PFN(vkCmdPipelineBarrier)
|
||||||
VK_DEVICE_PFN(vkCmdPushConstants)
|
VK_DEVICE_PFN(vkCmdPushConstants)
|
||||||
VK_DEVICE_PFN(vkCmdResetEvent)
|
VK_DEVICE_PFN(vkCmdResetEvent)
|
||||||
VK_DEVICE_PFN(vkCmdResetQueryPool)
|
VK_DEVICE_PFN(vkCmdResetQueryPool)
|
||||||
|
VK_DEVICE_PFN(vkCmdResolveImage)
|
||||||
VK_DEVICE_PFN(vkCmdSetBlendConstants)
|
VK_DEVICE_PFN(vkCmdSetBlendConstants)
|
||||||
VK_DEVICE_PFN(vkCmdSetDepthBias)
|
VK_DEVICE_PFN(vkCmdSetDepthBias)
|
||||||
VK_DEVICE_PFN(vkCmdSetDepthBounds)
|
VK_DEVICE_PFN(vkCmdSetDepthBounds)
|
||||||
|
@ -113,6 +121,7 @@ VK_DEVICE_PFN(vkCreateImageView)
|
||||||
VK_DEVICE_PFN(vkCreatePipelineCache)
|
VK_DEVICE_PFN(vkCreatePipelineCache)
|
||||||
VK_DEVICE_PFN(vkCreatePipelineLayout)
|
VK_DEVICE_PFN(vkCreatePipelineLayout)
|
||||||
VK_DEVICE_PFN(vkCreateQueryPool)
|
VK_DEVICE_PFN(vkCreateQueryPool)
|
||||||
|
VK_DEVICE_PFN(vkCreateRenderPass)
|
||||||
VK_DEVICE_PFN(vkCreateSampler)
|
VK_DEVICE_PFN(vkCreateSampler)
|
||||||
VK_DEVICE_PFN(vkCreateSemaphore)
|
VK_DEVICE_PFN(vkCreateSemaphore)
|
||||||
VK_DEVICE_PFN(vkCreateShaderModule)
|
VK_DEVICE_PFN(vkCreateShaderModule)
|
||||||
|
@ -130,6 +139,7 @@ VK_DEVICE_PFN(vkDestroyPipeline)
|
||||||
VK_DEVICE_PFN(vkDestroyPipelineCache)
|
VK_DEVICE_PFN(vkDestroyPipelineCache)
|
||||||
VK_DEVICE_PFN(vkDestroyPipelineLayout)
|
VK_DEVICE_PFN(vkDestroyPipelineLayout)
|
||||||
VK_DEVICE_PFN(vkDestroyQueryPool)
|
VK_DEVICE_PFN(vkDestroyQueryPool)
|
||||||
|
VK_DEVICE_PFN(vkDestroyRenderPass)
|
||||||
VK_DEVICE_PFN(vkDestroySampler)
|
VK_DEVICE_PFN(vkDestroySampler)
|
||||||
VK_DEVICE_PFN(vkDestroySemaphore)
|
VK_DEVICE_PFN(vkDestroySemaphore)
|
||||||
VK_DEVICE_PFN(vkDestroyShaderModule)
|
VK_DEVICE_PFN(vkDestroyShaderModule)
|
||||||
|
@ -153,6 +163,7 @@ VK_DEVICE_PFN(vkGetImageSparseMemoryRequirements2)
|
||||||
VK_DEVICE_PFN(vkGetImageSubresourceLayout)
|
VK_DEVICE_PFN(vkGetImageSubresourceLayout)
|
||||||
VK_DEVICE_PFN(vkGetPipelineCacheData)
|
VK_DEVICE_PFN(vkGetPipelineCacheData)
|
||||||
VK_DEVICE_PFN(vkGetQueryPoolResults)
|
VK_DEVICE_PFN(vkGetQueryPoolResults)
|
||||||
|
VK_DEVICE_PFN(vkGetRenderAreaGranularity)
|
||||||
VK_DEVICE_PFN(vkInvalidateMappedMemoryRanges)
|
VK_DEVICE_PFN(vkInvalidateMappedMemoryRanges)
|
||||||
VK_DEVICE_PFN(vkMapMemory)
|
VK_DEVICE_PFN(vkMapMemory)
|
||||||
VK_DEVICE_PFN(vkMergePipelineCaches)
|
VK_DEVICE_PFN(vkMergePipelineCaches)
|
||||||
|
@ -186,56 +197,6 @@ VK_DEVICE_EXT_PFN(vkCmdDrawIndexedIndirectCountKHR)
|
||||||
/* VK_KHR_push_descriptor */
|
/* VK_KHR_push_descriptor */
|
||||||
VK_DEVICE_EXT_PFN(vkCmdPushDescriptorSetKHR)
|
VK_DEVICE_EXT_PFN(vkCmdPushDescriptorSetKHR)
|
||||||
|
|
||||||
/* VK_KHR_ray_tracing_pipeline */
|
|
||||||
VK_DEVICE_EXT_PFN(vkCreateRayTracingPipelinesKHR)
|
|
||||||
VK_DEVICE_EXT_PFN(vkGetRayTracingShaderGroupHandlesKHR)
|
|
||||||
VK_DEVICE_EXT_PFN(vkGetRayTracingShaderGroupStackSizeKHR)
|
|
||||||
VK_DEVICE_EXT_PFN(vkCmdSetRayTracingPipelineStackSizeKHR)
|
|
||||||
VK_DEVICE_EXT_PFN(vkCmdTraceRaysKHR)
|
|
||||||
VK_DEVICE_EXT_PFN(vkCmdTraceRaysIndirectKHR)
|
|
||||||
|
|
||||||
/* VK_KHR_acceleration_structure */
|
|
||||||
VK_DEVICE_EXT_PFN(vkGetAccelerationStructureBuildSizesKHR)
|
|
||||||
VK_DEVICE_EXT_PFN(vkCreateAccelerationStructureKHR)
|
|
||||||
VK_DEVICE_EXT_PFN(vkDestroyAccelerationStructureKHR)
|
|
||||||
VK_DEVICE_EXT_PFN(vkGetAccelerationStructureDeviceAddressKHR)
|
|
||||||
VK_DEVICE_EXT_PFN(vkCmdBuildAccelerationStructuresKHR)
|
|
||||||
VK_DEVICE_EXT_PFN(vkCmdWriteAccelerationStructuresPropertiesKHR)
|
|
||||||
VK_DEVICE_EXT_PFN(vkCmdCopyAccelerationStructureKHR)
|
|
||||||
|
|
||||||
/* VK_KHR_fragment_shading_rate */
|
|
||||||
VK_INSTANCE_EXT_PFN(vkGetPhysicalDeviceFragmentShadingRatesKHR)
|
|
||||||
VK_DEVICE_EXT_PFN(vkCmdSetFragmentShadingRateKHR)
|
|
||||||
|
|
||||||
/* VK_KHR_bind_memory2 */
|
|
||||||
VK_DEVICE_EXT_PFN(vkBindBufferMemory2KHR)
|
|
||||||
VK_DEVICE_EXT_PFN(vkBindImageMemory2KHR)
|
|
||||||
|
|
||||||
/* VK_KHR_copy_commands2 */
|
|
||||||
VK_DEVICE_EXT_PFN(vkCmdBlitImage2KHR)
|
|
||||||
VK_DEVICE_EXT_PFN(vkCmdCopyBuffer2KHR)
|
|
||||||
VK_DEVICE_EXT_PFN(vkCmdCopyBufferToImage2KHR)
|
|
||||||
VK_DEVICE_EXT_PFN(vkCmdCopyImage2KHR)
|
|
||||||
VK_DEVICE_EXT_PFN(vkCmdCopyImageToBuffer2KHR)
|
|
||||||
VK_DEVICE_EXT_PFN(vkCmdResolveImage2KHR)
|
|
||||||
|
|
||||||
/* VK_KHR_maintenance4 */
|
|
||||||
VK_DEVICE_EXT_PFN(vkGetDeviceBufferMemoryRequirementsKHR)
|
|
||||||
VK_DEVICE_EXT_PFN(vkGetDeviceImageMemoryRequirementsKHR)
|
|
||||||
VK_DEVICE_EXT_PFN(vkGetDeviceImageSparseMemoryRequirementsKHR)
|
|
||||||
|
|
||||||
#ifdef VK_KHR_external_memory_win32
|
|
||||||
/* VK_KHR_external_memory_win32 */
|
|
||||||
VK_DEVICE_EXT_PFN(vkGetMemoryWin32HandleKHR)
|
|
||||||
VK_DEVICE_EXT_PFN(vkGetMemoryWin32HandlePropertiesKHR)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef VK_KHR_external_semaphore_win32
|
|
||||||
/* VK_KHR_external_semaphore_win32 */
|
|
||||||
VK_DEVICE_EXT_PFN(vkGetSemaphoreWin32HandleKHR)
|
|
||||||
VK_DEVICE_EXT_PFN(vkImportSemaphoreWin32HandleKHR)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* VK_EXT_calibrated_timestamps */
|
/* VK_EXT_calibrated_timestamps */
|
||||||
VK_DEVICE_EXT_PFN(vkGetCalibratedTimestampsEXT)
|
VK_DEVICE_EXT_PFN(vkGetCalibratedTimestampsEXT)
|
||||||
VK_INSTANCE_EXT_PFN(vkGetPhysicalDeviceCalibrateableTimeDomainsEXT)
|
VK_INSTANCE_EXT_PFN(vkGetPhysicalDeviceCalibrateableTimeDomainsEXT)
|
||||||
|
@ -263,9 +224,6 @@ VK_DEVICE_EXT_PFN(vkCmdSetPrimitiveTopologyEXT)
|
||||||
VK_DEVICE_EXT_PFN(vkCmdSetScissorWithCountEXT)
|
VK_DEVICE_EXT_PFN(vkCmdSetScissorWithCountEXT)
|
||||||
VK_DEVICE_EXT_PFN(vkCmdSetViewportWithCountEXT)
|
VK_DEVICE_EXT_PFN(vkCmdSetViewportWithCountEXT)
|
||||||
|
|
||||||
/* VK_EXT_extended_dynamic_state2 */
|
|
||||||
VK_DEVICE_EXT_PFN(vkCmdSetPrimitiveRestartEnableEXT)
|
|
||||||
|
|
||||||
/* VK_EXT_external_memory_host */
|
/* VK_EXT_external_memory_host */
|
||||||
VK_DEVICE_EXT_PFN(vkGetMemoryHostPointerPropertiesEXT)
|
VK_DEVICE_EXT_PFN(vkGetMemoryHostPointerPropertiesEXT)
|
||||||
|
|
||||||
|
@ -289,41 +247,9 @@ VK_DEVICE_EXT_PFN(vkGetSwapchainImagesKHR)
|
||||||
VK_DEVICE_EXT_PFN(vkAcquireNextImageKHR)
|
VK_DEVICE_EXT_PFN(vkAcquireNextImageKHR)
|
||||||
VK_DEVICE_EXT_PFN(vkQueuePresentKHR)
|
VK_DEVICE_EXT_PFN(vkQueuePresentKHR)
|
||||||
|
|
||||||
/* VK_KHR_dynamic_rendering */
|
|
||||||
VK_DEVICE_EXT_PFN(vkCmdBeginRenderingKHR)
|
|
||||||
VK_DEVICE_EXT_PFN(vkCmdEndRenderingKHR)
|
|
||||||
|
|
||||||
/* VK_KHR_ray_tracing_maintenance1 */
|
|
||||||
VK_DEVICE_EXT_PFN(vkCmdTraceRaysIndirect2KHR)
|
|
||||||
|
|
||||||
/* VK_AMD_buffer_marker */
|
/* VK_AMD_buffer_marker */
|
||||||
VK_DEVICE_EXT_PFN(vkCmdWriteBufferMarkerAMD)
|
VK_DEVICE_EXT_PFN(vkCmdWriteBufferMarkerAMD)
|
||||||
|
|
||||||
/* VK_NV_device_diagnostic_checkpoints */
|
|
||||||
VK_DEVICE_EXT_PFN(vkCmdSetCheckpointNV)
|
|
||||||
VK_DEVICE_EXT_PFN(vkGetQueueCheckpointDataNV)
|
|
||||||
|
|
||||||
/* VK_NVX_binary_import */
|
|
||||||
VK_DEVICE_EXT_PFN(vkCreateCuModuleNVX)
|
|
||||||
VK_DEVICE_EXT_PFN(vkCreateCuFunctionNVX)
|
|
||||||
VK_DEVICE_EXT_PFN(vkDestroyCuModuleNVX)
|
|
||||||
VK_DEVICE_EXT_PFN(vkDestroyCuFunctionNVX)
|
|
||||||
VK_DEVICE_EXT_PFN(vkCmdCuLaunchKernelNVX)
|
|
||||||
|
|
||||||
/* VK_NVX_image_view_handle */
|
|
||||||
VK_DEVICE_EXT_PFN(vkGetImageViewHandleNVX)
|
|
||||||
VK_DEVICE_EXT_PFN(vkGetImageViewAddressNVX)
|
|
||||||
|
|
||||||
/* VK_VALVE_descriptor_set_host_mapping */
|
|
||||||
VK_DEVICE_EXT_PFN(vkGetDescriptorSetLayoutHostMappingInfoVALVE)
|
|
||||||
VK_DEVICE_EXT_PFN(vkGetDescriptorSetHostMappingVALVE)
|
|
||||||
|
|
||||||
/* VK_NV_device_generated_commands */
|
|
||||||
VK_DEVICE_EXT_PFN(vkCreateIndirectCommandsLayoutNV)
|
|
||||||
VK_DEVICE_EXT_PFN(vkDestroyIndirectCommandsLayoutNV)
|
|
||||||
VK_DEVICE_EXT_PFN(vkGetGeneratedCommandsMemoryRequirementsNV)
|
|
||||||
VK_DEVICE_EXT_PFN(vkCmdExecuteGeneratedCommandsNV)
|
|
||||||
|
|
||||||
#undef VK_INSTANCE_PFN
|
#undef VK_INSTANCE_PFN
|
||||||
#undef VK_INSTANCE_EXT_PFN
|
#undef VK_INSTANCE_EXT_PFN
|
||||||
#undef VK_DEVICE_PFN
|
#undef VK_DEVICE_PFN
|
||||||
|
|
60
meson.build
60
meson.build
|
@ -1,42 +1,31 @@
|
||||||
project('vkd3d-proton', ['c'], version : '2.6', meson_version : '>= 0.49', default_options : [
|
project('vkd3d-proton', ['c'], version : '2.0', meson_version : '>= 0.49', default_options : [
|
||||||
'warning_level=2',
|
'warning_level=2',
|
||||||
])
|
])
|
||||||
|
|
||||||
cpu_family = target_machine.cpu_family()
|
cpu_family = target_machine.cpu_family()
|
||||||
|
|
||||||
vkd3d_compiler = meson.get_compiler('c')
|
vkd3d_compiler = meson.get_compiler('c')
|
||||||
vkd3d_is_msvc = vkd3d_compiler.get_id() == 'msvc' or vkd3d_compiler.get_id() == 'clang-cl'
|
vkd3d_msvc = vkd3d_compiler.get_id() == 'msvc'
|
||||||
vkd3d_is_clang = vkd3d_compiler.get_id() == 'clang'
|
vkd3d_c_std = 'c99'
|
||||||
vkd3d_c_std = 'c11'
|
|
||||||
vkd3d_platform = target_machine.system()
|
vkd3d_platform = target_machine.system()
|
||||||
|
|
||||||
vkd3d_buildtype = get_option('buildtype')
|
|
||||||
vkd3d_debug = vkd3d_buildtype == 'debug' or vkd3d_buildtype == 'debugoptimized'
|
|
||||||
|
|
||||||
enable_tests = get_option('enable_tests')
|
enable_tests = get_option('enable_tests')
|
||||||
enable_extras = get_option('enable_extras')
|
enable_extras = get_option('enable_extras')
|
||||||
enable_d3d12 = get_option('enable_d3d12')
|
enable_d3d12 = get_option('enable_d3d12')
|
||||||
enable_profiling = get_option('enable_profiling')
|
enable_profiling = get_option('enable_profiling')
|
||||||
enable_renderdoc = get_option('enable_renderdoc')
|
enable_renderdoc = get_option('enable_renderdoc')
|
||||||
enable_descriptor_qa = get_option('enable_descriptor_qa')
|
|
||||||
enable_trace = get_option('enable_trace')
|
|
||||||
|
|
||||||
if enable_d3d12 == 'auto'
|
if enable_d3d12 == 'auto'
|
||||||
enable_d3d12 = vkd3d_platform == 'windows'
|
enable_d3d12 = (vkd3d_platform == 'windows')
|
||||||
else
|
else
|
||||||
enable_d3d12 = enable_d3d12 == 'true'
|
enable_d3d12 = (enable_d3d12 == 'true')
|
||||||
endif
|
|
||||||
|
|
||||||
if enable_trace == 'auto'
|
|
||||||
enable_trace = vkd3d_debug
|
|
||||||
else
|
|
||||||
enable_trace = enable_trace == 'true'
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if vkd3d_platform != 'windows' and enable_d3d12
|
if vkd3d_platform != 'windows' and enable_d3d12
|
||||||
error('Standalone D3D12 is only supported on Windows.')
|
error('Standalone D3D12 is only supported on Windows.')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
add_project_arguments('-DHAVE_DXIL_SPV', language : 'c')
|
||||||
add_project_arguments('-D_GNU_SOURCE', language : 'c')
|
add_project_arguments('-D_GNU_SOURCE', language : 'c')
|
||||||
add_project_arguments('-DPACKAGE_VERSION="' + meson.project_version() + '"', language : 'c')
|
add_project_arguments('-DPACKAGE_VERSION="' + meson.project_version() + '"', language : 'c')
|
||||||
|
|
||||||
|
@ -56,19 +45,6 @@ if enable_renderdoc
|
||||||
add_project_arguments('-DVKD3D_ENABLE_RENDERDOC', language : 'c')
|
add_project_arguments('-DVKD3D_ENABLE_RENDERDOC', language : 'c')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if enable_descriptor_qa
|
|
||||||
add_project_arguments('-DVKD3D_ENABLE_DESCRIPTOR_QA', language : 'c')
|
|
||||||
endif
|
|
||||||
|
|
||||||
if not enable_trace
|
|
||||||
add_project_arguments('-DVKD3D_NO_TRACE_MESSAGES', language : 'c')
|
|
||||||
endif
|
|
||||||
|
|
||||||
enable_breadcrumbs = enable_trace
|
|
||||||
if enable_breadcrumbs
|
|
||||||
add_project_arguments('-DVKD3D_ENABLE_BREADCRUMBS', language : 'c')
|
|
||||||
endif
|
|
||||||
|
|
||||||
vkd3d_external_includes = [ './subprojects/Vulkan-Headers/include', './subprojects/SPIRV-Headers/include' ]
|
vkd3d_external_includes = [ './subprojects/Vulkan-Headers/include', './subprojects/SPIRV-Headers/include' ]
|
||||||
vkd3d_public_includes = [ './include' ] + vkd3d_external_includes
|
vkd3d_public_includes = [ './include' ] + vkd3d_external_includes
|
||||||
vkd3d_private_includes = [ './include/private' ] + vkd3d_public_includes
|
vkd3d_private_includes = [ './include/private' ] + vkd3d_public_includes
|
||||||
|
@ -83,13 +59,9 @@ idl_generator = generator(idl_compiler,
|
||||||
arguments : [ '-h', '-o', '@OUTPUT@', '@INPUT@' ])
|
arguments : [ '-h', '-o', '@OUTPUT@', '@INPUT@' ])
|
||||||
|
|
||||||
glsl_compiler = find_program('glslangValidator')
|
glsl_compiler = find_program('glslangValidator')
|
||||||
glsl_args = [ '-V', '--target-env', 'vulkan1.1', '--vn', '@BASENAME@', '@INPUT@', '-o', '@OUTPUT@' ]
|
|
||||||
if run_command(glsl_compiler, [ '--quiet', '--version' ], check : false).returncode() == 0
|
|
||||||
glsl_args += [ '--quiet' ]
|
|
||||||
endif
|
|
||||||
glsl_generator = generator(glsl_compiler,
|
glsl_generator = generator(glsl_compiler,
|
||||||
output : [ '@BASENAME@.h' ],
|
output : [ '@BASENAME@.h' ],
|
||||||
arguments : glsl_args)
|
arguments : [ '-V', '--vn', '@BASENAME@', '@INPUT@', '-o', '@OUTPUT@' ])
|
||||||
|
|
||||||
threads_dep = dependency('threads')
|
threads_dep = dependency('threads')
|
||||||
lib_d3d12 = vkd3d_compiler.find_library('d3d12', required : false)
|
lib_d3d12 = vkd3d_compiler.find_library('d3d12', required : false)
|
||||||
|
@ -106,9 +78,6 @@ endif
|
||||||
|
|
||||||
add_project_arguments(vkd3d_compiler.get_supported_arguments([
|
add_project_arguments(vkd3d_compiler.get_supported_arguments([
|
||||||
'-fvisibility=hidden',
|
'-fvisibility=hidden',
|
||||||
# For some reason, the use of VLAs isn't in all+extra+pedantic
|
|
||||||
# We don't want to use these accidentally from consts...
|
|
||||||
'-Wvla',
|
|
||||||
'-Wno-format',
|
'-Wno-format',
|
||||||
'-Wno-missing-field-initializers',
|
'-Wno-missing-field-initializers',
|
||||||
'-Wno-unused-parameter',
|
'-Wno-unused-parameter',
|
||||||
|
@ -128,21 +97,6 @@ if cpu_family == 'x86'
|
||||||
'-Wl,--add-stdcall-alias',
|
'-Wl,--add-stdcall-alias',
|
||||||
'-Wl,--enable-stdcall-fixup']),
|
'-Wl,--enable-stdcall-fixup']),
|
||||||
language : [ 'c', 'cpp' ])
|
language : [ 'c', 'cpp' ])
|
||||||
|
|
||||||
# Need to link against libatomic for 64-bit atomic emulation on x86
|
|
||||||
# when using clang.
|
|
||||||
if vkd3d_is_clang
|
|
||||||
lib_atomic = vkd3d_compiler.find_library('atomic')
|
|
||||||
vkd3d_extra_libs += lib_atomic
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
if not vkd3d_is_msvc
|
|
||||||
# We need to set the section alignment for debug symbols to
|
|
||||||
# work properly as well as avoiding a memcpy from the Wine loader.
|
|
||||||
if vkd3d_compiler.has_link_argument('-Wl,--file-alignment=4096')
|
|
||||||
add_global_link_arguments('-Wl,--file-alignment=4096', language : [ 'c', 'cpp' ])
|
|
||||||
endif
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
vkd3d_build = vcs_tag(
|
vkd3d_build = vcs_tag(
|
||||||
|
|
|
@ -3,5 +3,3 @@ option('enable_extras', type : 'boolean', value : false)
|
||||||
option('enable_d3d12', type : 'combo', value : 'auto', choices : ['false', 'true', 'auto'])
|
option('enable_d3d12', type : 'combo', value : 'auto', choices : ['false', 'true', 'auto'])
|
||||||
option('enable_profiling', type : 'boolean', value : false)
|
option('enable_profiling', type : 'boolean', value : false)
|
||||||
option('enable_renderdoc', type : 'boolean', value : false)
|
option('enable_renderdoc', type : 'boolean', value : false)
|
||||||
option('enable_descriptor_qa', type : 'boolean', value : false)
|
|
||||||
option('enable_trace', type : 'combo', value : 'auto', choices : ['false', 'true', 'auto'])
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue