Compare commits
210 Commits
pso-creati
...
master
Author | SHA1 | Date |
---|---|---|
Joshua Ashton | d00d035321 | |
Joshua Ashton | 253dc9027a | |
Derek Lesho | 146f5b8a74 | |
Hans-Kristian Arntzen | db4a8544a1 | |
Hans-Kristian Arntzen | 1d25b29413 | |
Hans-Kristian Arntzen | 34a04a1a7f | |
Hans-Kristian Arntzen | b839fe14bb | |
Hans-Kristian Arntzen | d3a76eee90 | |
Hans-Kristian Arntzen | 481680ecd8 | |
Hans-Kristian Arntzen | 11c82c84d1 | |
Hans-Kristian Arntzen | c0b9682c69 | |
Hans-Kristian Arntzen | 9d8abd2db5 | |
Derek Lesho | df1829e407 | |
Hans-Kristian Arntzen | be2aafff1a | |
Derek Lesho | 849537614a | |
Derek Lesho | f487db4756 | |
Hans-Kristian Arntzen | 6265a7b5ce | |
Hans-Kristian Arntzen | 4f4c96bb11 | |
Derek Lesho | a2439e766f | |
Hans-Kristian Arntzen | 21799b202b | |
Hans-Kristian Arntzen | 4ff504b52d | |
Hans-Kristian Arntzen | 6335e411bb | |
Hans-Kristian Arntzen | 11c943dd7e | |
Hans-Kristian Arntzen | 5b73139f18 | |
Hans-Kristian Arntzen | 73700f4c3a | |
Hans-Kristian Arntzen | a917d60ca5 | |
Hans-Kristian Arntzen | 8d780458f1 | |
Hans-Kristian Arntzen | 8da6ca6772 | |
Hans-Kristian Arntzen | 766da69afb | |
Hans-Kristian Arntzen | b7a960f94f | |
Hans-Kristian Arntzen | ee39209798 | |
Hans-Kristian Arntzen | afb87e013f | |
Hans-Kristian Arntzen | 433262c254 | |
Hans-Kristian Arntzen | 277bbe35e8 | |
Hans-Kristian Arntzen | 9451fdcab9 | |
Hans-Kristian Arntzen | 0640f44560 | |
Hans-Kristian Arntzen | b287864cd1 | |
Hans-Kristian Arntzen | 0a7b13fe7f | |
Hans-Kristian Arntzen | f704cb9776 | |
Hans-Kristian Arntzen | e17a7cb40c | |
Hans-Kristian Arntzen | 9e45c72256 | |
Hans-Kristian Arntzen | 2a8c762025 | |
Hans-Kristian Arntzen | 3b8a13e63d | |
Hans-Kristian Arntzen | 65804bbde5 | |
Hans-Kristian Arntzen | 233ff38175 | |
Hans-Kristian Arntzen | 4a07d9c038 | |
Hans-Kristian Arntzen | bcdac3180a | |
Hans-Kristian Arntzen | df11b5ba5a | |
Hans-Kristian Arntzen | e138a5117a | |
Hans-Kristian Arntzen | 96fdb71ae4 | |
Hans-Kristian Arntzen | fe707989fe | |
Hans-Kristian Arntzen | 6d3c5d53b0 | |
Hans-Kristian Arntzen | f93a581dae | |
Hans-Kristian Arntzen | b7bbdcabd4 | |
Hans-Kristian Arntzen | a28e4b6e11 | |
Hans-Kristian Arntzen | eda0b2fab2 | |
Hans-Kristian Arntzen | 7f5dbcfc40 | |
Hans-Kristian Arntzen | d333159c86 | |
Hans-Kristian Arntzen | 74eb676cfb | |
Hans-Kristian Arntzen | 5033904e10 | |
Hans-Kristian Arntzen | b34931eb17 | |
Hans-Kristian Arntzen | 7410f53912 | |
Hans-Kristian Arntzen | 089d2c6cb7 | |
Hans-Kristian Arntzen | 03fdbac59e | |
Hans-Kristian Arntzen | 7832eeb60d | |
Hans-Kristian Arntzen | 8a94c3ce0e | |
Hans-Kristian Arntzen | ddb425c5cb | |
Hans-Kristian Arntzen | ad7459551d | |
Hans-Kristian Arntzen | e3c36a47dd | |
Hans-Kristian Arntzen | ee8b8374b4 | |
Hans-Kristian Arntzen | ce00c9322d | |
Hans-Kristian Arntzen | b88b04e4f1 | |
Hans-Kristian Arntzen | 4a121b9aaa | |
Hans-Kristian Arntzen | 0ef6a8b798 | |
Hans-Kristian Arntzen | 49b6e67e7d | |
Hans-Kristian Arntzen | 2ef3fd469c | |
Hans-Kristian Arntzen | 22778b99be | |
Hans-Kristian Arntzen | b8b2a93aa6 | |
Hans-Kristian Arntzen | 14470d5456 | |
Hans-Kristian Arntzen | 3aad4edf6e | |
Hans-Kristian Arntzen | 3c92b3a1bc | |
Hans-Kristian Arntzen | 8473355a98 | |
Hans-Kristian Arntzen | 1438ff5637 | |
Hans-Kristian Arntzen | c3ee963d2f | |
Hans-Kristian Arntzen | 684e41fabe | |
Philip Rebohle | 1d869e3e21 | |
Tatsuyuki Ishi | 02c7ec404c | |
Hans-Kristian Arntzen | 9b5f3bfc26 | |
Hans-Kristian Arntzen | b4ab6c3f08 | |
Hans-Kristian Arntzen | 707af8152e | |
Hans-Kristian Arntzen | bc759be2af | |
Hans-Kristian Arntzen | 18f1d1c72e | |
Hans-Kristian Arntzen | 1b704287e5 | |
Hans-Kristian Arntzen | f975f09bb1 | |
Hans-Kristian Arntzen | 619a54810d | |
Hans-Kristian Arntzen | cecb8d6ebc | |
Hans-Kristian Arntzen | 8ae391e675 | |
Hans-Kristian Arntzen | a30205589f | |
Hans-Kristian Arntzen | abdef77695 | |
Hans-Kristian Arntzen | c132073df8 | |
Hans-Kristian Arntzen | 128852200a | |
Hans-Kristian Arntzen | 717026f903 | |
Hans-Kristian Arntzen | b849bd4256 | |
Georg Lehmann | d8905afd5d | |
Hans-Kristian Arntzen | de5b751468 | |
Hans-Kristian Arntzen | 219d9698b3 | |
Hans-Kristian Arntzen | acef5429c5 | |
Hans-Kristian Arntzen | 135aff4685 | |
Hans-Kristian Arntzen | 2f6a9e0d55 | |
Hans-Kristian Arntzen | 3a19dea7c7 | |
Tatsuyuki Ishi | 39d07dea2c | |
Tatsuyuki Ishi | 3577ca3144 | |
Tatsuyuki Ishi | 829ac72e3d | |
Hans-Kristian Arntzen | c64916686d | |
Hans-Kristian Arntzen | c4b00bbe1e | |
Hans-Kristian Arntzen | fd05839eb9 | |
Hans-Kristian Arntzen | 46470017a3 | |
Georg Lehmann | cbca29dd90 | |
Hans-Kristian Arntzen | c3fb6a6c5e | |
Hans-Kristian Arntzen | e8f1936ee2 | |
Hans-Kristian Arntzen | 4166eb042b | |
Hans-Kristian Arntzen | 7a002698f3 | |
Hans-Kristian Arntzen | 896e6fb868 | |
Hans-Kristian Arntzen | 8989360087 | |
Hans-Kristian Arntzen | f804ddc4c7 | |
Hans-Kristian Arntzen | 3b0d7e043d | |
Hans-Kristian Arntzen | 75e0506404 | |
Hans-Kristian Arntzen | 0f9d7dd10d | |
Hans-Kristian Arntzen | 7acc33ae39 | |
Hans-Kristian Arntzen | 7916d2a6d8 | |
Hans-Kristian Arntzen | 48157c29e8 | |
Hans-Kristian Arntzen | 467db76f90 | |
Hans-Kristian Arntzen | 2953ef8688 | |
Hans-Kristian Arntzen | f964532619 | |
Hans-Kristian Arntzen | 5a0c8289d8 | |
Hans-Kristian Arntzen | cca7613bca | |
Philip Rebohle | 910f15dff8 | |
Hans-Kristian Arntzen | a94e9b8b6a | |
Hans-Kristian Arntzen | 4ac0a3b455 | |
Hans-Kristian Arntzen | 300058d9a7 | |
Hans-Kristian Arntzen | 2e16a777ca | |
Hans-Kristian Arntzen | ac211d5f6a | |
Hans-Kristian Arntzen | 1dc4bbe5f2 | |
Tatsuyuki Ishi | 2965b7e379 | |
Tatsuyuki Ishi | 0d9c0a3903 | |
Robin Kertels | 1a773cfb71 | |
Robin Kertels | cdabda7805 | |
Robin Kertels | 8ac7aaca99 | |
Robin Kertels | 7e7c472005 | |
Hans-Kristian Arntzen | 71940797d1 | |
Hans-Kristian Arntzen | 4603c25d69 | |
Hans-Kristian Arntzen | 97201b8e93 | |
Hans-Kristian Arntzen | 51199752dd | |
Hans-Kristian Arntzen | ebe589d622 | |
Hans-Kristian Arntzen | 55a6847c61 | |
Hans-Kristian Arntzen | 04c020525c | |
Dean Beeler | 063ce7e4bd | |
Hans-Kristian Arntzen | 2c54e18245 | |
Philip Rebohle | bb2e35c539 | |
Philip Rebohle | d5ad5bb1de | |
Philip Rebohle | beb58f8472 | |
Hans-Kristian Arntzen | 358f95aff2 | |
Philip Rebohle | 119e00ed45 | |
Philip Rebohle | beaedbd857 | |
Philip Rebohle | 81927c5895 | |
Philip Rebohle | e7a6af4971 | |
Philip Rebohle | a1d5e6f39a | |
Hans-Kristian Arntzen | 4a05360a0a | |
Hans-Kristian Arntzen | 0c4df9b32c | |
Hans-Kristian Arntzen | 25c4bc18e7 | |
Hans-Kristian Arntzen | 30ec6b7f1f | |
Hans-Kristian Arntzen | c47a6a904b | |
Hans-Kristian Arntzen | 5044975152 | |
Hans-Kristian Arntzen | 8dc8b72807 | |
Hans-Kristian Arntzen | ae0dafa3a1 | |
Hans-Kristian Arntzen | 6c8542f7d6 | |
Hans-Kristian Arntzen | 2dcb1e2efc | |
Hans-Kristian Arntzen | 3095ed84d3 | |
Hans-Kristian Arntzen | db9b9a13de | |
Hans-Kristian Arntzen | 637834dc75 | |
Hans-Kristian Arntzen | 93928424a9 | |
Hans-Kristian Arntzen | c8b143c0bd | |
Hans-Kristian Arntzen | ca0a186a4b | |
Philip Rebohle | c9101b8ec3 | |
Philip Rebohle | 829c02bf90 | |
Philip Rebohle | e4184830c5 | |
Philip Rebohle | d1425ee4d1 | |
Denis Barkar | 8dda6df729 | |
Joshua Ashton | 2ed513b99a | |
Hans-Kristian Arntzen | 19e088cdfc | |
Hans-Kristian Arntzen | 241078d7e8 | |
Hans-Kristian Arntzen | e01589a33b | |
Hans-Kristian Arntzen | 2e704c5a5e | |
Hans-Kristian Arntzen | 6f43f450c8 | |
Hans-Kristian Arntzen | cfeaa18b09 | |
Hans-Kristian Arntzen | da63f0beac | |
Hans-Kristian Arntzen | 35e777f8a0 | |
Hans-Kristian Arntzen | 095a36cbaf | |
Philip Rebohle | 6378f1b880 | |
Philip Rebohle | 307190e96b | |
Hans-Kristian Arntzen | 2e8fb27182 | |
Hans-Kristian Arntzen | 1b5f7e8fc3 | |
Hans-Kristian Arntzen | cf65a78570 | |
Philip Rebohle | 1d3957fe6d | |
Philip Rebohle | c9abcfa656 | |
Hans-Kristian Arntzen | 03427c6ee6 | |
Hans-Kristian Arntzen | 09682f8417 | |
Hans-Kristian Arntzen | 6273780e50 | |
Hans-Kristian Arntzen | 6e915dd2c0 | |
Philip Rebohle | 34f5fc6a31 |
|
@ -15,7 +15,7 @@ jobs:
|
|||
|
||||
- name: Build release
|
||||
id: build-release
|
||||
uses: Joshua-Ashton/arch-mingw-github-action@v7
|
||||
uses: Joshua-Ashton/arch-mingw-github-action@v8
|
||||
with:
|
||||
command: |
|
||||
export VERSION_NAME="${GITHUB_REF##*/}-${GITHUB_SHA##*/}"
|
||||
|
|
|
@ -18,7 +18,7 @@ jobs:
|
|||
|
||||
- name: Build MinGW x86
|
||||
id: build-mingw-x86
|
||||
uses: Joshua-Ashton/arch-mingw-github-action@v7
|
||||
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
|
||||
|
@ -26,7 +26,7 @@ jobs:
|
|||
|
||||
- name: Build MinGW x64
|
||||
id: build-mingw-x64
|
||||
uses: Joshua-Ashton/arch-mingw-github-action@v7
|
||||
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
|
||||
|
@ -34,7 +34,7 @@ jobs:
|
|||
|
||||
- name: Build Native GCC x86
|
||||
id: build-native-gcc-x86
|
||||
uses: Joshua-Ashton/arch-mingw-github-action@v7
|
||||
uses: Joshua-Ashton/arch-mingw-github-action@v8
|
||||
with:
|
||||
command: |
|
||||
export CC="gcc -m32"
|
||||
|
@ -45,7 +45,7 @@ jobs:
|
|||
|
||||
- name: Build Native GCC x64
|
||||
id: build-native-gcc-x64
|
||||
uses: Joshua-Ashton/arch-mingw-github-action@v7
|
||||
uses: Joshua-Ashton/arch-mingw-github-action@v8
|
||||
with:
|
||||
command: |
|
||||
export CC="gcc"
|
||||
|
@ -55,7 +55,7 @@ jobs:
|
|||
|
||||
- name: Build Native Clang x86
|
||||
id: build-native-clang-x86
|
||||
uses: Joshua-Ashton/arch-mingw-github-action@v7
|
||||
uses: Joshua-Ashton/arch-mingw-github-action@v8
|
||||
with:
|
||||
command: |
|
||||
export CC="clang -m32"
|
||||
|
@ -66,7 +66,7 @@ jobs:
|
|||
|
||||
- name: Build Native Clang x64
|
||||
id: build-native-clang-x64
|
||||
uses: Joshua-Ashton/arch-mingw-github-action@v7
|
||||
uses: Joshua-Ashton/arch-mingw-github-action@v8
|
||||
with:
|
||||
command: |
|
||||
export CC="clang"
|
||||
|
|
66
README.md
66
README.md
|
@ -29,6 +29,7 @@ There are some hard requirements on drivers to be able to implement D3D12 in a r
|
|||
- `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.
|
||||
These extensions will likely become mandatory later.
|
||||
|
@ -41,20 +42,16 @@ These extensions will likely become mandatory later.
|
|||
### AMD (RADV)
|
||||
|
||||
For AMD, RADV is the recommended driver and the one that sees most testing on AMD GPUs.
|
||||
The recommendation here is to use a driver built from Git.
|
||||
The minimum requirement at the moment is Mesa 22.0 since it supports `VK_KHR_dynamic_rendering`.
|
||||
|
||||
NOTE: For older Mesa versions, use the v2.6 release.
|
||||
|
||||
### NVIDIA
|
||||
|
||||
The [Vulkan beta drivers](https://developer.nvidia.com/vulkan-driver) generally contain the latest
|
||||
driver fixes that we identify while getting games to work.
|
||||
At least Linux 455.26.01 (2020-10-20) is recommended as it contains fixes for:
|
||||
|
||||
> 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.
|
||||
The latest drivers (stable, beta or Vulkan beta tracks) are always preferred.
|
||||
If you're having problems, always try the latest drivers.
|
||||
|
||||
### Intel
|
||||
|
||||
|
@ -188,6 +185,39 @@ commas or semicolons.
|
|||
- `VKD3D_PROFILE_PATH` - If profiling is enabled in the build, a profiling block is
|
||||
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)
|
||||
|
||||
Pass `-Denable_profiling=true` to Meson to enable a profiled build. With a profiled build, use `VKD3D_PROFILE_PATH` environment variable.
|
||||
|
@ -218,6 +248,17 @@ pass `-Denable_renderdoc=true` to Meson.
|
|||
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.
|
||||
|
||||
### 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
|
||||
|
||||
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.
|
||||
|
@ -229,8 +270,11 @@ 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.
|
||||
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`.
|
||||
Use `glslc -I/path/to/vkd3d-proton/include/shader-debug --target-env=vulkan1.1` when compiling replaced shaders.
|
||||
```
|
||||
# Inside folder full of override shaders, build everything with:
|
||||
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);
|
||||
|
|
|
@ -456,13 +456,8 @@ static void cxg_mesh_create(ID3D12Device *device, float inner_radius, float oute
|
|||
float r0, r1, r2;
|
||||
float angle, da;
|
||||
|
||||
if (!(vertices = calloc(tooth_count, 12 * sizeof(*vertices))))
|
||||
return;
|
||||
if (!(faces = calloc(tooth_count, 20 * sizeof(*faces))))
|
||||
{
|
||||
free(vertices);
|
||||
return;
|
||||
}
|
||||
vertices = calloc(tooth_count, 12 * sizeof(*vertices));
|
||||
faces = calloc(tooth_count, 20 * sizeof(*faces));
|
||||
|
||||
r0 = inner_radius;
|
||||
r1 = outer_radius - tooth_depth / 2.0f;
|
||||
|
|
|
@ -27,9 +27,12 @@
|
|||
#include <stdint.h>
|
||||
#include <limits.h>
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <intrin.h>
|
||||
#else
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
#ifndef ARRAY_SIZE
|
||||
|
@ -44,11 +47,13 @@
|
|||
|
||||
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)
|
||||
{
|
||||
assert(alignment > 0 && (alignment & (alignment - 1)) == 0);
|
||||
return (addr + (alignment - 1)) & ~(alignment - 1);
|
||||
}
|
||||
|
||||
|
@ -118,8 +123,7 @@ static inline unsigned int vkd3d_bitmask_tzcnt32(uint32_t mask)
|
|||
{
|
||||
#ifdef _MSC_VER
|
||||
unsigned long result;
|
||||
_BitScanForward(&result, mask) ? result : 32;
|
||||
return result;
|
||||
return _BitScanForward(&result, mask) ? result : 32;
|
||||
#elif defined(__GNUC__) || defined(__clang__)
|
||||
return mask ? __builtin_ctz(mask) : 32;
|
||||
#else
|
||||
|
@ -290,4 +294,36 @@ static inline void *void_ptr_offset(void *ptr, size_t offset)
|
|||
#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 */
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* 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,6 +23,7 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "vkd3d_common.h"
|
||||
#include "vkd3d_debug.h"
|
||||
|
||||
static inline void *vkd3d_malloc(size_t size)
|
||||
|
@ -57,12 +58,12 @@ static inline void vkd3d_free(void *ptr)
|
|||
bool vkd3d_array_reserve(void **elements, size_t *capacity,
|
||||
size_t element_count, size_t element_size);
|
||||
|
||||
static inline void *vkd3d_malloc_aligned(size_t size, size_t align)
|
||||
static inline void *vkd3d_malloc_aligned(size_t size, size_t alignment)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return _aligned_malloc(size, align);
|
||||
return _aligned_malloc(size, alignment);
|
||||
#else
|
||||
return aligned_alloc(align, size);
|
||||
return aligned_alloc(alignment, align(size, alignment));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,8 @@ int vkd3d_dlclose(vkd3d_module_t handle);
|
|||
|
||||
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]);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -21,39 +21,15 @@
|
|||
|
||||
#include "vkd3d_windows.h"
|
||||
#include "vkd3d_spinlock.h"
|
||||
#include <stdint.h>
|
||||
#include "vkd3d_common.h"
|
||||
|
||||
#ifdef VKD3D_ENABLE_PROFILING
|
||||
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
void vkd3d_init_profiling(void);
|
||||
bool vkd3d_uses_profiling(void);
|
||||
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);
|
||||
|
||||
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) \
|
||||
static uint32_t _vkd3d_region_latch_##name; \
|
||||
static spinlock_t _vkd3d_region_lock_##name; \
|
||||
|
@ -65,12 +41,12 @@ static inline uint64_t vkd3d_profiling_get_tick_count(void)
|
|||
do { \
|
||||
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_begin_tick_##name = vkd3d_profiling_get_tick_count(); \
|
||||
_vkd3d_region_begin_tick_##name = vkd3d_get_current_time_ticks(); \
|
||||
} while(0)
|
||||
|
||||
#define VKD3D_REGION_END_ITERATIONS(name, iter) \
|
||||
do { \
|
||||
_vkd3d_region_end_tick_##name = vkd3d_profiling_get_tick_count(); \
|
||||
_vkd3d_region_end_tick_##name = vkd3d_get_current_time_ticks(); \
|
||||
vkd3d_profiling_notify_work(_vkd3d_region_index_##name, _vkd3d_region_begin_tick_##name, _vkd3d_region_end_tick_##name, iter); \
|
||||
} while(0)
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ 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);
|
||||
|
|
|
@ -6,6 +6,12 @@ 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) \
|
||||
|
@ -13,25 +19,49 @@ SPV_OBJECTS := \
|
|||
$(COMP_SOURCES:.comp=.spv) \
|
||||
$(TESC_SOURCES:.tesc=.spv) \
|
||||
$(TESE_SOURCES:.tese=.spv) \
|
||||
$(GEOM_SOURCES:.geom=.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 -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 -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 -o $@ $< -I$(INCLUDE_DIR) --target-env=vulkan1.1 $(GLSLC_FLAGS)
|
||||
|
||||
%.spv: %.geom
|
||||
glslc -o $@ $< -I$(INCLUDE_DIR) --target-env=vulkan1.1
|
||||
glslc -o $@ $< -I$(INCLUDE_DIR) --target-env=vulkan1.1 $(GLSLC_FLAGS)
|
||||
|
||||
%.spv: %.tesc
|
||||
glslc -o $@ $< -I$(INCLUDE_DIR) --target-env=vulkan1.1
|
||||
glslc -o $@ $< -I$(INCLUDE_DIR) --target-env=vulkan1.1 $(GLSLC_FLAGS)
|
||||
|
||||
%.spv: %.tese
|
||||
glslc -o $@ $< -I$(INCLUDE_DIR) --target-env=vulkan1.1
|
||||
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)
|
||||
|
||||
|
|
|
@ -97,6 +97,14 @@ void DEBUG_CHANNEL_INIT(uvec3 id)
|
|||
#endif
|
||||
}
|
||||
|
||||
void DEBUG_CHANNEL_INIT_IMPLICIT_INSTANCE(uvec3 id, uint inst)
|
||||
{
|
||||
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();
|
||||
|
|
|
@ -59,36 +59,39 @@
|
|||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
enum vkd3d_config_flags
|
||||
{
|
||||
VKD3D_CONFIG_FLAG_VULKAN_DEBUG = 0x00000001,
|
||||
VKD3D_CONFIG_FLAG_SKIP_APPLICATION_WORKAROUNDS = 0x00000002,
|
||||
VKD3D_CONFIG_FLAG_DEBUG_UTILS = 0x00000004,
|
||||
VKD3D_CONFIG_FLAG_FORCE_STATIC_CBV = 0x00000008,
|
||||
VKD3D_CONFIG_FLAG_DXR = 0x00000010,
|
||||
VKD3D_CONFIG_FLAG_SINGLE_QUEUE = 0x00000020,
|
||||
VKD3D_CONFIG_FLAG_DESCRIPTOR_QA_CHECKS = 0x00000040,
|
||||
VKD3D_CONFIG_FLAG_FORCE_RTV_EXCLUSIVE_QUEUE = 0x00000080,
|
||||
VKD3D_CONFIG_FLAG_FORCE_DSV_EXCLUSIVE_QUEUE = 0x00000100,
|
||||
VKD3D_CONFIG_FLAG_FORCE_MINIMUM_SUBGROUP_SIZE = 0x00000200,
|
||||
VKD3D_CONFIG_FLAG_NO_UPLOAD_HVV = 0x00000400,
|
||||
VKD3D_CONFIG_FLAG_LOG_MEMORY_BUDGET = 0x00000800,
|
||||
VKD3D_CONFIG_FLAG_IGNORE_RTV_HOST_VISIBLE = 0x00001000,
|
||||
VKD3D_CONFIG_FLAG_FORCE_HOST_CACHED = 0x00002000,
|
||||
VKD3D_CONFIG_FLAG_DXR11 = 0x00004000,
|
||||
VKD3D_CONFIG_FLAG_FORCE_NO_INVARIANT_POSITION = 0x00008000,
|
||||
VKD3D_CONFIG_FLAG_WORKAROUND_MISSING_COLOR_COMPUTE_BARRIERS = 0x00010000,
|
||||
VKD3D_CONFIG_FLAG_GLOBAL_PIPELINE_CACHE = 0x00020000,
|
||||
VKD3D_CONFIG_FLAG_PIPELINE_LIBRARY_NO_SERIALIZE_SPIRV = 0x00040000,
|
||||
VKD3D_CONFIG_FLAG_PIPELINE_LIBRARY_SANITIZE_SPIRV = 0x00080000,
|
||||
VKD3D_CONFIG_FLAG_PIPELINE_LIBRARY_LOG = 0x00100000,
|
||||
VKD3D_CONFIG_FLAG_PIPELINE_LIBRARY_IGNORE_SPIRV = 0x00200000,
|
||||
VKD3D_CONFIG_FLAG_MUTABLE_SINGLE_SET = 0x00400000,
|
||||
VKD3D_CONFIG_FLAG_MEMORY_ALLOCATOR_SKIP_CLEAR = 0x00800000,
|
||||
VKD3D_CONFIG_FLAG_RECYCLE_COMMAND_POOLS = 0x01000000,
|
||||
VKD3D_CONFIG_FLAG_PIPELINE_LIBRARY_IGNORE_MISMATCH_DRIVER = 0x02000000,
|
||||
VKD3D_CONFIG_FLAG_BREADCRUMBS = 0x04000000,
|
||||
};
|
||||
#define VKD3D_CONFIG_FLAG_VULKAN_DEBUG (1ull << 0)
|
||||
#define VKD3D_CONFIG_FLAG_SKIP_APPLICATION_WORKAROUNDS (1ull << 1)
|
||||
#define VKD3D_CONFIG_FLAG_DEBUG_UTILS (1ull << 2)
|
||||
#define VKD3D_CONFIG_FLAG_FORCE_STATIC_CBV (1ull << 3)
|
||||
#define VKD3D_CONFIG_FLAG_DXR (1ull << 4)
|
||||
#define VKD3D_CONFIG_FLAG_SINGLE_QUEUE (1ull << 5)
|
||||
#define VKD3D_CONFIG_FLAG_DESCRIPTOR_QA_CHECKS (1ull << 6)
|
||||
#define VKD3D_CONFIG_FLAG_FORCE_RTV_EXCLUSIVE_QUEUE (1ull << 7)
|
||||
#define VKD3D_CONFIG_FLAG_FORCE_DSV_EXCLUSIVE_QUEUE (1ull << 8)
|
||||
#define VKD3D_CONFIG_FLAG_FORCE_MINIMUM_SUBGROUP_SIZE (1ull << 9)
|
||||
#define VKD3D_CONFIG_FLAG_NO_UPLOAD_HVV (1ull << 10)
|
||||
#define VKD3D_CONFIG_FLAG_LOG_MEMORY_BUDGET (1ull << 11)
|
||||
#define VKD3D_CONFIG_FLAG_IGNORE_RTV_HOST_VISIBLE (1ull << 12)
|
||||
#define VKD3D_CONFIG_FLAG_FORCE_HOST_CACHED (1ull << 13)
|
||||
#define VKD3D_CONFIG_FLAG_DXR11 (1ull << 14)
|
||||
#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);
|
||||
|
||||
|
|
|
@ -3644,8 +3644,8 @@ interface ID3D12CommandQueue : ID3D12Pageable
|
|||
ID3D12Heap *heap,
|
||||
UINT range_count,
|
||||
const D3D12_TILE_RANGE_FLAGS *range_flags,
|
||||
UINT *heap_range_offsets,
|
||||
UINT *range_tile_counts,
|
||||
const UINT *heap_range_offsets,
|
||||
const UINT *range_tile_counts,
|
||||
D3D12_TILE_MAPPING_FLAGS flags);
|
||||
|
||||
void CopyTileMappings(ID3D12Resource *dst_resource,
|
||||
|
|
|
@ -241,6 +241,7 @@ struct vkd3d_shader_root_constant
|
|||
struct vkd3d_shader_root_descriptor
|
||||
{
|
||||
struct vkd3d_shader_resource_binding *binding;
|
||||
uint32_t raw_va_root_descriptor_index;
|
||||
};
|
||||
|
||||
struct vkd3d_shader_root_parameter
|
||||
|
@ -308,6 +309,9 @@ enum vkd3d_shader_target_extension
|
|||
* 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
|
||||
|
@ -656,6 +660,7 @@ struct vkd3d_shader_scan_info
|
|||
bool has_side_effects;
|
||||
bool needs_late_zs;
|
||||
bool discards;
|
||||
bool has_uav_counter;
|
||||
unsigned int patch_vertex_count;
|
||||
};
|
||||
|
||||
|
@ -749,7 +754,11 @@ int vkd3d_shader_compile_dxbc(const struct vkd3d_shader_code *dxbc,
|
|||
void vkd3d_shader_free_shader_code(struct vkd3d_shader_code *code);
|
||||
|
||||
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);
|
||||
|
||||
/* FIXME: Add support for returning error messages (ID3DBlob). */
|
||||
|
@ -775,19 +784,65 @@ void vkd3d_shader_free_shader_signature(struct vkd3d_shader_signature *signature
|
|||
struct vkd3d_shader_library_entry_point
|
||||
{
|
||||
unsigned int identifier;
|
||||
VkShaderStageFlagBits stage;
|
||||
WCHAR *mangled_entry_point;
|
||||
WCHAR *plain_entry_point;
|
||||
char *real_entry_point;
|
||||
VkShaderStageFlagBits stage;
|
||||
};
|
||||
|
||||
int vkd3d_shader_dxil_append_library_entry_points(
|
||||
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);
|
||||
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,
|
||||
|
@ -813,7 +868,8 @@ 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 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 int (*PFN_vkd3d_shader_serialize_root_signature)(
|
||||
|
|
|
@ -88,6 +88,9 @@ typedef void *HANDLE;
|
|||
|
||||
typedef const WCHAR* LPCWSTR;
|
||||
|
||||
#define _fseeki64(a, b, c) fseeko64(a, b, c)
|
||||
#define _ftelli64(a) ftello64(a)
|
||||
|
||||
/* GUID */
|
||||
# ifdef __WIDL__
|
||||
typedef struct
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#include "vkd3d_debug.h"
|
||||
#include "vkd3d_threads.h"
|
||||
|
||||
#include "vkd3d_platform.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
|
@ -58,13 +60,13 @@ static FILE *vkd3d_log_file;
|
|||
|
||||
static void vkd3d_dbg_init_once(void)
|
||||
{
|
||||
const char *vkd3d_debug;
|
||||
char vkd3d_debug[VKD3D_PATH_MAX];
|
||||
unsigned int channel, i;
|
||||
|
||||
for (channel = 0; channel < VKD3D_DBG_CHANNEL_COUNT; channel++)
|
||||
{
|
||||
if (!(vkd3d_debug = getenv(env_for_channel[channel])))
|
||||
vkd3d_debug = "";
|
||||
if (!vkd3d_get_env_var(env_for_channel[channel], vkd3d_debug, sizeof(vkd3d_debug)))
|
||||
strncpy(vkd3d_debug, "", VKD3D_PATH_MAX);
|
||||
|
||||
for (i = 1; i < ARRAY_SIZE(debug_level_names); ++i)
|
||||
if (!strcmp(debug_level_names[i], vkd3d_debug))
|
||||
|
@ -75,7 +77,7 @@ static void vkd3d_dbg_init_once(void)
|
|||
vkd3d_dbg_level[channel] = VKD3D_DBG_LEVEL_FIXME;
|
||||
}
|
||||
|
||||
if ((vkd3d_debug = getenv("VKD3D_LOG_FILE")))
|
||||
if (vkd3d_get_env_var("VKD3D_LOG_FILE", vkd3d_debug, sizeof(vkd3d_debug)))
|
||||
{
|
||||
vkd3d_log_file = fopen(vkd3d_debug, "w");
|
||||
if (!vkd3d_log_file)
|
||||
|
@ -281,11 +283,11 @@ const char *debugstr_w(const WCHAR *wstr)
|
|||
|
||||
unsigned int vkd3d_env_var_as_uint(const char *name, unsigned int default_value)
|
||||
{
|
||||
const char *value = getenv(name);
|
||||
char value[VKD3D_PATH_MAX];
|
||||
unsigned long r;
|
||||
char *end_ptr;
|
||||
|
||||
if (value)
|
||||
if (vkd3d_get_env_var(name, value, sizeof(value)) && strlen(value) > 0)
|
||||
{
|
||||
errno = 0;
|
||||
r = strtoul(value, &end_ptr, 0);
|
||||
|
|
|
@ -0,0 +1,188 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
|
@ -4,6 +4,8 @@ vkd3d_common_src = [
|
|||
'utf8.c',
|
||||
'profiling.c',
|
||||
'string.c',
|
||||
'file_utils.c',
|
||||
'platform.c',
|
||||
]
|
||||
|
||||
vkd3d_common_lib = static_library('vkd3d_common', vkd3d_common_src, vkd3d_header_files,
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
|
||||
#include "vkd3d_platform.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined(__linux__)
|
||||
|
||||
# include <dlfcn.h>
|
||||
|
@ -153,3 +156,43 @@ bool vkd3d_get_program_name(char program_name[VKD3D_PATH_MAX])
|
|||
}
|
||||
|
||||
#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
|
|
@ -21,6 +21,7 @@
|
|||
#define VKD3D_DBG_CHANNEL VKD3D_DBG_CHANNEL_API
|
||||
|
||||
#include "vkd3d_profiling.h"
|
||||
#include "vkd3d_platform.h"
|
||||
#include "vkd3d_threads.h"
|
||||
#include "vkd3d_debug.h"
|
||||
#include <stdlib.h>
|
||||
|
@ -124,8 +125,10 @@ static void vkd3d_init_profiling_path(const char *path)
|
|||
|
||||
static void vkd3d_init_profiling_once(void)
|
||||
{
|
||||
const char *path = getenv("VKD3D_PROFILE_PATH");
|
||||
if (path)
|
||||
char path[VKD3D_PATH_MAX];
|
||||
|
||||
vkd3d_get_env_var("VKD3D_PROFILE_PATH", path, sizeof(path));
|
||||
if (strlen(path) > 0)
|
||||
vkd3d_init_profiling_path(path);
|
||||
}
|
||||
|
||||
|
|
|
@ -82,6 +82,21 @@ bool vkd3d_export_strequal(const WCHAR *a, const WCHAR *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;
|
||||
|
|
|
@ -2755,8 +2755,9 @@ static int shader_parse_static_samplers(struct root_signature_parser_context *co
|
|||
return VKD3D_OK;
|
||||
}
|
||||
|
||||
static int shader_parse_root_signature(const char *data, unsigned int data_size,
|
||||
struct vkd3d_versioned_root_signature_desc *desc)
|
||||
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)
|
||||
{
|
||||
struct vkd3d_root_signature_desc *v_1_0 = &desc->v_1_0;
|
||||
struct root_signature_parser_context context;
|
||||
|
@ -2764,6 +2765,8 @@ static int shader_parse_root_signature(const char *data, unsigned int data_size,
|
|||
const char *ptr = data;
|
||||
int ret;
|
||||
|
||||
memset(desc, 0, sizeof(*desc));
|
||||
|
||||
context.data = data;
|
||||
context.data_size = data_size;
|
||||
|
||||
|
@ -2835,28 +2838,46 @@ static int shader_parse_root_signature(const char *data, unsigned int data_size,
|
|||
read_uint32(&ptr, &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;
|
||||
}
|
||||
|
||||
static int rts0_handler(const char *data, DWORD data_size, DWORD tag, void *context)
|
||||
{
|
||||
struct vkd3d_versioned_root_signature_desc *desc = context;
|
||||
struct vkd3d_shader_code *payload = context;
|
||||
|
||||
if (tag != TAG_RTS0)
|
||||
return VKD3D_OK;
|
||||
|
||||
return shader_parse_root_signature(data, data_size, desc);
|
||||
payload->code = data;
|
||||
payload->size = data_size;
|
||||
return VKD3D_OK;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
TRACE("dxbc {%p, %zu}, root_signature %p.\n", dxbc->code, dxbc->size, root_signature);
|
||||
|
||||
memset(root_signature, 0, sizeof(*root_signature));
|
||||
if ((ret = parse_dxbc(dxbc->code, dxbc->size, rts0_handler, root_signature)) < 0)
|
||||
memset(&raw_payload, 0, sizeof(raw_payload));
|
||||
|
||||
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);
|
||||
return ret;
|
||||
|
|
|
@ -764,6 +764,30 @@ int vkd3d_shader_compile_dxil(const struct vkd3d_shader_code *dxbc,
|
|||
goto end;
|
||||
}
|
||||
}
|
||||
else if (compiler_args->target_extensions[i] == VKD3D_SHADER_TARGET_EXTENSION_BARYCENTRIC_KHR)
|
||||
{
|
||||
static const dxil_spv_option_barycentric_khr helper =
|
||||
{ { DXIL_SPV_OPTION_BARYCENTRIC_KHR }, DXIL_SPV_TRUE };
|
||||
|
||||
if (dxil_spv_converter_add_option(converter, &helper.base) != DXIL_SPV_SUCCESS)
|
||||
{
|
||||
ERR("dxil-spirv does not support BARYCENTRIC_KHR.\n");
|
||||
ret = VKD3D_ERROR_NOT_IMPLEMENTED;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
else if (compiler_args->target_extensions[i] == VKD3D_SHADER_TARGET_EXTENSION_MIN_PRECISION_IS_NATIVE_16BIT)
|
||||
{
|
||||
static const dxil_spv_option_min_precision_native_16bit helper =
|
||||
{ { DXIL_SPV_OPTION_MIN_PRECISION_NATIVE_16BIT }, DXIL_SPV_TRUE };
|
||||
|
||||
if (dxil_spv_converter_add_option(converter, &helper.base) != DXIL_SPV_SUCCESS)
|
||||
{
|
||||
ERR("dxil-spirv does not support MIN_PRECISION_NATIVE_16BIT.\n");
|
||||
ret = VKD3D_ERROR_NOT_IMPLEMENTED;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (compiler_args->dual_source_blending)
|
||||
|
@ -1250,6 +1274,18 @@ int vkd3d_shader_compile_dxil_export(const struct vkd3d_shader_code *dxil,
|
|||
goto end;
|
||||
}
|
||||
}
|
||||
else if (compiler_args->target_extensions[i] == VKD3D_SHADER_TARGET_EXTENSION_MIN_PRECISION_IS_NATIVE_16BIT)
|
||||
{
|
||||
static const dxil_spv_option_min_precision_native_16bit helper =
|
||||
{ { DXIL_SPV_OPTION_MIN_PRECISION_NATIVE_16BIT }, DXIL_SPV_TRUE };
|
||||
|
||||
if (dxil_spv_converter_add_option(converter, &helper.base) != DXIL_SPV_SUCCESS)
|
||||
{
|
||||
ERR("dxil-spirv does not support MIN_PRECISION_NATIVE_16BIT.\n");
|
||||
ret = VKD3D_ERROR_NOT_IMPLEMENTED;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1316,6 +1352,31 @@ void vkd3d_shader_dxil_free_library_entry_points(struct vkd3d_shader_library_ent
|
|||
vkd3d_free(entry_points);
|
||||
}
|
||||
|
||||
void vkd3d_shader_dxil_free_library_subobjects(struct vkd3d_shader_library_subobject *subobjects, size_t count)
|
||||
{
|
||||
size_t i, j;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
if (subobjects[i].kind == VKD3D_SHADER_SUBOBJECT_KIND_SUBOBJECT_TO_EXPORTS_ASSOCIATION)
|
||||
{
|
||||
for (j = 0; j < subobjects[i].data.association.NumExports; j++)
|
||||
vkd3d_free((void*)subobjects[i].data.association.pExports[j]);
|
||||
vkd3d_free((void*)subobjects[i].data.association.pExports);
|
||||
vkd3d_free((void*)subobjects[i].data.association.SubobjectToAssociate);
|
||||
}
|
||||
else if (subobjects[i].kind == VKD3D_SHADER_SUBOBJECT_KIND_HIT_GROUP)
|
||||
{
|
||||
vkd3d_free((void*)subobjects[i].data.hit_group.HitGroupExport);
|
||||
vkd3d_free((void*)subobjects[i].data.hit_group.AnyHitShaderImport);
|
||||
vkd3d_free((void*)subobjects[i].data.hit_group.ClosestHitShaderImport);
|
||||
vkd3d_free((void*)subobjects[i].data.hit_group.IntersectionShaderImport);
|
||||
}
|
||||
}
|
||||
|
||||
vkd3d_free(subobjects);
|
||||
}
|
||||
|
||||
static VkShaderStageFlagBits convert_stage(dxil_spv_shader_stage stage)
|
||||
{
|
||||
/* Only interested in RT entry_points. There is no way yet to use lib_6_3+ for non-RT. */
|
||||
|
@ -1360,20 +1421,95 @@ static bool vkd3d_dxil_build_entry(struct vkd3d_shader_library_entry_point *entr
|
|||
return true;
|
||||
}
|
||||
|
||||
int vkd3d_shader_dxil_append_library_entry_points(
|
||||
static void vkd3d_shader_dxil_copy_subobject(unsigned int identifier,
|
||||
struct vkd3d_shader_library_subobject *subobject,
|
||||
const dxil_spv_rdat_subobject *dxil_subobject)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
/* Reuse same enums as DXIL. */
|
||||
subobject->kind = (enum vkd3d_shader_subobject_kind)dxil_subobject->kind;
|
||||
subobject->name = dxil_subobject->subobject_name;
|
||||
subobject->dxil_identifier = identifier;
|
||||
|
||||
switch (dxil_subobject->kind)
|
||||
{
|
||||
case DXIL_SPV_RDAT_SUBOBJECT_KIND_GLOBAL_ROOT_SIGNATURE:
|
||||
case DXIL_SPV_RDAT_SUBOBJECT_KIND_LOCAL_ROOT_SIGNATURE:
|
||||
subobject->data.payload.data = dxil_subobject->payload;
|
||||
subobject->data.payload.size = dxil_subobject->payload_size;
|
||||
break;
|
||||
|
||||
case DXIL_SPV_RDAT_SUBOBJECT_KIND_RAYTRACING_PIPELINE_CONFIG:
|
||||
/* Normalize the kind. */
|
||||
subobject->kind = VKD3D_SHADER_SUBOBJECT_KIND_RAYTRACING_PIPELINE_CONFIG1;
|
||||
subobject->data.pipeline_config.MaxTraceRecursionDepth = dxil_subobject->args[0];
|
||||
subobject->data.pipeline_config.Flags = 0;
|
||||
break;
|
||||
|
||||
case DXIL_SPV_RDAT_SUBOBJECT_KIND_RAYTRACING_PIPELINE_CONFIG1:
|
||||
subobject->kind = VKD3D_SHADER_SUBOBJECT_KIND_RAYTRACING_PIPELINE_CONFIG1;
|
||||
subobject->data.pipeline_config.MaxTraceRecursionDepth = dxil_subobject->args[0];
|
||||
subobject->data.pipeline_config.Flags = dxil_subobject->args[1];
|
||||
break;
|
||||
|
||||
case DXIL_SPV_RDAT_SUBOBJECT_KIND_RAYTRACING_SHADER_CONFIG:
|
||||
subobject->data.shader_config.MaxPayloadSizeInBytes = dxil_subobject->args[0];
|
||||
subobject->data.shader_config.MaxAttributeSizeInBytes = dxil_subobject->args[1];
|
||||
break;
|
||||
|
||||
case DXIL_SPV_RDAT_SUBOBJECT_KIND_HIT_GROUP:
|
||||
/* Enum aliases. */
|
||||
subobject->data.hit_group.Type = (D3D12_HIT_GROUP_TYPE)dxil_subobject->hit_group_type;
|
||||
assert(dxil_subobject->num_exports == 3);
|
||||
/* Implementation simplifies a lot if we can reuse the D3D12 type here. */
|
||||
subobject->data.hit_group.HitGroupExport = vkd3d_dup_entry_point(dxil_subobject->subobject_name);
|
||||
subobject->data.hit_group.AnyHitShaderImport = dxil_subobject->exports[0] && *dxil_subobject->exports[0] != '\0' ?
|
||||
vkd3d_dup_entry_point(dxil_subobject->exports[0]) : NULL;
|
||||
subobject->data.hit_group.ClosestHitShaderImport = dxil_subobject->exports[1] && *dxil_subobject->exports[1] != '\0' ?
|
||||
vkd3d_dup_entry_point(dxil_subobject->exports[1]) : NULL;
|
||||
subobject->data.hit_group.IntersectionShaderImport = dxil_subobject->exports[2] && *dxil_subobject->exports[2] != '\0' ?
|
||||
vkd3d_dup_entry_point(dxil_subobject->exports[2]) : NULL;
|
||||
break;
|
||||
|
||||
case DXIL_SPV_RDAT_SUBOBJECT_KIND_STATE_OBJECT_CONFIG:
|
||||
subobject->data.object_config.Flags = dxil_subobject->args[0];
|
||||
break;
|
||||
|
||||
case DXIL_SPV_RDAT_SUBOBJECT_KIND_SUBOBJECT_TO_EXPORTS_ASSOCIATION:
|
||||
assert(dxil_subobject->num_exports >= 1);
|
||||
subobject->data.association.SubobjectToAssociate = vkd3d_dup_entry_point(dxil_subobject->exports[0]);
|
||||
subobject->data.association.pExports = vkd3d_malloc((dxil_subobject->num_exports - 1) * sizeof(LPCWSTR));
|
||||
subobject->data.association.NumExports = dxil_subobject->num_exports - 1;
|
||||
for (i = 1; i < dxil_subobject->num_exports; i++)
|
||||
subobject->data.association.pExports[i - 1] = vkd3d_dup_entry_point(dxil_subobject->exports[i]);
|
||||
break;
|
||||
|
||||
default:
|
||||
FIXME("Unrecognized RDAT subobject type: %u.\n", dxil_subobject->kind);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
size_t *entry_point_size, size_t *entry_point_count,
|
||||
struct vkd3d_shader_library_subobject **subobjects,
|
||||
size_t *subobjects_size, size_t *subobjects_count)
|
||||
{
|
||||
struct vkd3d_shader_library_entry_point new_entry;
|
||||
struct vkd3d_shader_library_subobject *subobject;
|
||||
dxil_spv_parsed_blob blob = NULL;
|
||||
struct vkd3d_shader_code code;
|
||||
dxil_spv_rdat_subobject sub;
|
||||
dxil_spv_shader_stage stage;
|
||||
const char *mangled_entry;
|
||||
char *ascii_entry = NULL;
|
||||
vkd3d_shader_hash_t hash;
|
||||
unsigned int count, i;
|
||||
unsigned int count, i, j;
|
||||
unsigned int rdat_count;
|
||||
int ret = VKD3D_OK;
|
||||
|
||||
memset(&new_entry, 0, sizeof(new_entry));
|
||||
|
@ -1394,6 +1530,8 @@ int vkd3d_shader_dxil_append_library_entry_points(
|
|||
goto end;
|
||||
}
|
||||
|
||||
rdat_count = dxil_spv_parsed_blob_get_num_rdat_subobjects(blob);
|
||||
|
||||
if (library_desc->NumExports)
|
||||
{
|
||||
for (i = 0; i < library_desc->NumExports; i++)
|
||||
|
@ -1403,24 +1541,44 @@ int vkd3d_shader_dxil_append_library_entry_points(
|
|||
else
|
||||
ascii_entry = vkd3d_strdup_w_utf8(library_desc->pExports[i].Name, 0);
|
||||
|
||||
stage = dxil_spv_parsed_blob_get_shader_stage_for_entry(blob, ascii_entry);
|
||||
if (stage == DXIL_SPV_STAGE_UNKNOWN)
|
||||
/* An export can point to a subobject or an entry point. */
|
||||
for (j = 0; j < rdat_count; j++)
|
||||
{
|
||||
ret = VKD3D_ERROR_INVALID_ARGUMENT;
|
||||
goto end;
|
||||
dxil_spv_parsed_blob_get_rdat_subobject(blob, j, &sub);
|
||||
/* Subobject names are not mangled. */
|
||||
if (strcmp(sub.subobject_name, ascii_entry) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
new_entry.real_entry_point = ascii_entry;
|
||||
new_entry.plain_entry_point = vkd3d_wstrdup(library_desc->pExports[i].Name);
|
||||
new_entry.mangled_entry_point = NULL;
|
||||
new_entry.identifier = identifier;
|
||||
new_entry.stage = convert_stage(stage);
|
||||
ascii_entry = NULL;
|
||||
if (j < rdat_count)
|
||||
{
|
||||
vkd3d_array_reserve((void**)subobjects, subobjects_size,
|
||||
*subobjects_count + 1, sizeof(**subobjects));
|
||||
subobject = &(*subobjects)[*subobjects_count];
|
||||
vkd3d_shader_dxil_copy_subobject(identifier, subobject, &sub);
|
||||
*subobjects_count += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
stage = dxil_spv_parsed_blob_get_shader_stage_for_entry(blob, ascii_entry);
|
||||
if (stage == DXIL_SPV_STAGE_UNKNOWN)
|
||||
{
|
||||
ret = VKD3D_ERROR_INVALID_ARGUMENT;
|
||||
goto end;
|
||||
}
|
||||
|
||||
vkd3d_array_reserve((void**)entry_points, entry_point_size,
|
||||
*entry_point_count + 1, sizeof(new_entry));
|
||||
(*entry_points)[(*entry_point_count)++] = new_entry;
|
||||
memset(&new_entry, 0, sizeof(new_entry));
|
||||
new_entry.real_entry_point = ascii_entry;
|
||||
new_entry.plain_entry_point = vkd3d_wstrdup(library_desc->pExports[i].Name);
|
||||
new_entry.mangled_entry_point = NULL;
|
||||
new_entry.identifier = identifier;
|
||||
new_entry.stage = convert_stage(stage);
|
||||
ascii_entry = NULL;
|
||||
|
||||
vkd3d_array_reserve((void**)entry_points, entry_point_size,
|
||||
*entry_point_count + 1, sizeof(new_entry));
|
||||
(*entry_points)[(*entry_point_count)++] = new_entry;
|
||||
memset(&new_entry, 0, sizeof(new_entry));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1453,6 +1611,21 @@ int vkd3d_shader_dxil_append_library_entry_points(
|
|||
(*entry_points)[(*entry_point_count)++] = new_entry;
|
||||
memset(&new_entry, 0, sizeof(new_entry));
|
||||
}
|
||||
|
||||
if (rdat_count)
|
||||
{
|
||||
/* All subobjects are also exported. */
|
||||
vkd3d_array_reserve((void**)subobjects, subobjects_size,
|
||||
*subobjects_count + rdat_count, sizeof(**subobjects));
|
||||
|
||||
for (i = 0; i < rdat_count; i++)
|
||||
{
|
||||
dxil_spv_parsed_blob_get_rdat_subobject(blob, i, &sub);
|
||||
subobject = &(*subobjects)[*subobjects_count];
|
||||
vkd3d_shader_dxil_copy_subobject(identifier, subobject, &sub);
|
||||
*subobjects_count += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
|
|
|
@ -1404,6 +1404,13 @@ static uint32_t vkd3d_spirv_build_op_logical_and(struct vkd3d_spirv_builder *bui
|
|||
SpvOpLogicalAnd, result_type, operand0, operand1);
|
||||
}
|
||||
|
||||
static uint32_t vkd3d_spirv_build_op_any(struct vkd3d_spirv_builder *builder,
|
||||
uint32_t result_type, uint32_t operand0)
|
||||
{
|
||||
return vkd3d_spirv_build_op_tr1(builder, &builder->function_stream,
|
||||
SpvOpAny, result_type, operand0);
|
||||
}
|
||||
|
||||
static uint32_t vkd3d_spirv_build_op_iequal(struct vkd3d_spirv_builder *builder,
|
||||
uint32_t result_type, uint32_t operand0, uint32_t operand1)
|
||||
{
|
||||
|
@ -1931,12 +1938,12 @@ vkd3d_spirv_resource_type_table[] =
|
|||
{VKD3D_SHADER_RESOURCE_TEXTURE_2DMS, SpvDim2D, 0, 1, 2, 2},
|
||||
{VKD3D_SHADER_RESOURCE_TEXTURE_2D, SpvDim2D, 0, 0, 2, 2},
|
||||
{VKD3D_SHADER_RESOURCE_TEXTURE_3D, SpvDim3D, 0, 0, 3, 3},
|
||||
{VKD3D_SHADER_RESOURCE_TEXTURE_CUBE, SpvDimCube, 0, 0, 3, 0},
|
||||
{VKD3D_SHADER_RESOURCE_TEXTURE_CUBE, SpvDimCube, 0, 0, 3, 3},
|
||||
{VKD3D_SHADER_RESOURCE_TEXTURE_1DARRAY, SpvDim1D, 1, 0, 2, 1,
|
||||
SpvCapabilitySampled1D, SpvCapabilityImage1D},
|
||||
{VKD3D_SHADER_RESOURCE_TEXTURE_2DARRAY, SpvDim2D, 1, 0, 3, 2},
|
||||
{VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY, SpvDim2D, 1, 1, 3, 2},
|
||||
{VKD3D_SHADER_RESOURCE_TEXTURE_CUBEARRAY, SpvDimCube, 1, 0, 4, 0,
|
||||
{VKD3D_SHADER_RESOURCE_TEXTURE_CUBEARRAY, SpvDimCube, 1, 0, 4, 3,
|
||||
SpvCapabilitySampledCubeArray, SpvCapabilityImageCubeArray},
|
||||
};
|
||||
|
||||
|
@ -2323,6 +2330,8 @@ struct vkd3d_dxbc_compiler
|
|||
vkd3d_shader_hash_t descriptor_qa_shader_hash;
|
||||
#endif
|
||||
|
||||
uint32_t robust_physical_counter_func_id;
|
||||
|
||||
int compiler_error;
|
||||
};
|
||||
|
||||
|
@ -3512,8 +3521,17 @@ static uint32_t vkd3d_dxbc_compiler_emit_load_constant_buffer(struct vkd3d_dxbc_
|
|||
}
|
||||
}
|
||||
|
||||
ptr_id = vkd3d_spirv_build_op_access_chain(builder, ptr_type_id,
|
||||
base_id, indexes, last_index + 1);
|
||||
if (access_mask == SpvMemoryAccessAlignedMask)
|
||||
{
|
||||
/* For physical pointers, prefer InBounds for optimal codegen. */
|
||||
ptr_id = vkd3d_spirv_build_op_in_bounds_access_chain(builder, ptr_type_id,
|
||||
base_id, indexes, last_index + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr_id = vkd3d_spirv_build_op_access_chain(builder, ptr_type_id,
|
||||
base_id, indexes, last_index + 1);
|
||||
}
|
||||
|
||||
if (reg->modifier == VKD3DSPRM_NONUNIFORM)
|
||||
vkd3d_dxbc_compiler_decorate_nonuniform(compiler, ptr_id);
|
||||
|
@ -5513,31 +5531,22 @@ static const struct vkd3d_shader_global_binding *vkd3d_dxbc_compiler_get_global_
|
|||
{
|
||||
if (binding->flags & VKD3D_SHADER_BINDING_FLAG_RAW_VA)
|
||||
{
|
||||
uint32_t counter_struct_id, pointer_struct_id, array_type_id;
|
||||
|
||||
counter_struct_id = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_UINT, 1);
|
||||
counter_struct_id = vkd3d_spirv_build_op_type_struct(builder, &counter_struct_id, 1);
|
||||
|
||||
vkd3d_spirv_build_op_member_decorate1(builder, counter_struct_id, 0, SpvDecorationOffset, 0);
|
||||
vkd3d_spirv_build_op_decorate(builder, counter_struct_id, SpvDecorationBlock, NULL, 0);
|
||||
vkd3d_spirv_build_op_name(builder, counter_struct_id, "uav_ctr_t");
|
||||
|
||||
type_id = vkd3d_spirv_build_op_type_pointer(builder, SpvStorageClassPhysicalStorageBuffer, counter_struct_id);
|
||||
uint32_t struct_id, array_type_id;
|
||||
|
||||
type_id = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_UINT, 2);
|
||||
array_type_id = vkd3d_spirv_build_op_type_runtime_array(builder, type_id);
|
||||
vkd3d_spirv_build_op_decorate1(builder, array_type_id, SpvDecorationArrayStride, sizeof(uint64_t));
|
||||
struct_id = vkd3d_spirv_build_op_type_struct(builder, &array_type_id, 1);
|
||||
|
||||
pointer_struct_id = vkd3d_spirv_build_op_type_struct(builder, &array_type_id, 1);
|
||||
|
||||
vkd3d_spirv_build_op_member_decorate1(builder, pointer_struct_id, 0, SpvDecorationOffset, 0);
|
||||
vkd3d_spirv_build_op_decorate(builder, pointer_struct_id, SpvDecorationBufferBlock, NULL, 0);
|
||||
vkd3d_spirv_build_op_name(builder, pointer_struct_id, "uav_ctrs_t");
|
||||
vkd3d_spirv_build_op_member_decorate1(builder, struct_id, 0, SpvDecorationOffset, 0);
|
||||
vkd3d_spirv_build_op_member_decorate(builder, struct_id, 0, SpvDecorationNonWritable, NULL, 0);
|
||||
vkd3d_spirv_build_op_decorate(builder, struct_id, SpvDecorationBufferBlock, NULL, 0);
|
||||
vkd3d_spirv_build_op_name(builder, struct_id, "uav_ctrs_t");
|
||||
|
||||
var_id = vkd3d_spirv_build_op_variable(builder, &builder->global_stream,
|
||||
vkd3d_spirv_get_op_type_pointer(builder, storage_class, pointer_struct_id),
|
||||
vkd3d_spirv_get_op_type_pointer(builder, storage_class, struct_id),
|
||||
storage_class, 0);
|
||||
|
||||
vkd3d_spirv_build_op_decorate(builder, var_id, SpvDecorationAliasedPointer, NULL, 0);
|
||||
vkd3d_spirv_enable_capability(builder, SpvCapabilityPhysicalStorageBufferAddresses);
|
||||
}
|
||||
else
|
||||
|
@ -5710,10 +5719,116 @@ static const struct vkd3d_shader_buffer_reference_type *vkd3d_dxbc_compiler_get_
|
|||
static void vkd3d_dxbc_compiler_emit_descriptor_qa_checks(struct vkd3d_dxbc_compiler *compiler);
|
||||
#endif
|
||||
|
||||
static void vkd3d_dxbc_compiler_emit_robust_physical_counter_func(struct vkd3d_dxbc_compiler *compiler)
|
||||
{
|
||||
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
||||
uint32_t not_equal_vec_id, not_equal_id;
|
||||
uint32_t merge_label_id, body_label_id;
|
||||
uint32_t ptr_type_id, ptr_id;
|
||||
uint32_t parameter_types[3];
|
||||
uint32_t parameter_ids[3];
|
||||
uint32_t phi_arguments[4];
|
||||
uint32_t atomic_args[4];
|
||||
uint32_t func_type_id;
|
||||
uint32_t phi_result_id;
|
||||
uint32_t uvec2_type;
|
||||
uint32_t bvec2_type;
|
||||
uint32_t result_id;
|
||||
uint32_t bool_type;
|
||||
uint32_t u32_type;
|
||||
uint32_t label_id;
|
||||
uint32_t zero_id;
|
||||
unsigned int i;
|
||||
|
||||
bool_type = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_BOOL, 1);
|
||||
bvec2_type = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_BOOL, 2);
|
||||
u32_type = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_UINT, 1);
|
||||
uvec2_type = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_UINT, 2);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(parameter_types); i++)
|
||||
parameter_types[i] = i == 0 ? uvec2_type : u32_type;
|
||||
|
||||
func_type_id = vkd3d_spirv_get_op_type_function(builder, u32_type,
|
||||
parameter_types, ARRAY_SIZE(parameter_types));
|
||||
compiler->robust_physical_counter_func_id = vkd3d_spirv_alloc_id(builder);
|
||||
vkd3d_spirv_build_op_name(builder, compiler->robust_physical_counter_func_id, "robust_physical_counter_op");
|
||||
vkd3d_spirv_build_op_function(builder, u32_type, compiler->robust_physical_counter_func_id,
|
||||
SpvFunctionControlMaskNone, func_type_id);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(parameter_ids); i++)
|
||||
parameter_ids[i] = vkd3d_spirv_build_op_function_parameter(builder, i == 0 ? uvec2_type : u32_type);
|
||||
|
||||
vkd3d_spirv_build_op_name(builder, parameter_ids[0], "bda");
|
||||
vkd3d_spirv_build_op_name(builder, parameter_ids[1], "direction");
|
||||
vkd3d_spirv_build_op_name(builder, parameter_ids[2], "fixup");
|
||||
|
||||
label_id = vkd3d_spirv_alloc_id(builder);
|
||||
merge_label_id = vkd3d_spirv_alloc_id(builder);
|
||||
body_label_id = vkd3d_spirv_alloc_id(builder);
|
||||
zero_id = vkd3d_dxbc_compiler_get_constant_uint_vector(compiler, 0, 2);
|
||||
|
||||
vkd3d_spirv_build_op_label(builder, label_id);
|
||||
not_equal_vec_id = vkd3d_spirv_build_op_inotequal(builder, bvec2_type,
|
||||
parameter_ids[0], zero_id);
|
||||
not_equal_id = vkd3d_spirv_build_op_any(builder, bool_type, not_equal_vec_id);
|
||||
|
||||
vkd3d_spirv_build_op_selection_merge(builder, merge_label_id, SpvSelectionControlMaskNone);
|
||||
vkd3d_spirv_build_op_branch_conditional(builder, not_equal_id, body_label_id, merge_label_id);
|
||||
|
||||
phi_arguments[1] = body_label_id;
|
||||
phi_arguments[2] = vkd3d_dxbc_compiler_get_constant_uint(compiler, 0);
|
||||
phi_arguments[3] = label_id;
|
||||
|
||||
{
|
||||
vkd3d_spirv_build_op_label(builder, body_label_id);
|
||||
ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassPhysicalStorageBuffer, u32_type);
|
||||
ptr_id = vkd3d_spirv_build_op_bitcast(builder, ptr_type_id, parameter_ids[0]);
|
||||
|
||||
atomic_args[0] = ptr_id;
|
||||
atomic_args[1] = vkd3d_dxbc_compiler_get_constant_uint(compiler, SpvScopeDevice);
|
||||
atomic_args[2] = vkd3d_dxbc_compiler_get_constant_uint(compiler, SpvMemoryAccessMaskNone);
|
||||
atomic_args[3] = parameter_ids[1];
|
||||
|
||||
result_id = vkd3d_spirv_build_op_trv(builder, &builder->function_stream,
|
||||
SpvOpAtomicIAdd, u32_type,
|
||||
atomic_args, ARRAY_SIZE(atomic_args));
|
||||
phi_arguments[0] = vkd3d_spirv_build_op_iadd(builder, u32_type,
|
||||
result_id, parameter_ids[2]);
|
||||
|
||||
vkd3d_spirv_build_op_branch(builder, merge_label_id);
|
||||
}
|
||||
|
||||
vkd3d_spirv_build_op_label(builder, merge_label_id);
|
||||
phi_result_id = vkd3d_spirv_build_op_trv(builder, &builder->function_stream,
|
||||
SpvOpPhi, u32_type,
|
||||
phi_arguments, ARRAY_SIZE(phi_arguments));
|
||||
vkd3d_spirv_build_op_return_value(builder, phi_result_id);
|
||||
vkd3d_spirv_build_op_function_end(builder);
|
||||
vkd3d_spirv_enable_capability(builder, SpvCapabilityPhysicalStorageBufferAddresses);
|
||||
}
|
||||
|
||||
static uint32_t vkd3d_dxbc_compiler_emit_robust_physical_counter(struct vkd3d_dxbc_compiler *compiler,
|
||||
uint32_t bda_id, bool increment)
|
||||
{
|
||||
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
||||
uint32_t u32_type;
|
||||
uint32_t args[3];
|
||||
|
||||
u32_type = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_UINT, 1);
|
||||
args[0] = bda_id;
|
||||
args[1] = vkd3d_dxbc_compiler_get_constant_uint(compiler, increment ? 1u : -1u);
|
||||
args[2] = vkd3d_dxbc_compiler_get_constant_uint(compiler, increment ? 0u : -1u);
|
||||
|
||||
return vkd3d_spirv_build_op_function_call(builder, u32_type,
|
||||
compiler->robust_physical_counter_func_id,
|
||||
args, ARRAY_SIZE(args));
|
||||
}
|
||||
|
||||
static void vkd3d_dxbc_compiler_emit_initial_declarations(struct vkd3d_dxbc_compiler *compiler)
|
||||
{
|
||||
const struct vkd3d_shader_transform_feedback_info *xfb_info = compiler->shader_interface.xfb_info;
|
||||
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
||||
unsigned int i;
|
||||
|
||||
switch (compiler->shader_type)
|
||||
{
|
||||
|
@ -5763,6 +5878,19 @@ static void vkd3d_dxbc_compiler_emit_initial_declarations(struct vkd3d_dxbc_comp
|
|||
vkd3d_dxbc_compiler_emit_descriptor_qa_checks(compiler);
|
||||
#endif
|
||||
|
||||
if (compiler->scan_info->has_uav_counter)
|
||||
{
|
||||
/* Check if we're expected to deal with RAW VAs. In this case we will enable BDA. */
|
||||
for (i = 0; i < compiler->shader_interface.binding_count; i++)
|
||||
{
|
||||
if (compiler->shader_interface.bindings[i].flags & VKD3D_SHADER_BINDING_FLAG_RAW_VA)
|
||||
{
|
||||
vkd3d_dxbc_compiler_emit_robust_physical_counter_func(compiler);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (compiler->shader_type != VKD3D_SHADER_TYPE_HULL)
|
||||
{
|
||||
vkd3d_spirv_builder_begin_main_function(builder);
|
||||
|
@ -6434,8 +6562,13 @@ static void vkd3d_dxbc_compiler_emit_dcl_constant_buffer(struct vkd3d_dxbc_compi
|
|||
else if (binding && (binding->flags & VKD3D_SHADER_BINDING_FLAG_RAW_VA))
|
||||
{
|
||||
storage_class = SpvStorageClassPhysicalStorageBuffer;
|
||||
/* Could use cb->size here, but we will use InBounds access chains
|
||||
* which could confuse a compiler if we tried
|
||||
* to access an array out of bounds. Robustness on descriptors depends on the descriptor, not the
|
||||
* declaration, and it's possible to declare a CBV with fewer array elements than you access.
|
||||
* In this case, we pretend to have a 64 KiB descriptor. */
|
||||
type_id = vkd3d_dxbc_compiler_get_buffer_reference_type(compiler,
|
||||
VKD3D_DATA_FLOAT, 4, cb->size, 0)->type_id;
|
||||
VKD3D_DATA_FLOAT, 4, 4 * 1024, 0)->type_id;
|
||||
var_id = compiler->root_parameter_var_id;
|
||||
}
|
||||
else
|
||||
|
@ -9377,9 +9510,9 @@ static void vkd3d_dxbc_compiler_emit_gather4(struct vkd3d_dxbc_compiler *compile
|
|||
unsigned int image_flags = VKD3D_IMAGE_FLAG_SAMPLED;
|
||||
SpvImageOperandsMask operands_mask = 0;
|
||||
unsigned int image_operand_count = 0;
|
||||
uint32_t image_operands[1] = { 0 };
|
||||
struct vkd3d_shader_image image;
|
||||
unsigned int component_idx;
|
||||
uint32_t image_operands[1];
|
||||
DWORD coordinate_mask;
|
||||
bool extended_offset;
|
||||
bool is_sparse_op;
|
||||
|
@ -9678,7 +9811,19 @@ static void vkd3d_dxbc_compiler_emit_ld_raw_structured_srv_uav(struct vkd3d_dxbc
|
|||
uint32_t indices[2];
|
||||
indices[0] = vkd3d_dxbc_compiler_get_constant_uint(compiler, 0);
|
||||
indices[1] = coordinate_id;
|
||||
ptr_id = vkd3d_spirv_build_op_access_chain(builder, ptr_type_id, image.id, indices, ARRAY_SIZE(indices));
|
||||
|
||||
if (access_mask == SpvMemoryAccessAlignedMask)
|
||||
{
|
||||
/* For physical pointers, prefer InBounds for optimal codegen. */
|
||||
ptr_id = vkd3d_spirv_build_op_in_bounds_access_chain(builder, ptr_type_id,
|
||||
image.id, indices, ARRAY_SIZE(indices));
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr_id = vkd3d_spirv_build_op_access_chain(builder, ptr_type_id,
|
||||
image.id, indices, ARRAY_SIZE(indices));
|
||||
}
|
||||
|
||||
constituents[j++] = vkd3d_spirv_build_op_loadv(builder, type_id, ptr_id, access_mask, &alignment, 1);
|
||||
|
||||
if (resource->reg.modifier == VKD3DSPRM_NONUNIFORM)
|
||||
|
@ -9818,7 +9963,17 @@ static void vkd3d_dxbc_compiler_emit_store_uav_raw_structured(struct vkd3d_dxbc_
|
|||
if (component_count > 1)
|
||||
texel_id = vkd3d_spirv_build_op_composite_extract1(builder, type_id, texel_id, component_idx);
|
||||
|
||||
ptr_id = vkd3d_spirv_build_op_access_chain(builder, ptr_type_id, image.id, indices, ARRAY_SIZE(indices));
|
||||
if (access_mask == SpvMemoryAccessAlignedMask)
|
||||
{
|
||||
ptr_id = vkd3d_spirv_build_op_in_bounds_access_chain(builder, ptr_type_id,
|
||||
image.id, indices, ARRAY_SIZE(indices));
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr_id = vkd3d_spirv_build_op_access_chain(builder, ptr_type_id,
|
||||
image.id, indices, ARRAY_SIZE(indices));
|
||||
}
|
||||
|
||||
vkd3d_spirv_build_op_storev(builder, ptr_id, texel_id, access_mask, &alignment, 1);
|
||||
|
||||
if (dst->reg.modifier == VKD3DSPRM_NONUNIFORM)
|
||||
|
@ -9983,6 +10138,7 @@ static void vkd3d_dxbc_compiler_emit_uav_counter_instruction(struct vkd3d_dxbc_c
|
|||
const struct vkd3d_shader_resource_binding *binding;
|
||||
uint32_t type_id, result_id, pointer_id, zero_id;
|
||||
const struct vkd3d_symbol *resource_symbol;
|
||||
bool check_post_decrement;
|
||||
uint32_t operands[3];
|
||||
SpvOp op;
|
||||
|
||||
|
@ -9998,7 +10154,6 @@ static void vkd3d_dxbc_compiler_emit_uav_counter_instruction(struct vkd3d_dxbc_c
|
|||
|
||||
if (binding && (binding->flags & VKD3D_SHADER_BINDING_FLAG_RAW_VA))
|
||||
{
|
||||
uint32_t ctr_ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassPhysicalStorageBuffer, type_id);
|
||||
uint32_t buf_ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, resource_symbol->info.resource.uav_counter_type_id);
|
||||
uint32_t indices[2];
|
||||
|
||||
|
@ -10013,8 +10168,10 @@ static void vkd3d_dxbc_compiler_emit_uav_counter_instruction(struct vkd3d_dxbc_c
|
|||
resource_symbol->info.resource.uav_counter_type_id,
|
||||
pointer_id, SpvMemoryAccessMaskNone);
|
||||
|
||||
pointer_id = vkd3d_spirv_build_op_access_chain1(builder,
|
||||
ctr_ptr_type_id, pointer_id, zero_id);
|
||||
result_id = vkd3d_dxbc_compiler_emit_robust_physical_counter(compiler, pointer_id,
|
||||
instruction->handler_idx == VKD3DSIH_IMM_ATOMIC_ALLOC);
|
||||
|
||||
check_post_decrement = false;
|
||||
}
|
||||
else if (binding && (binding->flags & VKD3D_SHADER_BINDING_FLAG_BINDLESS))
|
||||
{
|
||||
|
@ -10034,6 +10191,8 @@ static void vkd3d_dxbc_compiler_emit_uav_counter_instruction(struct vkd3d_dxbc_c
|
|||
/* Need to mark the pointer argument itself as non-uniform. */
|
||||
if (src->reg.modifier == VKD3DSPRM_NONUNIFORM)
|
||||
vkd3d_dxbc_compiler_decorate_nonuniform(compiler, pointer_id);
|
||||
|
||||
check_post_decrement = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -10041,19 +10200,25 @@ static void vkd3d_dxbc_compiler_emit_uav_counter_instruction(struct vkd3d_dxbc_c
|
|||
|
||||
pointer_id = vkd3d_spirv_build_op_image_texel_pointer(builder, ptr_type_id,
|
||||
resource_symbol->info.resource.uav_counter_id, zero_id, zero_id);
|
||||
|
||||
check_post_decrement = true;
|
||||
}
|
||||
|
||||
operands[0] = pointer_id;
|
||||
operands[1] = vkd3d_dxbc_compiler_get_constant_uint(compiler, SpvScopeDevice);
|
||||
operands[2] = vkd3d_dxbc_compiler_get_constant_uint(compiler, memory_semantics);
|
||||
result_id = vkd3d_spirv_build_op_trv(builder, &builder->function_stream,
|
||||
op, type_id, operands, ARRAY_SIZE(operands));
|
||||
if (op == SpvOpAtomicIDecrement)
|
||||
if (check_post_decrement)
|
||||
{
|
||||
/* SpvOpAtomicIDecrement returns the original value. */
|
||||
result_id = vkd3d_spirv_build_op_isub(builder, type_id, result_id,
|
||||
vkd3d_dxbc_compiler_get_constant_uint(compiler, 1));
|
||||
operands[0] = pointer_id;
|
||||
operands[1] = vkd3d_dxbc_compiler_get_constant_uint(compiler, SpvScopeDevice);
|
||||
operands[2] = vkd3d_dxbc_compiler_get_constant_uint(compiler, memory_semantics);
|
||||
result_id = vkd3d_spirv_build_op_trv(builder, &builder->function_stream,
|
||||
op, type_id, operands, ARRAY_SIZE(operands));
|
||||
if (op == SpvOpAtomicIDecrement)
|
||||
{
|
||||
/* SpvOpAtomicIDecrement returns the original value. */
|
||||
result_id = vkd3d_spirv_build_op_isub(builder, type_id, result_id,
|
||||
vkd3d_dxbc_compiler_get_constant_uint(compiler, 1));
|
||||
}
|
||||
}
|
||||
|
||||
vkd3d_dxbc_compiler_emit_store_dst(compiler, dst, result_id);
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
|
||||
#include "vkd3d_shader_private.h"
|
||||
|
||||
#include "vkd3d_platform.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
|
@ -81,13 +83,13 @@ err:
|
|||
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];
|
||||
const char *path;
|
||||
|
||||
if (!enabled)
|
||||
return false;
|
||||
|
||||
if (!(path = getenv("VKD3D_SHADER_OVERRIDE")))
|
||||
if (!vkd3d_get_env_var("VKD3D_SHADER_OVERRIDE", path, sizeof(path)))
|
||||
{
|
||||
enabled = false;
|
||||
return false;
|
||||
|
@ -100,13 +102,13 @@ bool vkd3d_shader_replace(vkd3d_shader_hash_t hash, const void **data, size_t *s
|
|||
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];
|
||||
const char *path;
|
||||
|
||||
if (!enabled)
|
||||
return false;
|
||||
|
||||
if (!(path = getenv("VKD3D_SHADER_OVERRIDE")))
|
||||
if (!vkd3d_get_env_var("VKD3D_SHADER_OVERRIDE", path, sizeof(path)))
|
||||
{
|
||||
enabled = false;
|
||||
return false;
|
||||
|
@ -119,12 +121,12 @@ bool vkd3d_shader_replace_export(vkd3d_shader_hash_t hash, const void **data, si
|
|||
void vkd3d_shader_dump_shader(vkd3d_shader_hash_t hash, const struct vkd3d_shader_code *shader, const char *ext)
|
||||
{
|
||||
static bool enabled = true;
|
||||
const char *path;
|
||||
char path[VKD3D_PATH_MAX];
|
||||
|
||||
if (!enabled)
|
||||
return;
|
||||
|
||||
if (!(path = getenv("VKD3D_SHADER_DUMP_PATH")))
|
||||
if (!vkd3d_get_env_var("VKD3D_SHADER_DUMP_PATH", path, sizeof(path)))
|
||||
{
|
||||
enabled = false;
|
||||
return;
|
||||
|
@ -136,12 +138,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)
|
||||
{
|
||||
static bool enabled = true;
|
||||
const char *path;
|
||||
char path[VKD3D_PATH_MAX];
|
||||
|
||||
if (!enabled)
|
||||
return;
|
||||
|
||||
if (!(path = getenv("VKD3D_SHADER_DUMP_PATH")))
|
||||
if (!vkd3d_get_env_var("VKD3D_SHADER_DUMP_PATH", path, sizeof(path)))
|
||||
{
|
||||
enabled = false;
|
||||
return;
|
||||
|
@ -154,13 +156,13 @@ void vkd3d_shader_dump_spirv_shader_export(vkd3d_shader_hash_t hash, const struc
|
|||
const char *export)
|
||||
{
|
||||
static bool enabled = true;
|
||||
const char *path;
|
||||
char path[VKD3D_PATH_MAX];
|
||||
char tag[1024];
|
||||
|
||||
if (!enabled)
|
||||
return;
|
||||
|
||||
if (!(path = getenv("VKD3D_SHADER_DUMP_PATH")))
|
||||
if (!vkd3d_get_env_var("VKD3D_SHADER_DUMP_PATH", path, sizeof(path)))
|
||||
{
|
||||
enabled = false;
|
||||
return;
|
||||
|
@ -475,6 +477,7 @@ static void vkd3d_shader_scan_record_uav_counter(struct vkd3d_shader_scan_info *
|
|||
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,
|
||||
reg->idx[0].offset, VKD3D_SHADER_UAV_FLAG_ATOMIC_COUNTER);
|
||||
}
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
#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)
|
||||
{
|
||||
|
@ -74,19 +76,31 @@ bool vkd3d_acceleration_structure_convert_inputs(const struct d3d12_device *devi
|
|||
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;
|
||||
|
||||
|
@ -109,6 +123,9 @@ bool vkd3d_acceleration_structure_convert_inputs(const struct d3d12_device *devi
|
|||
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
|
||||
{
|
||||
|
@ -132,13 +149,21 @@ bool vkd3d_acceleration_structure_convert_inputs(const struct d3d12_device *devi
|
|||
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)
|
||||
{
|
||||
|
@ -155,17 +180,26 @@ bool vkd3d_acceleration_structure_convert_inputs(const struct d3d12_device *devi
|
|||
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.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;
|
||||
|
@ -173,6 +207,11 @@ bool vkd3d_acceleration_structure_convert_inputs(const struct d3d12_device *devi
|
|||
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:
|
||||
|
@ -190,12 +229,15 @@ bool vkd3d_acceleration_structure_convert_inputs(const struct d3d12_device *devi
|
|||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -209,6 +251,8 @@ bool vkd3d_acceleration_structure_convert_inputs(const struct d3d12_device *devi
|
|||
}
|
||||
|
||||
build_info->pGeometries = info->geometries;
|
||||
|
||||
RT_TRACE("=====================\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -262,12 +306,18 @@ static void vkd3d_acceleration_structure_write_postbuild_info(
|
|||
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);
|
||||
FIXME("NumBottomLevelPointers will always return 0.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -298,9 +348,31 @@ static void vkd3d_acceleration_structure_write_postbuild_info(
|
|||
|
||||
if (desc->InfoType == D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_SERIALIZATION)
|
||||
{
|
||||
/* TODO: We'll need some way to store these values for later use and copy them here instead. */
|
||||
VK_CALL(vkCmdFillBuffer(list->vk_command_buffer, vk_buffer, offset + sizeof(uint64_t),
|
||||
sizeof(uint64_t), 0));
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -50,6 +50,8 @@ static const char *vkd3d_breadcrumb_command_type_to_str(enum vkd3d_breadcrumb_co
|
|||
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:
|
||||
|
@ -82,6 +84,8 @@ static const char *vkd3d_breadcrumb_command_type_to_str(enum vkd3d_breadcrumb_co
|
|||
return "root_desc";
|
||||
case VKD3D_BREADCRUMB_COMMAND_ROOT_CONST:
|
||||
return "root_const";
|
||||
case VKD3D_BREADCRUMB_COMMAND_TAG:
|
||||
return "tag";
|
||||
|
||||
default:
|
||||
return "?";
|
||||
|
@ -306,6 +310,10 @@ static void vkd3d_breadcrumb_tracer_report_command_list(
|
|||
{
|
||||
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));
|
||||
|
|
1289
libs/vkd3d/cache.c
1289
libs/vkd3d/cache.c
File diff suppressed because it is too large
Load Diff
3029
libs/vkd3d/command.c
3029
libs/vkd3d/command.c
File diff suppressed because it is too large
Load Diff
|
@ -21,6 +21,7 @@
|
|||
#include "vkd3d_private.h"
|
||||
#include "vkd3d_debug.h"
|
||||
#include "vkd3d_common.h"
|
||||
#include "vkd3d_platform.h"
|
||||
#include <stdio.h>
|
||||
|
||||
void vkd3d_shader_debug_ring_init_spec_constant(struct d3d12_device *device,
|
||||
|
@ -60,12 +61,56 @@ void vkd3d_shader_debug_ring_init_spec_constant(struct d3d12_device *device,
|
|||
#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)
|
||||
{
|
||||
case VKD3D_PATCH_COMMAND_TOKEN_COPY_CONST_U32: return "RootConst";
|
||||
case VKD3D_PATCH_COMMAND_TOKEN_COPY_IBO_VA_LO: return "IBO VA LO";
|
||||
case VKD3D_PATCH_COMMAND_TOKEN_COPY_IBO_VA_HI: return "IBO VA HI";
|
||||
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];
|
||||
uint64_t shader_hash;
|
||||
size_t len, avail;
|
||||
|
||||
if (message_word_count < 8)
|
||||
{
|
||||
|
@ -79,52 +124,107 @@ static bool vkd3d_shader_debug_ring_print_message(struct vkd3d_shader_debug_ring
|
|||
debug_thread_id[i] = READ_RING_WORD(word_offset + 4 + i);
|
||||
fmt = READ_RING_WORD(word_offset + 7);
|
||||
|
||||
snprintf(message_buffer, sizeof(message_buffer), "Shader: %"PRIx64": Instance %u, ID (%u, %u, %u):",
|
||||
shader_hash, debug_instance,
|
||||
debug_thread_id[0], debug_thread_id[1], debug_thread_id[2]);
|
||||
|
||||
word_offset += 8;
|
||||
message_word_count -= 8;
|
||||
|
||||
for (i = 0; i < message_word_count; i++)
|
||||
if (shader_hash == 0)
|
||||
{
|
||||
union
|
||||
/* We got this from our internal debug shaders. Pretty-print.
|
||||
* Make sure the log is sortable for easier debug.
|
||||
* TODO: Might consider a callback system that listeners from different subsystems can listen to and print their own messages,
|
||||
* but that is overengineering at this time ... */
|
||||
snprintf(message_buffer, sizeof(message_buffer), "ExecuteIndirect: GlobalCommandIndex %010u, Debug tag %010u, DrawID %04u (ThreadID %04u): ",
|
||||
debug_instance, debug_thread_id[0], debug_thread_id[1], debug_thread_id[2]);
|
||||
|
||||
if (message_word_count == 2)
|
||||
{
|
||||
float f32;
|
||||
uint32_t u32;
|
||||
int32_t i32;
|
||||
} u;
|
||||
const char *delim;
|
||||
size_t len, avail;
|
||||
u.u32 = READ_RING_WORD(word_offset + i);
|
||||
len = strlen(message_buffer);
|
||||
avail = sizeof(message_buffer) - len;
|
||||
snprintf(message_buffer + len, avail, "DrawCount %u, MaxDrawCount %u",
|
||||
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);
|
||||
if (len + 1 >= sizeof(message_buffer))
|
||||
break;
|
||||
avail = sizeof(message_buffer) - len;
|
||||
len = strlen(message_buffer);
|
||||
avail = sizeof(message_buffer) - len;
|
||||
|
||||
delim = i == 0 ? " " : ", ";
|
||||
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,
|
||||
debug_thread_id[0], debug_thread_id[1], debug_thread_id[2]);
|
||||
|
||||
for (i = 0; i < message_word_count; i++)
|
||||
{
|
||||
union
|
||||
{
|
||||
float f32;
|
||||
uint32_t u32;
|
||||
int32_t i32;
|
||||
} u;
|
||||
const char *delim;
|
||||
u.u32 = READ_RING_WORD(word_offset + i);
|
||||
|
||||
len = strlen(message_buffer);
|
||||
if (len + 1 >= sizeof(message_buffer))
|
||||
break;
|
||||
avail = sizeof(message_buffer) - len;
|
||||
|
||||
delim = i == 0 ? " " : ", ";
|
||||
|
||||
#define VKD3D_DEBUG_CHANNEL_FMT_HEX 0u
|
||||
#define VKD3D_DEBUG_CHANNEL_FMT_I32 1u
|
||||
#define VKD3D_DEBUG_CHANNEL_FMT_F32 2u
|
||||
switch ((fmt >> (2u * i)) & 3u)
|
||||
{
|
||||
case VKD3D_DEBUG_CHANNEL_FMT_HEX:
|
||||
snprintf(message_buffer + len, avail, "%s#%x", delim, u.u32);
|
||||
break;
|
||||
switch ((fmt >> (2u * i)) & 3u)
|
||||
{
|
||||
case VKD3D_DEBUG_CHANNEL_FMT_HEX:
|
||||
snprintf(message_buffer + len, avail, "%s#%x", delim, u.u32);
|
||||
break;
|
||||
|
||||
case VKD3D_DEBUG_CHANNEL_FMT_I32:
|
||||
snprintf(message_buffer + len, avail, "%s%d", delim, u.i32);
|
||||
break;
|
||||
case VKD3D_DEBUG_CHANNEL_FMT_I32:
|
||||
snprintf(message_buffer + len, avail, "%s%d", delim, u.i32);
|
||||
break;
|
||||
|
||||
case VKD3D_DEBUG_CHANNEL_FMT_F32:
|
||||
snprintf(message_buffer + len, avail, "%s%f", delim, u.f32);
|
||||
break;
|
||||
case VKD3D_DEBUG_CHANNEL_FMT_F32:
|
||||
snprintf(message_buffer + len, avail, "%s%f", delim, u.f32);
|
||||
break;
|
||||
|
||||
default:
|
||||
snprintf(message_buffer + len, avail, "%s????", delim);
|
||||
break;
|
||||
default:
|
||||
snprintf(message_buffer + len, avail, "%s????", delim);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -259,10 +359,11 @@ HRESULT vkd3d_shader_debug_ring_init(struct vkd3d_shader_debug_ring *ring,
|
|||
D3D12_HEAP_PROPERTIES heap_properties;
|
||||
D3D12_RESOURCE_DESC1 resource_desc;
|
||||
VkMemoryPropertyFlags memory_props;
|
||||
const char *env;
|
||||
char env[VKD3D_PATH_MAX];
|
||||
|
||||
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;
|
||||
|
||||
ring->active = true;
|
||||
|
|
|
@ -76,10 +76,10 @@ static const char *debug_descriptor_type(vkd3d_descriptor_qa_flags type_flags)
|
|||
|
||||
static void vkd3d_descriptor_debug_init_once(void)
|
||||
{
|
||||
const char *env;
|
||||
char env[VKD3D_PATH_MAX];
|
||||
vkd3d_get_env_var("VKD3D_DESCRIPTOR_QA_LOG", env, sizeof(env));
|
||||
|
||||
env = getenv("VKD3D_DESCRIPTOR_QA_LOG");
|
||||
if (env)
|
||||
if (strlen(env) > 0)
|
||||
{
|
||||
INFO("Enabling VKD3D_DESCRIPTOR_QA_LOG\n");
|
||||
descriptor_debug_file = fopen(env, "w");
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -240,6 +240,7 @@ static HRESULT d3d12_heap_init(struct d3d12_heap *heap, struct d3d12_device *dev
|
|||
|
||||
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;
|
||||
|
|
|
@ -327,34 +327,39 @@ static HRESULT vkd3d_import_host_memory(struct d3d12_device *device, void *host_
|
|||
void *pNext, struct vkd3d_device_memory_allocation *allocation)
|
||||
{
|
||||
VkImportMemoryHostPointerInfoEXT import_info;
|
||||
HRESULT hr;
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
import_info.sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT;
|
||||
import_info.pNext = pNext;
|
||||
import_info.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT;
|
||||
import_info.pHostPointer = host_address;
|
||||
|
||||
if (FAILED(hr = vkd3d_try_allocate_device_memory(device, size,
|
||||
if ((vkd3d_config_flags & VKD3D_CONFIG_FLAG_USE_HOST_IMPORT_FALLBACK) ||
|
||||
FAILED(hr = vkd3d_try_allocate_device_memory(device, size,
|
||||
type_flags, type_mask, &import_info, allocation)))
|
||||
{
|
||||
WARN("Failed to import host memory, hr %#x.\n", hr);
|
||||
if (FAILED(hr))
|
||||
WARN("Failed to import host memory, hr %#x.\n", hr);
|
||||
/* If we failed, fall back to a host-visible allocation. Generally
|
||||
* the app will access the memory thorugh the main host pointer,
|
||||
* so it's fine. */
|
||||
hr = vkd3d_try_allocate_device_memory(device, size,
|
||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
|
||||
type_mask, &import_info, allocation);
|
||||
type_mask, pNext, allocation);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT vkd3d_allocation_assign_gpu_address(struct vkd3d_memory_allocation *allocation, struct d3d12_device *device, struct vkd3d_memory_allocator *allocator)
|
||||
static HRESULT vkd3d_allocation_assign_gpu_address(struct vkd3d_memory_allocation *allocation,
|
||||
struct d3d12_device *device, struct vkd3d_memory_allocator *allocator)
|
||||
{
|
||||
if (device->device_info.buffer_device_address_features.bufferDeviceAddress)
|
||||
allocation->resource.va = vkd3d_get_buffer_device_address(device, allocation->resource.vk_buffer);
|
||||
else
|
||||
else if (!(allocation->flags & VKD3D_ALLOCATION_FLAG_INTERNAL_SCRATCH))
|
||||
allocation->resource.va = vkd3d_va_map_alloc_fake_va(&allocator->va_map, allocation->resource.size);
|
||||
else
|
||||
allocation->resource.va = 0xdeadbeef;
|
||||
|
||||
if (!allocation->resource.va)
|
||||
{
|
||||
|
@ -362,7 +367,9 @@ static HRESULT vkd3d_allocation_assign_gpu_address(struct vkd3d_memory_allocatio
|
|||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
vkd3d_va_map_insert(&allocator->va_map, &allocation->resource);
|
||||
/* Internal scratch buffers are not visible to application so we never have to map it back to VkBuffer. */
|
||||
if (!(allocation->flags & VKD3D_ALLOCATION_FLAG_INTERNAL_SCRATCH))
|
||||
vkd3d_va_map_insert(&allocator->va_map, &allocation->resource);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -446,10 +453,12 @@ static void vkd3d_memory_allocation_free(const struct vkd3d_memory_allocation *a
|
|||
|
||||
if ((allocation->flags & VKD3D_ALLOCATION_FLAG_GPU_ADDRESS) && allocation->resource.va)
|
||||
{
|
||||
vkd3d_va_map_remove(&allocator->va_map, &allocation->resource);
|
||||
|
||||
if (!device->device_info.buffer_device_address_features.bufferDeviceAddress)
|
||||
vkd3d_va_map_free_fake_va(&allocator->va_map, allocation->resource.va, allocation->resource.size);
|
||||
if (!(allocation->flags & VKD3D_ALLOCATION_FLAG_INTERNAL_SCRATCH))
|
||||
{
|
||||
vkd3d_va_map_remove(&allocator->va_map, &allocation->resource);
|
||||
if (!device->device_info.buffer_device_address_features.bufferDeviceAddress)
|
||||
vkd3d_va_map_free_fake_va(&allocator->va_map, allocation->resource.va, allocation->resource.size);
|
||||
}
|
||||
}
|
||||
|
||||
if (allocation->resource.view_map)
|
||||
|
@ -1148,6 +1157,7 @@ static HRESULT vkd3d_memory_allocator_flush_clears_locked(struct vkd3d_memory_al
|
|||
for (i = 0; i < queue_family->queue_count; i++)
|
||||
{
|
||||
vkd3d_queue_add_wait(queue_family->queues[i],
|
||||
NULL,
|
||||
clear_queue->vk_semaphore,
|
||||
clear_queue->next_signal_value);
|
||||
}
|
||||
|
@ -1392,13 +1402,35 @@ static HRESULT vkd3d_suballocate_memory(struct d3d12_device *device, struct vkd3
|
|||
return hr;
|
||||
}
|
||||
|
||||
static inline bool vkd3d_driver_implicitly_clears(VkDriverId driver_id)
|
||||
{
|
||||
switch (driver_id)
|
||||
{
|
||||
/* Known to pass test_stress_suballocation which hits this path. */
|
||||
case VK_DRIVER_ID_MESA_RADV:
|
||||
case VK_DRIVER_ID_NVIDIA_PROPRIETARY:
|
||||
case VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT vkd3d_allocate_memory(struct d3d12_device *device, struct vkd3d_memory_allocator *allocator,
|
||||
const struct vkd3d_allocate_memory_info *info, struct vkd3d_memory_allocation *allocation)
|
||||
{
|
||||
bool implementation_implicitly_clears;
|
||||
bool needs_clear;
|
||||
bool suballocate;
|
||||
HRESULT hr;
|
||||
|
||||
if (!info->pNext && !info->host_ptr && info->memory_requirements.size < VKD3D_VA_BLOCK_SIZE &&
|
||||
!(info->heap_flags & (D3D12_HEAP_FLAG_DENY_BUFFERS | D3D12_HEAP_FLAG_ALLOW_WRITE_WATCH)))
|
||||
suballocate = !info->pNext && !info->host_ptr &&
|
||||
info->memory_requirements.size < VKD3D_VA_BLOCK_SIZE &&
|
||||
!(info->heap_flags & (D3D12_HEAP_FLAG_DENY_BUFFERS | D3D12_HEAP_FLAG_ALLOW_WRITE_WATCH)) &&
|
||||
!(info->flags & VKD3D_ALLOCATION_FLAG_INTERNAL_SCRATCH);
|
||||
|
||||
if (suballocate)
|
||||
hr = vkd3d_suballocate_memory(device, allocator, info, allocation);
|
||||
else
|
||||
hr = vkd3d_memory_allocation_init(allocation, device, allocator, info);
|
||||
|
@ -1406,8 +1438,20 @@ HRESULT vkd3d_allocate_memory(struct d3d12_device *device, struct vkd3d_memory_a
|
|||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
if (!(info->heap_flags & D3D12_HEAP_FLAG_CREATE_NOT_ZEROED) &&
|
||||
!(vkd3d_config_flags & VKD3D_CONFIG_FLAG_MEMORY_ALLOCATOR_SKIP_CLEAR))
|
||||
/* If we're allocating Vulkan memory directly,
|
||||
* we can rely on the driver doing this for us.
|
||||
* This is relying on implementation details.
|
||||
* RADV definitely does this, and it seems like NV also does it.
|
||||
* TODO: an extension for this would be nice. */
|
||||
implementation_implicitly_clears =
|
||||
vkd3d_driver_implicitly_clears(device->device_info.driver_properties.driverID) &&
|
||||
!suballocate;
|
||||
|
||||
needs_clear = !implementation_implicitly_clears &&
|
||||
!(info->heap_flags & D3D12_HEAP_FLAG_CREATE_NOT_ZEROED) &&
|
||||
!(vkd3d_config_flags & VKD3D_CONFIG_FLAG_MEMORY_ALLOCATOR_SKIP_CLEAR);
|
||||
|
||||
if (needs_clear)
|
||||
vkd3d_memory_allocator_clear_allocation(allocator, device, allocation);
|
||||
|
||||
return hr;
|
||||
|
@ -1436,6 +1480,7 @@ static bool vkd3d_heap_allocation_accept_deferred_resource_placements(struct d3d
|
|||
HRESULT vkd3d_allocate_heap_memory(struct d3d12_device *device, struct vkd3d_memory_allocator *allocator,
|
||||
const struct vkd3d_allocate_heap_memory_info *info, struct vkd3d_memory_allocation *allocation)
|
||||
{
|
||||
struct vkd3d_allocate_heap_memory_info heap_info;
|
||||
struct vkd3d_allocate_memory_info alloc_info;
|
||||
HRESULT hr;
|
||||
|
||||
|
@ -1447,9 +1492,31 @@ HRESULT vkd3d_allocate_heap_memory(struct d3d12_device *device, struct vkd3d_mem
|
|||
alloc_info.heap_flags = info->heap_desc.Flags;
|
||||
alloc_info.host_ptr = info->host_ptr;
|
||||
|
||||
alloc_info.flags |= info->extra_allocation_flags;
|
||||
if (!(info->heap_desc.Flags & D3D12_HEAP_FLAG_DENY_BUFFERS))
|
||||
alloc_info.flags |= VKD3D_ALLOCATION_FLAG_GLOBAL_BUFFER;
|
||||
|
||||
if (is_cpu_accessible_heap(&info->heap_desc.Properties))
|
||||
{
|
||||
if (info->heap_desc.Flags & D3D12_HEAP_FLAG_DENY_BUFFERS)
|
||||
{
|
||||
/* If the heap was only designed to handle images, the heap is useless,
|
||||
* and we can force everything to go through committed path. */
|
||||
memset(allocation, 0, sizeof(*allocation));
|
||||
return S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* CPU visible textures are never placed on a heap directly,
|
||||
* since LINEAR images have alignment / size requirements
|
||||
* that are vastly different from OPTIMAL ones.
|
||||
* We can place buffers however. */
|
||||
heap_info = *info;
|
||||
info = &heap_info;
|
||||
heap_info.heap_desc.Flags |= D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS;
|
||||
}
|
||||
}
|
||||
|
||||
hr = vkd3d_allocate_memory(device, allocator, &alloc_info, allocation);
|
||||
if (hr == E_OUTOFMEMORY && vkd3d_heap_allocation_accept_deferred_resource_placements(device,
|
||||
&info->heap_desc.Properties, info->heap_desc.Flags))
|
||||
|
|
|
@ -27,6 +27,8 @@ vkd3d_shaders =[
|
|||
|
||||
'shaders/vs_swapchain_fullscreen.vert',
|
||||
'shaders/fs_swapchain_fullscreen.frag',
|
||||
'shaders/cs_execute_indirect_patch.comp',
|
||||
'shaders/cs_execute_indirect_patch_debug_ring.comp',
|
||||
]
|
||||
|
||||
vkd3d_src = [
|
||||
|
@ -39,7 +41,6 @@ vkd3d_src = [
|
|||
'heap.c',
|
||||
'memory.c',
|
||||
'meta.c',
|
||||
'platform.c',
|
||||
'resource.c',
|
||||
'state.c',
|
||||
'utils.c',
|
||||
|
@ -66,6 +67,10 @@ if enable_breadcrumbs
|
|||
vkd3d_src += ['breadcrumbs.c']
|
||||
endif
|
||||
|
||||
if vkd3d_platform == 'windows'
|
||||
vkd3d_src += ['shared_metadata.c']
|
||||
endif
|
||||
|
||||
if not enable_d3d12
|
||||
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,
|
||||
|
|
|
@ -138,7 +138,7 @@ static VkResult vkd3d_meta_create_compute_pipeline(struct d3d12_device *device,
|
|||
}
|
||||
|
||||
static VkResult vkd3d_meta_create_graphics_pipeline(struct vkd3d_meta_ops *meta_ops,
|
||||
VkPipelineLayout layout, VkFormat color_format, VkFormat ds_format,
|
||||
VkPipelineLayout layout, VkFormat color_format, VkFormat ds_format, VkImageAspectFlags vk_aspect_mask,
|
||||
VkShaderModule vs_module, VkShaderModule fs_module,
|
||||
VkSampleCountFlagBits samples, const VkPipelineDepthStencilStateCreateInfo *ds_state,
|
||||
const VkPipelineColorBlendStateCreateInfo *cb_state, const VkSpecializationInfo *spec_info,
|
||||
|
@ -218,10 +218,10 @@ static VkResult vkd3d_meta_create_graphics_pipeline(struct vkd3d_meta_ops *meta_
|
|||
rendering_info.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR;
|
||||
rendering_info.pNext = NULL;
|
||||
rendering_info.viewMask = 0;
|
||||
rendering_info.colorAttachmentCount = color_format ? 1 : 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 = ds_format;
|
||||
rendering_info.stencilAttachmentFormat = ds_format;
|
||||
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.pNext = &rendering_info;
|
||||
|
@ -611,7 +611,7 @@ static HRESULT vkd3d_meta_create_swapchain_pipeline(struct vkd3d_meta_ops *meta_
|
|||
VK_COLOR_COMPONENT_A_BIT;
|
||||
|
||||
if ((vr = vkd3d_meta_create_graphics_pipeline(meta_ops,
|
||||
meta_swapchain_ops->vk_pipeline_layouts[key->filter], key->format, VK_FORMAT_UNDEFINED,
|
||||
meta_swapchain_ops->vk_pipeline_layouts[key->filter], key->format, VK_FORMAT_UNDEFINED, VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
meta_swapchain_ops->vk_vs_module, meta_swapchain_ops->vk_fs_module, 1,
|
||||
NULL, &cb_state,
|
||||
NULL, &pipeline->vk_pipeline)) < 0)
|
||||
|
@ -731,6 +731,7 @@ static HRESULT vkd3d_meta_create_copy_image_pipeline(struct vkd3d_meta_ops *meta
|
|||
meta_copy_image_ops->vk_pipeline_layout,
|
||||
has_depth_target ? VK_FORMAT_UNDEFINED : key->format->vk_format,
|
||||
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,
|
||||
&spec_info, &pipeline->vk_pipeline)) < 0)
|
||||
|
@ -1216,6 +1217,144 @@ void vkd3d_meta_get_predicate_pipeline(struct vkd3d_meta_ops *meta_ops,
|
|||
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 hr;
|
||||
|
@ -1241,8 +1380,13 @@ HRESULT vkd3d_meta_ops_init(struct vkd3d_meta_ops *meta_ops, struct d3d12_device
|
|||
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;
|
||||
|
||||
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:
|
||||
|
@ -1259,6 +1403,7 @@ fail_common:
|
|||
|
||||
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_swapchain_ops_cleanup(&meta_ops->swapchain, device);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -100,9 +100,9 @@ static bool vkd3d_renderdoc_enable_submit_counter(uint32_t counter)
|
|||
|
||||
static void vkd3d_renderdoc_init_once(void)
|
||||
{
|
||||
char counts[VKD3D_PATH_MAX];
|
||||
pRENDERDOC_GetAPI get_api;
|
||||
const char *counts;
|
||||
const char *env;
|
||||
char env[VKD3D_PATH_MAX];
|
||||
|
||||
#ifdef _WIN32
|
||||
HMODULE renderdoc;
|
||||
|
@ -112,19 +112,19 @@ static void vkd3d_renderdoc_init_once(void)
|
|||
void *fn_ptr;
|
||||
#endif
|
||||
|
||||
env = getenv("VKD3D_AUTO_CAPTURE_SHADER");
|
||||
counts = getenv("VKD3D_AUTO_CAPTURE_COUNTS");
|
||||
vkd3d_get_env_var("VKD3D_AUTO_CAPTURE_SHADER", env, sizeof(env));
|
||||
vkd3d_get_env_var("VKD3D_AUTO_CAPTURE_COUNTS", counts, sizeof(counts));
|
||||
|
||||
if (!env && !counts)
|
||||
if (strlen(env) == 0 && strlen(counts) == 0)
|
||||
{
|
||||
WARN("VKD3D_AUTO_CAPTURE_SHADER or VKD3D_AUTO_CAPTURE_COUNTS is not set, RenderDoc auto capture will not be enabled.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!counts)
|
||||
if (strlen(counts) == 0)
|
||||
WARN("VKD3D_AUTO_CAPTURE_COUNTS is not set, will assume that only the first submission is captured.\n");
|
||||
|
||||
if (env)
|
||||
if (strlen(env) > 0)
|
||||
renderdoc_capture_shader_hash = strtoull(env, NULL, 16);
|
||||
|
||||
if (renderdoc_capture_shader_hash)
|
||||
|
@ -132,7 +132,7 @@ static void vkd3d_renderdoc_init_once(void)
|
|||
else
|
||||
INFO("Enabling RenderDoc capture for all shaders.\n");
|
||||
|
||||
if (counts)
|
||||
if (strlen(counts) > 0)
|
||||
vkd3d_renderdoc_init_capture_count_list(counts);
|
||||
else
|
||||
{
|
||||
|
|
|
@ -224,13 +224,8 @@ static bool vkd3d_get_format_compatibility_list(const struct d3d12_device *devic
|
|||
|
||||
if (desc->Flags & D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS)
|
||||
{
|
||||
const struct vkd3d_format *uint_format = vkd3d_get_format(device, list.uint_format, false);
|
||||
|
||||
/* Format used for ClearUnorderedAccessViewUint */
|
||||
if (uint_format)
|
||||
vkd3d_format_compatibility_list_add_format(&list, uint_format->vk_format);
|
||||
|
||||
/* Legacy D3D11 compatibility rule that allows typed UAV loads on FL11.0 hardware */
|
||||
/* Legacy D3D11 compatibility rule that allows typed UAV loads on FL11.0 hardware.
|
||||
* 5.3.9.5 from D3D11 functional spec. 32-bit typeless formats can be viewed as R32{U,I,F}.*/
|
||||
if (format->byte_count == 4 && format->type == VKD3D_FORMAT_TYPE_TYPELESS)
|
||||
{
|
||||
for (i = 0; i < ARRAY_SIZE(r32_uav_formats); i++)
|
||||
|
@ -490,19 +485,28 @@ static bool vkd3d_format_check_usage_support(struct d3d12_device *device, VkForm
|
|||
return (supported_flags & required_flags) == required_flags;
|
||||
}
|
||||
|
||||
static HRESULT vkd3d_create_image(struct d3d12_device *device,
|
||||
const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags,
|
||||
const D3D12_RESOURCE_DESC1 *desc, struct d3d12_resource *resource, VkImage *vk_image)
|
||||
struct vkd3d_image_create_info
|
||||
{
|
||||
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
||||
struct vkd3d_format_compatibility_list compat_list;
|
||||
const bool sparse_resource = !heap_properties;
|
||||
struct vkd3d_format_compatibility_list format_compat_list;
|
||||
VkExternalMemoryImageCreateInfo external_info;
|
||||
VkImageFormatListCreateInfoKHR format_list;
|
||||
const struct vkd3d_format *format;
|
||||
VkImageCreateInfo image_info;
|
||||
};
|
||||
|
||||
static HRESULT vkd3d_get_image_create_info(struct d3d12_device *device,
|
||||
const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags,
|
||||
const D3D12_RESOURCE_DESC1 *desc, struct d3d12_resource *resource,
|
||||
struct vkd3d_image_create_info *create_info)
|
||||
{
|
||||
struct vkd3d_format_compatibility_list *compat_list = &create_info->format_compat_list;
|
||||
VkExternalMemoryImageCreateInfo *external_info = &create_info->external_info;
|
||||
VkImageFormatListCreateInfoKHR *format_list = &create_info->format_list;
|
||||
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
||||
VkImageCreateInfo *image_info = &create_info->image_info;
|
||||
const bool sparse_resource = !heap_properties;
|
||||
const struct vkd3d_format *format;
|
||||
bool use_concurrent;
|
||||
unsigned int i;
|
||||
VkResult vr;
|
||||
|
||||
if (!resource)
|
||||
{
|
||||
|
@ -517,32 +521,40 @@ static HRESULT vkd3d_create_image(struct d3d12_device *device,
|
|||
format = resource->format;
|
||||
}
|
||||
|
||||
image_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||
image_info.pNext = NULL;
|
||||
image_info.flags = 0;
|
||||
image_info->sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||
image_info->pNext = NULL;
|
||||
image_info->flags = 0;
|
||||
|
||||
if (resource && (resource->heap_flags & D3D12_HEAP_FLAG_SHARED))
|
||||
{
|
||||
external_info->sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO;
|
||||
external_info->pNext = NULL;
|
||||
external_info->handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT;
|
||||
|
||||
image_info->pNext = external_info;
|
||||
}
|
||||
|
||||
if (!(desc->Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL))
|
||||
{
|
||||
if (vkd3d_get_format_compatibility_list(device, desc, &compat_list))
|
||||
if (vkd3d_get_format_compatibility_list(device, desc, compat_list))
|
||||
{
|
||||
format_list.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR;
|
||||
format_list.pNext = NULL;
|
||||
format_list.viewFormatCount = compat_list.format_count;
|
||||
format_list.pViewFormats = compat_list.vk_formats;
|
||||
format_list->sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR;
|
||||
format_list->pNext = image_info->pNext;
|
||||
format_list->viewFormatCount = compat_list->format_count;
|
||||
format_list->pViewFormats = compat_list->vk_formats;
|
||||
|
||||
image_info.pNext = &format_list;
|
||||
image_info.flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
|
||||
image_info->pNext = format_list;
|
||||
image_info->flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
|
||||
}
|
||||
}
|
||||
if (desc->Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE2D
|
||||
&& desc->Width == desc->Height && desc->DepthOrArraySize >= 6
|
||||
&& desc->SampleDesc.Count == 1)
|
||||
image_info.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
|
||||
if (desc->Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D)
|
||||
image_info.flags |= VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR;
|
||||
image_info->flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
|
||||
|
||||
if (sparse_resource)
|
||||
{
|
||||
image_info.flags |= VK_IMAGE_CREATE_SPARSE_BINDING_BIT |
|
||||
image_info->flags |= VK_IMAGE_CREATE_SPARSE_BINDING_BIT |
|
||||
VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT |
|
||||
VK_IMAGE_CREATE_SPARSE_ALIASED_BIT;
|
||||
|
||||
|
@ -566,24 +578,24 @@ static HRESULT vkd3d_create_image(struct d3d12_device *device,
|
|||
}
|
||||
}
|
||||
|
||||
image_info.imageType = vk_image_type_from_d3d12_resource_dimension(desc->Dimension);
|
||||
image_info.format = format->vk_format;
|
||||
image_info.extent.width = desc->Width;
|
||||
image_info.extent.height = desc->Height;
|
||||
image_info->imageType = vk_image_type_from_d3d12_resource_dimension(desc->Dimension);
|
||||
image_info->format = format->vk_format;
|
||||
image_info->extent.width = desc->Width;
|
||||
image_info->extent.height = desc->Height;
|
||||
|
||||
if (desc->Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D)
|
||||
{
|
||||
image_info.extent.depth = desc->DepthOrArraySize;
|
||||
image_info.arrayLayers = 1;
|
||||
image_info->extent.depth = desc->DepthOrArraySize;
|
||||
image_info->arrayLayers = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
image_info.extent.depth = 1;
|
||||
image_info.arrayLayers = desc->DepthOrArraySize;
|
||||
image_info->extent.depth = 1;
|
||||
image_info->arrayLayers = desc->DepthOrArraySize;
|
||||
}
|
||||
|
||||
image_info.mipLevels = min(desc->MipLevels, max_miplevel_count(desc));
|
||||
image_info.samples = vk_samples_from_dxgi_sample_desc(&desc->SampleDesc);
|
||||
image_info->mipLevels = min(desc->MipLevels, max_miplevel_count(desc));
|
||||
image_info->samples = vk_samples_from_dxgi_sample_desc(&desc->SampleDesc);
|
||||
|
||||
if (sparse_resource)
|
||||
{
|
||||
|
@ -593,15 +605,15 @@ static HRESULT vkd3d_create_image(struct d3d12_device *device,
|
|||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
image_info.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||
image_info->tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||
}
|
||||
else if (desc->Layout == D3D12_TEXTURE_LAYOUT_UNKNOWN || desc->Layout == D3D12_TEXTURE_LAYOUT_64KB_UNDEFINED_SWIZZLE)
|
||||
{
|
||||
image_info.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||
image_info->tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||
}
|
||||
else if (desc->Layout == D3D12_TEXTURE_LAYOUT_ROW_MAJOR)
|
||||
{
|
||||
image_info.tiling = VK_IMAGE_TILING_LINEAR;
|
||||
image_info->tiling = VK_IMAGE_TILING_LINEAR;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -609,26 +621,31 @@ static HRESULT vkd3d_create_image(struct d3d12_device *device,
|
|||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
image_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
|
||||
image_info->usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
|
||||
if (desc->Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET)
|
||||
image_info.usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
image_info->usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
if (desc->Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL)
|
||||
image_info.usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
|
||||
image_info->usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
|
||||
if (desc->Flags & D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS)
|
||||
image_info.usage |= VK_IMAGE_USAGE_STORAGE_BIT;
|
||||
image_info->usage |= VK_IMAGE_USAGE_STORAGE_BIT;
|
||||
if (!(desc->Flags & D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE))
|
||||
image_info.usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
|
||||
image_info->usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
|
||||
|
||||
/* Additional usage flags for shader-based copies */
|
||||
if (vkd3d_format_allows_shader_copies(format->dxgi_format))
|
||||
{
|
||||
image_info.usage |= (format->vk_aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT)
|
||||
image_info->usage |= (format->vk_aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT)
|
||||
? VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
|
||||
: VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
}
|
||||
|
||||
if (vkd3d_resource_can_be_vrs(device, heap_properties, desc))
|
||||
image_info.usage |= VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR;
|
||||
image_info->usage |= VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR;
|
||||
|
||||
/* Additional image flags as necessary */
|
||||
if (image_info->imageType == VK_IMAGE_TYPE_3D &&
|
||||
(image_info->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT))
|
||||
image_info->flags |= VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT;
|
||||
|
||||
use_concurrent = !!(device->unique_queue_mask & (device->unique_queue_mask - 1));
|
||||
|
||||
|
@ -648,61 +665,61 @@ static HRESULT vkd3d_create_image(struct d3d12_device *device,
|
|||
{
|
||||
/* For multi-queue, we have to use CONCURRENT since D3D does
|
||||
* not give us enough information to do ownership transfers. */
|
||||
image_info.sharingMode = VK_SHARING_MODE_CONCURRENT;
|
||||
image_info.queueFamilyIndexCount = device->queue_family_count;
|
||||
image_info.pQueueFamilyIndices = device->queue_family_indices;
|
||||
image_info->sharingMode = VK_SHARING_MODE_CONCURRENT;
|
||||
image_info->queueFamilyIndexCount = device->queue_family_count;
|
||||
image_info->pQueueFamilyIndices = device->queue_family_indices;
|
||||
}
|
||||
else
|
||||
{
|
||||
image_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
image_info.queueFamilyIndexCount = 0;
|
||||
image_info.pQueueFamilyIndices = NULL;
|
||||
image_info->sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
image_info->queueFamilyIndexCount = 0;
|
||||
image_info->pQueueFamilyIndices = NULL;
|
||||
}
|
||||
|
||||
if (heap_properties && is_cpu_accessible_heap(heap_properties))
|
||||
{
|
||||
image_info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
|
||||
image_info->initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
|
||||
/* Required for ReadFromSubresource(). */
|
||||
image_info.tiling = VK_IMAGE_TILING_LINEAR;
|
||||
image_info->tiling = VK_IMAGE_TILING_LINEAR;
|
||||
|
||||
if ((vkd3d_config_flags & VKD3D_CONFIG_FLAG_IGNORE_RTV_HOST_VISIBLE) &&
|
||||
(image_info.usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT))
|
||||
(image_info->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT))
|
||||
{
|
||||
WARN("Workaround applied. Ignoring RTV on linear resources.\n");
|
||||
image_info.usage &= ~VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
image_info->usage &= ~VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
if (resource)
|
||||
resource->desc.Flags &= ~D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
image_info->initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
}
|
||||
|
||||
if ((image_info.flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) &&
|
||||
!vkd3d_format_check_usage_support(device, format->vk_format, image_info.usage, image_info.tiling))
|
||||
image_info.flags |= VK_IMAGE_CREATE_EXTENDED_USAGE_BIT;
|
||||
if ((image_info->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) &&
|
||||
!vkd3d_format_check_usage_support(device, format->vk_format, image_info->usage, image_info->tiling))
|
||||
image_info->flags |= VK_IMAGE_CREATE_EXTENDED_USAGE_BIT;
|
||||
|
||||
if (image_info.tiling == VK_IMAGE_TILING_LINEAR)
|
||||
if (image_info->tiling == VK_IMAGE_TILING_LINEAR)
|
||||
{
|
||||
bool supported = vkd3d_is_linear_tiling_supported(device, &image_info);
|
||||
bool supported = vkd3d_is_linear_tiling_supported(device, image_info);
|
||||
|
||||
/* Apparently NV drivers do not support EXTENDED_USAGE_BIT on linear images? */
|
||||
if (!supported && (image_info.flags & VK_IMAGE_CREATE_EXTENDED_USAGE_BIT))
|
||||
if (!supported && (image_info->flags & VK_IMAGE_CREATE_EXTENDED_USAGE_BIT))
|
||||
{
|
||||
WARN("Linear image not supported, attempting without EXTENDED_USAGE as a workaround ...\n");
|
||||
image_info.flags &= ~VK_IMAGE_CREATE_EXTENDED_USAGE_BIT;
|
||||
supported = vkd3d_is_linear_tiling_supported(device, &image_info);
|
||||
image_info->flags &= ~VK_IMAGE_CREATE_EXTENDED_USAGE_BIT;
|
||||
supported = vkd3d_is_linear_tiling_supported(device, image_info);
|
||||
}
|
||||
|
||||
if (!supported)
|
||||
{
|
||||
WARN("Linear image not supported, forcing OPTIMAL tiling ...\n");
|
||||
image_info.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||
image_info->tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||
|
||||
if ((image_info.flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) &&
|
||||
!vkd3d_format_check_usage_support(device, format->vk_format, image_info.usage, image_info.tiling))
|
||||
image_info.flags |= VK_IMAGE_CREATE_EXTENDED_USAGE_BIT;
|
||||
if ((image_info->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) &&
|
||||
!vkd3d_format_check_usage_support(device, format->vk_format, image_info->usage, image_info->tiling))
|
||||
image_info->flags |= VK_IMAGE_CREATE_EXTENDED_USAGE_BIT;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -714,14 +731,14 @@ static HRESULT vkd3d_create_image(struct d3d12_device *device,
|
|||
// D3D12 only allows sparse images with one aspect, so we can only
|
||||
// get one struct for metadata aspect and one for the data aspect
|
||||
VK_CALL(vkGetPhysicalDeviceSparseImageFormatProperties(
|
||||
device->vk_physical_device, image_info.format,
|
||||
image_info.imageType, image_info.samples, image_info.usage,
|
||||
image_info.tiling, &sparse_info_count, sparse_infos));
|
||||
device->vk_physical_device, image_info->format,
|
||||
image_info->imageType, image_info->samples, image_info->usage,
|
||||
image_info->tiling, &sparse_info_count, sparse_infos));
|
||||
|
||||
if (!sparse_info_count)
|
||||
{
|
||||
ERR("Sparse images not supported with format %u, type %u, samples %u, usage %#x, tiling %u.\n",
|
||||
image_info.format, image_info.imageType, image_info.samples, image_info.usage, image_info.tiling);
|
||||
image_info->format, image_info->imageType, image_info->samples, image_info->usage, image_info->tiling);
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
|
@ -740,7 +757,7 @@ static HRESULT vkd3d_create_image(struct d3d12_device *device,
|
|||
|
||||
if (resource)
|
||||
{
|
||||
if (image_info.tiling == VK_IMAGE_TILING_LINEAR)
|
||||
if (image_info->tiling == VK_IMAGE_TILING_LINEAR)
|
||||
{
|
||||
resource->flags |= VKD3D_RESOURCE_LINEAR_TILING;
|
||||
resource->common_layout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
|
@ -752,7 +769,23 @@ static HRESULT vkd3d_create_image(struct d3d12_device *device,
|
|||
resource->flags |= VKD3D_RESOURCE_SIMULTANEOUS_ACCESS;
|
||||
}
|
||||
|
||||
if ((vr = VK_CALL(vkCreateImage(device->vk_device, &image_info, NULL, vk_image))) < 0)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT vkd3d_create_image(struct d3d12_device *device,
|
||||
const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags,
|
||||
const D3D12_RESOURCE_DESC1 *desc, struct d3d12_resource *resource, VkImage *vk_image)
|
||||
{
|
||||
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
||||
struct vkd3d_image_create_info create_info;
|
||||
VkResult vr;
|
||||
HRESULT hr;
|
||||
|
||||
if (FAILED(hr = vkd3d_get_image_create_info(device, heap_properties,
|
||||
heap_flags, desc, resource, &create_info)))
|
||||
return hr;
|
||||
|
||||
if ((vr = VK_CALL(vkCreateImage(device->vk_device, &create_info.image_info, NULL, vk_image))) < 0)
|
||||
WARN("Failed to create Vulkan image, vr %d.\n", vr);
|
||||
|
||||
return hresult_from_vk_result(vr);
|
||||
|
@ -763,10 +796,11 @@ HRESULT vkd3d_get_image_allocation_info(struct d3d12_device *device,
|
|||
{
|
||||
static const D3D12_HEAP_PROPERTIES heap_properties = {D3D12_HEAP_TYPE_DEFAULT};
|
||||
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
||||
VkDeviceImageMemoryRequirementsKHR requirement_info;
|
||||
struct vkd3d_image_create_info create_info;
|
||||
D3D12_RESOURCE_DESC1 validated_desc;
|
||||
VkMemoryRequirements requirements;
|
||||
VkMemoryRequirements2 requirements;
|
||||
VkDeviceSize target_alignment;
|
||||
VkImage vk_image;
|
||||
HRESULT hr;
|
||||
|
||||
assert(desc->Dimension != D3D12_RESOURCE_DIMENSION_BUFFER);
|
||||
|
@ -779,15 +813,21 @@ HRESULT vkd3d_get_image_allocation_info(struct d3d12_device *device,
|
|||
desc = &validated_desc;
|
||||
}
|
||||
|
||||
/* XXX: We have to create an image to get its memory requirements. */
|
||||
if (FAILED(hr = vkd3d_create_image(device, &heap_properties, 0, desc, NULL, &vk_image)))
|
||||
if (FAILED(hr = vkd3d_get_image_create_info(device, &heap_properties, 0, desc, NULL, &create_info)))
|
||||
return hr;
|
||||
|
||||
VK_CALL(vkGetImageMemoryRequirements(device->vk_device, vk_image, &requirements));
|
||||
VK_CALL(vkDestroyImage(device->vk_device, vk_image, NULL));
|
||||
requirement_info.sType = VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS_KHR;
|
||||
requirement_info.pNext = NULL;
|
||||
requirement_info.pCreateInfo = &create_info.image_info;
|
||||
requirement_info.planeAspect = 0; /* irrelevant for us */
|
||||
|
||||
allocation_info->SizeInBytes = requirements.size;
|
||||
allocation_info->Alignment = requirements.alignment;
|
||||
requirements.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2;
|
||||
requirements.pNext = NULL;
|
||||
|
||||
VK_CALL(vkGetDeviceImageMemoryRequirementsKHR(device->vk_device, &requirement_info, &requirements));
|
||||
|
||||
allocation_info->SizeInBytes = requirements.memoryRequirements.size;
|
||||
allocation_info->Alignment = requirements.memoryRequirements.alignment;
|
||||
|
||||
/* Do not report alignments greater than DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT
|
||||
* since that might confuse apps. Instead, pad the allocation so that we can
|
||||
|
@ -841,6 +881,7 @@ static uint32_t vkd3d_view_entry_hash(const void *key)
|
|||
hash = hash_combine(hash, k->u.texture.components.g);
|
||||
hash = hash_combine(hash, k->u.texture.components.b);
|
||||
hash = hash_combine(hash, k->u.texture.components.a);
|
||||
hash = hash_combine(hash, k->u.texture.image_usage);
|
||||
hash = hash_combine(hash, k->u.texture.allowed_swizzle);
|
||||
break;
|
||||
|
||||
|
@ -901,6 +942,7 @@ static bool vkd3d_view_entry_compare(const void *key, const struct hash_map_entr
|
|||
k->u.texture.components.g == e->key.u.texture.components.g &&
|
||||
k->u.texture.components.b == e->key.u.texture.components.b &&
|
||||
k->u.texture.components.a == e->key.u.texture.components.a &&
|
||||
k->u.texture.image_usage == e->key.u.texture.image_usage &&
|
||||
k->u.texture.allowed_swizzle == e->key.u.texture.allowed_swizzle;
|
||||
|
||||
case VKD3D_VIEW_TYPE_SAMPLER:
|
||||
|
@ -1360,18 +1402,12 @@ static void d3d12_resource_get_tiling(struct d3d12_device *device, struct d3d12_
|
|||
|
||||
tile_count += packed_tiles;
|
||||
|
||||
if (standard_mips)
|
||||
{
|
||||
tile_shape->WidthInTexels = block_extent.width;
|
||||
tile_shape->HeightInTexels = block_extent.height;
|
||||
tile_shape->DepthInTexels = block_extent.depth;
|
||||
}
|
||||
else
|
||||
{
|
||||
tile_shape->WidthInTexels = 0;
|
||||
tile_shape->HeightInTexels = 0;
|
||||
tile_shape->DepthInTexels = 0;
|
||||
}
|
||||
/* Docs say that we should clear tile_shape to zero if there are no standard mips,
|
||||
* but this conflicts with all native drivers, so the docs are likely lying here.
|
||||
* See test_get_resource_tiling() for info. */
|
||||
tile_shape->WidthInTexels = block_extent.width;
|
||||
tile_shape->HeightInTexels = block_extent.height;
|
||||
tile_shape->DepthInTexels = block_extent.depth;
|
||||
|
||||
*total_tile_count = tile_count;
|
||||
}
|
||||
|
@ -2677,7 +2713,7 @@ static HRESULT d3d12_resource_create(struct d3d12_device *device, uint32_t flags
|
|||
|
||||
HRESULT d3d12_resource_create_committed(struct d3d12_device *device, const D3D12_RESOURCE_DESC1 *desc,
|
||||
const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags, D3D12_RESOURCE_STATES initial_state,
|
||||
const D3D12_CLEAR_VALUE *optimized_clear_value, struct d3d12_resource **resource)
|
||||
const D3D12_CLEAR_VALUE *optimized_clear_value, HANDLE shared_handle, struct d3d12_resource **resource)
|
||||
{
|
||||
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
||||
struct d3d12_resource *object;
|
||||
|
@ -2698,6 +2734,11 @@ HRESULT d3d12_resource_create_committed(struct d3d12_device *device, const D3D12
|
|||
bool use_dedicated_allocation;
|
||||
VkResult vr;
|
||||
|
||||
#ifdef _WIN32
|
||||
VkImportMemoryWin32HandleInfoKHR import_info;
|
||||
VkExportMemoryAllocateInfo export_info;
|
||||
#endif
|
||||
|
||||
if (FAILED(hr = d3d12_resource_create_vk_resource(object, device)))
|
||||
goto fail;
|
||||
|
||||
|
@ -2730,10 +2771,36 @@ HRESULT d3d12_resource_create_committed(struct d3d12_device *device, const D3D12
|
|||
else
|
||||
allocate_info.heap_flags |= D3D12_HEAP_FLAG_ALLOW_ONLY_NON_RT_DS_TEXTURES;
|
||||
|
||||
if (heap_flags & D3D12_HEAP_FLAG_SHARED)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
use_dedicated_allocation = true;
|
||||
|
||||
if (shared_handle && shared_handle != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
import_info.sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR;
|
||||
import_info.pNext = allocate_info.pNext;
|
||||
import_info.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT;
|
||||
import_info.handle = shared_handle;
|
||||
import_info.name = NULL;
|
||||
allocate_info.pNext = &import_info;
|
||||
}
|
||||
else
|
||||
{
|
||||
export_info.sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO;
|
||||
export_info.pNext = allocate_info.pNext;
|
||||
export_info.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT;
|
||||
allocate_info.pNext = &export_info;
|
||||
}
|
||||
#else
|
||||
FIXME("D3D12_HEAP_FLAG_SHARED can only be implemented in native Win32.\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
if (use_dedicated_allocation)
|
||||
{
|
||||
dedicated_info.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO;
|
||||
dedicated_info.pNext = NULL;
|
||||
dedicated_info.pNext = allocate_info.pNext;
|
||||
dedicated_info.image = object->res.vk_image;
|
||||
dedicated_info.buffer = VK_NULL_HANDLE;
|
||||
allocate_info.pNext = &dedicated_info;
|
||||
|
@ -2780,6 +2847,14 @@ HRESULT d3d12_resource_create_committed(struct d3d12_device *device, const D3D12
|
|||
allocate_info.heap_desc.SizeInBytes = align(desc->Width, allocate_info.heap_desc.Alignment);
|
||||
allocate_info.heap_desc.Flags = heap_flags | D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS;
|
||||
|
||||
/* Be very careful with suballocated buffers. */
|
||||
if ((vkd3d_config_flags & VKD3D_CONFIG_FLAG_ZERO_MEMORY_WORKAROUNDS_COMMITTED_BUFFER_UAV) &&
|
||||
(desc->Flags & D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS) &&
|
||||
desc->Width < VKD3D_VA_BLOCK_SIZE)
|
||||
{
|
||||
allocate_info.heap_desc.Flags &= ~D3D12_HEAP_FLAG_CREATE_NOT_ZEROED;
|
||||
}
|
||||
|
||||
if (FAILED(hr = vkd3d_allocate_heap_memory(device,
|
||||
&device->memory_allocator, &allocate_info, &object->mem)))
|
||||
goto fail;
|
||||
|
@ -2831,20 +2906,30 @@ HRESULT d3d12_resource_create_placed(struct d3d12_device *device, const D3D12_RE
|
|||
VkMemoryRequirements memory_requirements;
|
||||
VkBindImageMemoryInfo bind_info;
|
||||
struct d3d12_resource *object;
|
||||
bool force_committed;
|
||||
VkResult vr;
|
||||
HRESULT hr;
|
||||
|
||||
if (FAILED(hr = d3d12_resource_validate_heap(desc, heap)))
|
||||
return hr;
|
||||
|
||||
if (heap->allocation.device_allocation.vk_memory == VK_NULL_HANDLE)
|
||||
/* Placed linear textures are ... problematic
|
||||
* since we have no way of signalling that they have different alignment and size requirements
|
||||
* than optimal textures. GetResourceAllocationInfo() does not take heap property information
|
||||
* and assumes that we are not modifying the tiling mode. */
|
||||
force_committed = desc->Dimension != D3D12_RESOURCE_DIMENSION_BUFFER &&
|
||||
is_cpu_accessible_heap(&heap->desc.Properties);
|
||||
|
||||
if (force_committed || heap->allocation.device_allocation.vk_memory == VK_NULL_HANDLE)
|
||||
{
|
||||
WARN("Placing resource on heap with no memory backing it. Falling back to committed resource.\n");
|
||||
if (!force_committed)
|
||||
WARN("Placing resource on heap with no memory backing it. Falling back to committed resource.\n");
|
||||
|
||||
if (FAILED(hr = d3d12_resource_create_committed(device, desc, &heap->desc.Properties,
|
||||
heap->desc.Flags & ~(D3D12_HEAP_FLAG_DENY_BUFFERS |
|
||||
D3D12_HEAP_FLAG_DENY_NON_RT_DS_TEXTURES |
|
||||
D3D12_HEAP_FLAG_DENY_RT_DS_TEXTURES),
|
||||
initial_state, optimized_clear_value, resource)))
|
||||
initial_state, optimized_clear_value, NULL, resource)))
|
||||
{
|
||||
ERR("Failed to create fallback committed resource.\n");
|
||||
}
|
||||
|
@ -2915,6 +3000,15 @@ HRESULT d3d12_resource_create_placed(struct d3d12_device *device, const D3D12_RE
|
|||
goto fail;
|
||||
}
|
||||
|
||||
/* Placed RTV and DSV *must* be explicitly initialized after alias barriers and first use,
|
||||
* so there is no need to do initial layout transition ourselves.
|
||||
* It is extremely dangerous to do so since the initialization will clobber other
|
||||
* aliased buffers when clearing DCC/HTILE state.
|
||||
* For details, see:
|
||||
* https://docs.microsoft.com/en-us/windows/win32/api/d3d12/nf-d3d12-id3d12device-createplacedresource#notes-on-the-required-resource-initialization. */
|
||||
if (desc->Flags & (D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET | D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL))
|
||||
object->initial_layout_transition = 0;
|
||||
|
||||
*resource = object;
|
||||
return S_OK;
|
||||
|
||||
|
@ -3349,7 +3443,7 @@ bool vkd3d_create_raw_r32ui_vk_buffer_view(struct d3d12_device *device,
|
|||
return vr == VK_SUCCESS;
|
||||
}
|
||||
|
||||
static bool vkd3d_create_vk_buffer_view(struct d3d12_device *device,
|
||||
bool vkd3d_create_vk_buffer_view(struct d3d12_device *device,
|
||||
VkBuffer vk_buffer, const struct vkd3d_format *format,
|
||||
VkDeviceSize offset, VkDeviceSize range, VkBufferView *vk_view)
|
||||
{
|
||||
|
@ -3649,6 +3743,7 @@ static bool init_default_texture_view_desc(struct vkd3d_texture_view_desc *desc,
|
|||
desc->miplevel_clamp = 0.0f;
|
||||
desc->layer_idx = 0;
|
||||
desc->layer_count = d3d12_resource_desc_get_layer_count(&resource->desc);
|
||||
desc->image_usage = 0;
|
||||
|
||||
switch (resource->desc.Dimension)
|
||||
{
|
||||
|
@ -3683,6 +3778,7 @@ static bool init_default_texture_view_desc(struct vkd3d_texture_view_desc *desc,
|
|||
bool vkd3d_create_texture_view(struct d3d12_device *device, const struct vkd3d_texture_view_desc *desc, struct vkd3d_view **view)
|
||||
{
|
||||
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
||||
VkImageViewUsageCreateInfo image_usage_create_info;
|
||||
const struct vkd3d_format *format = desc->format;
|
||||
VkImageViewMinLodCreateInfoEXT min_lod_desc;
|
||||
VkImageView vk_view = VK_NULL_HANDLE;
|
||||
|
@ -3733,6 +3829,11 @@ bool vkd3d_create_texture_view(struct d3d12_device *device, const struct vkd3d_t
|
|||
}
|
||||
}
|
||||
|
||||
image_usage_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO;
|
||||
image_usage_create_info.pNext = NULL;
|
||||
image_usage_create_info.usage = desc->image_usage;
|
||||
vk_prepend_struct(&view_desc, &image_usage_create_info);
|
||||
|
||||
if ((vr = VK_CALL(vkCreateImageView(device->vk_device, &view_desc, NULL, &vk_view))) < 0)
|
||||
{
|
||||
WARN("Failed to create Vulkan image view, vr %d.\n", vr);
|
||||
|
@ -4230,6 +4331,7 @@ static void vkd3d_create_texture_srv(vkd3d_cpu_descriptor_va_t desc_va,
|
|||
key.view_type = VKD3D_VIEW_TYPE_IMAGE;
|
||||
key.u.texture.miplevel_count = VK_REMAINING_MIP_LEVELS;
|
||||
key.u.texture.allowed_swizzle = true;
|
||||
key.u.texture.image_usage = VK_IMAGE_USAGE_SAMPLED_BIT;
|
||||
|
||||
if (desc)
|
||||
{
|
||||
|
@ -4624,6 +4726,8 @@ static void vkd3d_create_texture_uav(vkd3d_cpu_descriptor_va_t desc_va,
|
|||
if (!init_default_texture_view_desc(&key.u.texture, resource, desc ? desc->Format : 0))
|
||||
return;
|
||||
|
||||
key.u.texture.image_usage = VK_IMAGE_USAGE_STORAGE_BIT;
|
||||
|
||||
if (vkd3d_format_is_compressed(key.u.texture.format))
|
||||
{
|
||||
WARN("UAVs cannot be created for compressed formats.\n");
|
||||
|
@ -5046,6 +5150,7 @@ void d3d12_rtv_desc_create_rtv(struct d3d12_rtv_desc *rtv_desc, struct d3d12_dev
|
|||
}
|
||||
|
||||
key.view_type = VKD3D_VIEW_TYPE_IMAGE;
|
||||
key.u.texture.image_usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
|
||||
if (desc)
|
||||
{
|
||||
|
@ -5151,6 +5256,7 @@ void d3d12_rtv_desc_create_dsv(struct d3d12_rtv_desc *dsv_desc, struct d3d12_dev
|
|||
}
|
||||
|
||||
key.view_type = VKD3D_VIEW_TYPE_IMAGE;
|
||||
key.u.texture.image_usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
|
||||
|
||||
if (desc)
|
||||
{
|
||||
|
@ -6404,7 +6510,9 @@ HRESULT vkd3d_memory_info_init(struct vkd3d_memory_info *info,
|
|||
struct d3d12_device *device)
|
||||
{
|
||||
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
||||
VkMemoryRequirements memory_requirements;
|
||||
VkDeviceBufferMemoryRequirementsKHR buffer_requirement_info;
|
||||
VkDeviceImageMemoryRequirementsKHR image_requirement_info;
|
||||
VkMemoryRequirements2 memory_requirements;
|
||||
struct vkd3d_memory_topology topology;
|
||||
VkBufferCreateInfo buffer_info;
|
||||
uint32_t sampled_type_mask_cpu;
|
||||
|
@ -6414,9 +6522,6 @@ HRESULT vkd3d_memory_info_init(struct vkd3d_memory_info *info,
|
|||
uint32_t host_visible_mask;
|
||||
uint32_t buffer_type_mask;
|
||||
uint32_t rt_ds_type_mask;
|
||||
VkBuffer buffer;
|
||||
VkImage image;
|
||||
VkResult vr;
|
||||
uint32_t i;
|
||||
|
||||
vkd3d_memory_info_get_topology(&topology, device);
|
||||
|
@ -6426,6 +6531,18 @@ HRESULT vkd3d_memory_info_init(struct vkd3d_memory_info *info,
|
|||
if (pthread_mutex_init(&info->budget_lock, NULL) != 0)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
buffer_requirement_info.sType = VK_STRUCTURE_TYPE_DEVICE_BUFFER_MEMORY_REQUIREMENTS_KHR;
|
||||
buffer_requirement_info.pNext = NULL;
|
||||
buffer_requirement_info.pCreateInfo = &buffer_info;
|
||||
|
||||
image_requirement_info.sType = VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS_KHR;
|
||||
image_requirement_info.pNext = NULL;
|
||||
image_requirement_info.pCreateInfo = &image_info;
|
||||
image_requirement_info.planeAspect = 0;
|
||||
|
||||
memory_requirements.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2;
|
||||
memory_requirements.pNext = NULL;
|
||||
|
||||
memset(&buffer_info, 0, sizeof(buffer_info));
|
||||
buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
||||
buffer_info.size = 65536;
|
||||
|
@ -6448,15 +6565,8 @@ HRESULT vkd3d_memory_info_init(struct vkd3d_memory_info *info,
|
|||
VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR;
|
||||
}
|
||||
|
||||
if ((vr = VK_CALL(vkCreateBuffer(device->vk_device, &buffer_info, NULL, &buffer))) < 0)
|
||||
{
|
||||
ERR("Failed to create dummy buffer");
|
||||
return hresult_from_vk_result(vr);
|
||||
}
|
||||
|
||||
VK_CALL(vkGetBufferMemoryRequirements(device->vk_device, buffer, &memory_requirements));
|
||||
VK_CALL(vkDestroyBuffer(device->vk_device, buffer, NULL));
|
||||
buffer_type_mask = memory_requirements.memoryTypeBits;
|
||||
VK_CALL(vkGetDeviceBufferMemoryRequirementsKHR(device->vk_device, &buffer_requirement_info, &memory_requirements));
|
||||
buffer_type_mask = memory_requirements.memoryRequirements.memoryTypeBits;
|
||||
|
||||
memset(&image_info, 0, sizeof(image_info));
|
||||
image_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||
|
@ -6476,15 +6586,8 @@ HRESULT vkd3d_memory_info_init(struct vkd3d_memory_info *info,
|
|||
image_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
|
||||
if ((vr = VK_CALL(vkCreateImage(device->vk_device, &image_info, NULL, &image))) < 0)
|
||||
{
|
||||
ERR("Failed to create dummy sampled image");
|
||||
return hresult_from_vk_result(vr);
|
||||
}
|
||||
|
||||
VK_CALL(vkGetImageMemoryRequirements(device->vk_device, image, &memory_requirements));
|
||||
VK_CALL(vkDestroyImage(device->vk_device, image, NULL));
|
||||
sampled_type_mask = memory_requirements.memoryTypeBits;
|
||||
VK_CALL(vkGetDeviceImageMemoryRequirementsKHR(device->vk_device, &image_requirement_info, &memory_requirements));
|
||||
sampled_type_mask = memory_requirements.memoryRequirements.memoryTypeBits;
|
||||
|
||||
/* CPU accessible images are always LINEAR.
|
||||
* If we ever get a way to write to OPTIMAL-ly tiled images, we can drop this and just
|
||||
|
@ -6499,12 +6602,8 @@ HRESULT vkd3d_memory_info_init(struct vkd3d_memory_info *info,
|
|||
sampled_type_mask_cpu = 0;
|
||||
if (vkd3d_is_linear_tiling_supported(device, &image_info))
|
||||
{
|
||||
if ((vr = VK_CALL(vkCreateImage(device->vk_device, &image_info, NULL, &image))) == VK_SUCCESS)
|
||||
{
|
||||
VK_CALL(vkGetImageMemoryRequirements(device->vk_device, image, &memory_requirements));
|
||||
VK_CALL(vkDestroyImage(device->vk_device, image, NULL));
|
||||
sampled_type_mask_cpu = memory_requirements.memoryTypeBits;
|
||||
}
|
||||
VK_CALL(vkGetDeviceImageMemoryRequirementsKHR(device->vk_device, &image_requirement_info, &memory_requirements));
|
||||
sampled_type_mask_cpu = memory_requirements.memoryRequirements.memoryTypeBits;
|
||||
}
|
||||
image_info.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||
image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
|
@ -6516,27 +6615,16 @@ HRESULT vkd3d_memory_info_init(struct vkd3d_memory_info *info,
|
|||
VK_IMAGE_USAGE_SAMPLED_BIT |
|
||||
VK_IMAGE_USAGE_STORAGE_BIT;
|
||||
|
||||
if ((vr = VK_CALL(vkCreateImage(device->vk_device, &image_info, NULL, &image))) < 0)
|
||||
{
|
||||
ERR("Failed to create dummy color image");
|
||||
return hresult_from_vk_result(vr);
|
||||
}
|
||||
|
||||
VK_CALL(vkGetImageMemoryRequirements(device->vk_device, image, &memory_requirements));
|
||||
VK_CALL(vkDestroyImage(device->vk_device, image, NULL));
|
||||
rt_ds_type_mask = memory_requirements.memoryTypeBits;
|
||||
VK_CALL(vkGetDeviceImageMemoryRequirementsKHR(device->vk_device, &image_requirement_info, &memory_requirements));
|
||||
rt_ds_type_mask = memory_requirements.memoryRequirements.memoryTypeBits;
|
||||
|
||||
image_info.tiling = VK_IMAGE_TILING_LINEAR;
|
||||
image_info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
|
||||
rt_ds_type_mask_cpu = 0;
|
||||
if (vkd3d_is_linear_tiling_supported(device, &image_info))
|
||||
{
|
||||
if ((vr = VK_CALL(vkCreateImage(device->vk_device, &image_info, NULL, &image))) == VK_SUCCESS)
|
||||
{
|
||||
VK_CALL(vkGetImageMemoryRequirements(device->vk_device, image, &memory_requirements));
|
||||
VK_CALL(vkDestroyImage(device->vk_device, image, NULL));
|
||||
rt_ds_type_mask_cpu = memory_requirements.memoryTypeBits;
|
||||
}
|
||||
VK_CALL(vkGetDeviceImageMemoryRequirementsKHR(device->vk_device, &image_requirement_info, &memory_requirements));
|
||||
rt_ds_type_mask_cpu = memory_requirements.memoryRequirements.memoryTypeBits;
|
||||
}
|
||||
image_info.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||
image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
|
@ -6547,15 +6635,8 @@ HRESULT vkd3d_memory_info_init(struct vkd3d_memory_info *info,
|
|||
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
|
||||
VK_IMAGE_USAGE_SAMPLED_BIT;
|
||||
|
||||
if ((vr = VK_CALL(vkCreateImage(device->vk_device, &image_info, NULL, &image))) < 0)
|
||||
{
|
||||
ERR("Failed to create dummy depth-stencil image");
|
||||
return hresult_from_vk_result(vr);
|
||||
}
|
||||
|
||||
VK_CALL(vkGetImageMemoryRequirements(device->vk_device, image, &memory_requirements));
|
||||
VK_CALL(vkDestroyImage(device->vk_device, image, NULL));
|
||||
rt_ds_type_mask &= memory_requirements.memoryTypeBits;
|
||||
VK_CALL(vkGetDeviceImageMemoryRequirementsKHR(device->vk_device, &image_requirement_info, &memory_requirements));
|
||||
rt_ds_type_mask &= memory_requirements.memoryRequirements.memoryTypeBits;
|
||||
|
||||
/* Unsure if we can have host visible depth-stencil.
|
||||
* On AMD, we can get linear RT, but not linear DS, so for now, just don't check for that.
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
#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;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
#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;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
|
@ -53,6 +53,12 @@ static ULONG STDMETHODCALLTYPE d3d12_root_signature_AddRef(ID3D12RootSignature *
|
|||
|
||||
TRACE("%p increasing refcount to %u.\n", root_signature, refcount);
|
||||
|
||||
if (refcount == 1)
|
||||
{
|
||||
d3d12_root_signature_inc_ref(root_signature);
|
||||
d3d12_device_add_ref(root_signature->device);
|
||||
}
|
||||
|
||||
return refcount;
|
||||
}
|
||||
|
||||
|
@ -77,19 +83,35 @@ static void d3d12_root_signature_cleanup(struct d3d12_root_signature *root_signa
|
|||
vkd3d_free(root_signature->static_samplers_desc);
|
||||
}
|
||||
|
||||
void d3d12_root_signature_inc_ref(struct d3d12_root_signature *root_signature)
|
||||
{
|
||||
InterlockedIncrement(&root_signature->internal_refcount);
|
||||
}
|
||||
|
||||
void d3d12_root_signature_dec_ref(struct d3d12_root_signature *root_signature)
|
||||
{
|
||||
struct d3d12_device *device = root_signature->device;
|
||||
ULONG refcount = InterlockedDecrement(&root_signature->internal_refcount);
|
||||
|
||||
if (refcount == 0)
|
||||
{
|
||||
vkd3d_private_store_destroy(&root_signature->private_store);
|
||||
d3d12_root_signature_cleanup(root_signature, device);
|
||||
vkd3d_free(root_signature);
|
||||
}
|
||||
}
|
||||
|
||||
static ULONG STDMETHODCALLTYPE d3d12_root_signature_Release(ID3D12RootSignature *iface)
|
||||
{
|
||||
struct d3d12_root_signature *root_signature = impl_from_ID3D12RootSignature(iface);
|
||||
struct d3d12_device *device = root_signature->device;
|
||||
ULONG refcount = InterlockedDecrement(&root_signature->refcount);
|
||||
|
||||
TRACE("%p decreasing refcount to %u.\n", root_signature, refcount);
|
||||
|
||||
if (!refcount)
|
||||
{
|
||||
struct d3d12_device *device = root_signature->device;
|
||||
vkd3d_private_store_destroy(&root_signature->private_store);
|
||||
d3d12_root_signature_cleanup(root_signature, device);
|
||||
vkd3d_free(root_signature);
|
||||
d3d12_root_signature_dec_ref(root_signature);
|
||||
d3d12_device_release(device);
|
||||
}
|
||||
|
||||
|
@ -923,6 +945,7 @@ static HRESULT d3d12_root_signature_init_root_descriptors(struct d3d12_root_sign
|
|||
struct vkd3d_shader_resource_binding *binding;
|
||||
VkDescriptorSetLayoutCreateFlags vk_flags;
|
||||
struct vkd3d_shader_root_parameter *param;
|
||||
uint32_t raw_va_root_descriptor_count = 0;
|
||||
unsigned int hoisted_parameter_index;
|
||||
const D3D12_DESCRIPTOR_RANGE1 *range;
|
||||
unsigned int i, j, k;
|
||||
|
@ -1039,10 +1062,13 @@ static HRESULT d3d12_root_signature_init_root_descriptors(struct d3d12_root_sign
|
|||
param = &root_signature->parameters[i];
|
||||
param->parameter_type = p->ParameterType;
|
||||
param->descriptor.binding = binding;
|
||||
param->descriptor.raw_va_root_descriptor_index = raw_va_root_descriptor_count;
|
||||
|
||||
context->binding_index += 1;
|
||||
|
||||
if (!raw_va)
|
||||
if (raw_va)
|
||||
raw_va_root_descriptor_count += 1;
|
||||
else
|
||||
context->vk_binding += 1;
|
||||
}
|
||||
|
||||
|
@ -1420,6 +1446,7 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa
|
|||
memset(root_signature, 0, sizeof(*root_signature));
|
||||
root_signature->ID3D12RootSignature_iface.lpVtbl = &d3d12_root_signature_vtbl;
|
||||
root_signature->refcount = 1;
|
||||
root_signature->internal_refcount = 1;
|
||||
|
||||
root_signature->d3d12_flags = desc->Flags;
|
||||
/* needed by some methods, increment ref count later */
|
||||
|
@ -1446,8 +1473,36 @@ fail:
|
|||
return hr;
|
||||
}
|
||||
|
||||
HRESULT d3d12_root_signature_create(struct d3d12_device *device,
|
||||
const void *bytecode, size_t bytecode_length, struct d3d12_root_signature **root_signature)
|
||||
HRESULT d3d12_root_signature_create_empty(struct d3d12_device *device,
|
||||
struct d3d12_root_signature **root_signature)
|
||||
{
|
||||
struct d3d12_root_signature *object;
|
||||
D3D12_ROOT_SIGNATURE_DESC1 desc;
|
||||
HRESULT hr;
|
||||
|
||||
if (!(object = vkd3d_malloc(sizeof(*object))))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
memset(&desc, 0, sizeof(desc));
|
||||
hr = d3d12_root_signature_init(object, device, &desc);
|
||||
|
||||
/* For pipeline libraries, (and later DXR to some degree), we need a way to
|
||||
* compare root signature objects. */
|
||||
object->compatibility_hash = 0;
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
vkd3d_free(object);
|
||||
return hr;
|
||||
}
|
||||
|
||||
*root_signature = object;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT d3d12_root_signature_create_from_blob(struct d3d12_device *device,
|
||||
const void *bytecode, size_t bytecode_length, bool raw_payload,
|
||||
struct d3d12_root_signature **root_signature)
|
||||
{
|
||||
const struct vkd3d_shader_code dxbc = {bytecode, bytecode_length};
|
||||
union
|
||||
|
@ -1455,14 +1510,26 @@ HRESULT d3d12_root_signature_create(struct d3d12_device *device,
|
|||
D3D12_VERSIONED_ROOT_SIGNATURE_DESC d3d12;
|
||||
struct vkd3d_versioned_root_signature_desc vkd3d;
|
||||
} root_signature_desc;
|
||||
vkd3d_shader_hash_t compatibility_hash;
|
||||
struct d3d12_root_signature *object;
|
||||
HRESULT hr;
|
||||
int ret;
|
||||
|
||||
if ((ret = vkd3d_parse_root_signature_v_1_1(&dxbc, &root_signature_desc.vkd3d)) < 0)
|
||||
if (raw_payload)
|
||||
{
|
||||
WARN("Failed to parse root signature, vkd3d result %d.\n", ret);
|
||||
return hresult_from_vkd3d_result(ret);
|
||||
if ((ret = vkd3d_parse_root_signature_v_1_1_from_raw_payload(&dxbc, &root_signature_desc.vkd3d, &compatibility_hash)))
|
||||
{
|
||||
WARN("Failed to parse root signature, vkd3d result %d.\n", ret);
|
||||
return hresult_from_vkd3d_result(ret);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((ret = vkd3d_parse_root_signature_v_1_1(&dxbc, &root_signature_desc.vkd3d, &compatibility_hash)) < 0)
|
||||
{
|
||||
WARN("Failed to parse root signature, vkd3d result %d.\n", ret);
|
||||
return hresult_from_vkd3d_result(ret);
|
||||
}
|
||||
}
|
||||
|
||||
if (!(object = vkd3d_malloc(sizeof(*object))))
|
||||
|
@ -1475,7 +1542,7 @@ HRESULT d3d12_root_signature_create(struct d3d12_device *device,
|
|||
|
||||
/* For pipeline libraries, (and later DXR to some degree), we need a way to
|
||||
* compare root signature objects. */
|
||||
object->compatibility_hash = vkd3d_shader_hash(&dxbc);
|
||||
object->compatibility_hash = compatibility_hash;
|
||||
|
||||
vkd3d_shader_free_root_signature(&root_signature_desc.vkd3d);
|
||||
if (FAILED(hr))
|
||||
|
@ -1491,6 +1558,20 @@ HRESULT d3d12_root_signature_create(struct d3d12_device *device,
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT d3d12_root_signature_create(struct d3d12_device *device,
|
||||
const void *bytecode, size_t bytecode_length,
|
||||
struct d3d12_root_signature **root_signature)
|
||||
{
|
||||
return d3d12_root_signature_create_from_blob(device, bytecode, bytecode_length, false, root_signature);
|
||||
}
|
||||
|
||||
HRESULT d3d12_root_signature_create_raw(struct d3d12_device *device,
|
||||
const void *payload, size_t payload_length,
|
||||
struct d3d12_root_signature **root_signature)
|
||||
{
|
||||
return d3d12_root_signature_create_from_blob(device, payload, payload_length, true, root_signature);
|
||||
}
|
||||
|
||||
unsigned int d3d12_root_signature_get_shader_interface_flags(const struct d3d12_root_signature *root_signature)
|
||||
{
|
||||
unsigned int flags = 0;
|
||||
|
@ -1878,7 +1959,7 @@ void d3d12_pipeline_state_dec_ref(struct d3d12_pipeline_state *state)
|
|||
VK_CALL(vkDestroyPipelineCache(device->vk_device, state->vk_pso_cache, NULL));
|
||||
|
||||
if (state->private_root_signature)
|
||||
ID3D12RootSignature_Release(state->private_root_signature);
|
||||
d3d12_root_signature_dec_ref(state->private_root_signature);
|
||||
|
||||
vkd3d_free(state);
|
||||
}
|
||||
|
@ -2247,7 +2328,8 @@ static HRESULT vkd3d_create_compute_pipeline(struct d3d12_device *device,
|
|||
}
|
||||
|
||||
static HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *state,
|
||||
struct d3d12_device *device, const struct d3d12_pipeline_state_desc *desc)
|
||||
struct d3d12_device *device, const struct d3d12_pipeline_state_desc *desc,
|
||||
const struct d3d12_cached_pipeline_state *cached_pso)
|
||||
{
|
||||
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
||||
struct vkd3d_shader_interface_info shader_interface;
|
||||
|
@ -2259,7 +2341,7 @@ static HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *st
|
|||
if (desc->root_signature)
|
||||
root_signature = impl_from_ID3D12RootSignature(desc->root_signature);
|
||||
else
|
||||
root_signature = impl_from_ID3D12RootSignature(state->private_root_signature);
|
||||
root_signature = state->private_root_signature;
|
||||
|
||||
shader_interface.flags = d3d12_root_signature_get_shader_interface_flags(root_signature);
|
||||
shader_interface.min_ssbo_alignment = d3d12_device_get_ssbo_alignment(device);
|
||||
|
@ -2278,22 +2360,22 @@ static HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *st
|
|||
shader_interface.descriptor_qa_heap_binding = &root_signature->descriptor_qa_heap_binding;
|
||||
#endif
|
||||
|
||||
if (!device->global_pipeline_cache)
|
||||
if (!(vkd3d_config_flags & VKD3D_CONFIG_FLAG_GLOBAL_PIPELINE_CACHE))
|
||||
{
|
||||
if ((hr = vkd3d_create_pipeline_cache_from_d3d12_desc(device, &desc->cached_pso, &state->vk_pso_cache)) < 0)
|
||||
if ((hr = vkd3d_create_pipeline_cache_from_d3d12_desc(device, cached_pso, &state->vk_pso_cache)) < 0)
|
||||
{
|
||||
ERR("Failed to create pipeline cache, hr %d.\n", hr);
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
|
||||
vkd3d_load_spirv_from_cached_state(device, &desc->cached_pso,
|
||||
vkd3d_load_spirv_from_cached_state(device, cached_pso,
|
||||
VK_SHADER_STAGE_COMPUTE_BIT, &state->compute.code);
|
||||
|
||||
hr = vkd3d_create_compute_pipeline(device,
|
||||
&desc->cs, &shader_interface,
|
||||
root_signature->compute.vk_pipeline_layout,
|
||||
state->vk_pso_cache ? state->vk_pso_cache : device->global_pipeline_cache,
|
||||
state->vk_pso_cache,
|
||||
&state->compute.vk_pipeline,
|
||||
&state->compute.code);
|
||||
|
||||
|
@ -2750,7 +2832,7 @@ static uint32_t d3d12_graphics_pipeline_state_get_plane_optimal_mask(
|
|||
dsv_format = graphics->dsv_format->vk_format;
|
||||
aspects = graphics->dsv_format->vk_aspect_mask;
|
||||
}
|
||||
else if (graphics->null_attachment_mask & dsv_attachment_mask(graphics))
|
||||
else if (d3d12_graphics_pipeline_state_has_unknown_dsv_format_with_test(graphics))
|
||||
{
|
||||
dsv_format = dynamic_dsv_format->vk_format;
|
||||
aspects = dynamic_dsv_format->vk_aspect_mask;
|
||||
|
@ -2799,6 +2881,24 @@ static bool vk_blend_attachment_needs_blend_constants(const VkPipelineColorBlend
|
|||
vk_blend_factor_needs_blend_constants(attachment->dstAlphaBlendFactor));
|
||||
}
|
||||
|
||||
static const struct
|
||||
{
|
||||
enum vkd3d_dynamic_state_flag flag;
|
||||
VkDynamicState vk_state;
|
||||
}
|
||||
vkd3d_dynamic_state_list[] =
|
||||
{
|
||||
{ VKD3D_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT },
|
||||
{ VKD3D_DYNAMIC_STATE_SCISSOR, VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT },
|
||||
{ VKD3D_DYNAMIC_STATE_BLEND_CONSTANTS, VK_DYNAMIC_STATE_BLEND_CONSTANTS },
|
||||
{ VKD3D_DYNAMIC_STATE_STENCIL_REFERENCE, VK_DYNAMIC_STATE_STENCIL_REFERENCE },
|
||||
{ VKD3D_DYNAMIC_STATE_DEPTH_BOUNDS, VK_DYNAMIC_STATE_DEPTH_BOUNDS },
|
||||
{ VKD3D_DYNAMIC_STATE_TOPOLOGY, VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT },
|
||||
{ VKD3D_DYNAMIC_STATE_VERTEX_BUFFER_STRIDE, VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT },
|
||||
{ VKD3D_DYNAMIC_STATE_FRAGMENT_SHADING_RATE, VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR },
|
||||
{ VKD3D_DYNAMIC_STATE_PRIMITIVE_RESTART, VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT },
|
||||
};
|
||||
|
||||
static uint32_t d3d12_graphics_pipeline_state_init_dynamic_state(struct d3d12_pipeline_state *state,
|
||||
VkPipelineDynamicStateCreateInfo *dynamic_desc, VkDynamicState *dynamic_state_buffer,
|
||||
const struct vkd3d_pipeline_key *key)
|
||||
|
@ -2807,23 +2907,6 @@ static uint32_t d3d12_graphics_pipeline_state_init_dynamic_state(struct d3d12_pi
|
|||
uint32_t dynamic_state_flags;
|
||||
unsigned int i, count;
|
||||
|
||||
static const struct
|
||||
{
|
||||
enum vkd3d_dynamic_state_flag flag;
|
||||
VkDynamicState vk_state;
|
||||
}
|
||||
dynamic_state_list[] =
|
||||
{
|
||||
{ VKD3D_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT },
|
||||
{ VKD3D_DYNAMIC_STATE_SCISSOR, VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT },
|
||||
{ VKD3D_DYNAMIC_STATE_BLEND_CONSTANTS, VK_DYNAMIC_STATE_BLEND_CONSTANTS },
|
||||
{ VKD3D_DYNAMIC_STATE_STENCIL_REFERENCE, VK_DYNAMIC_STATE_STENCIL_REFERENCE },
|
||||
{ VKD3D_DYNAMIC_STATE_DEPTH_BOUNDS, VK_DYNAMIC_STATE_DEPTH_BOUNDS },
|
||||
{ VKD3D_DYNAMIC_STATE_TOPOLOGY, VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT },
|
||||
{ VKD3D_DYNAMIC_STATE_VERTEX_BUFFER_STRIDE, VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT },
|
||||
{ VKD3D_DYNAMIC_STATE_FRAGMENT_SHADING_RATE, VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR },
|
||||
};
|
||||
|
||||
dynamic_state_flags = 0;
|
||||
|
||||
/* Enable dynamic states as necessary */
|
||||
|
@ -2866,11 +2949,14 @@ static uint32_t d3d12_graphics_pipeline_state_init_dynamic_state(struct d3d12_pi
|
|||
if (d3d12_device_supports_variable_shading_rate_tier_1(state->device) && graphics->rt_count)
|
||||
dynamic_state_flags |= VKD3D_DYNAMIC_STATE_FRAGMENT_SHADING_RATE;
|
||||
|
||||
if (graphics->index_buffer_strip_cut_value)
|
||||
dynamic_state_flags |= VKD3D_DYNAMIC_STATE_PRIMITIVE_RESTART;
|
||||
|
||||
/* Build dynamic state create info */
|
||||
for (i = 0, count = 0; i < ARRAY_SIZE(dynamic_state_list); i++)
|
||||
for (i = 0, count = 0; i < ARRAY_SIZE(vkd3d_dynamic_state_list); i++)
|
||||
{
|
||||
if (dynamic_state_flags & dynamic_state_list[i].flag)
|
||||
dynamic_state_buffer[count++] = dynamic_state_list[i].vk_state;
|
||||
if (dynamic_state_flags & vkd3d_dynamic_state_list[i].flag)
|
||||
dynamic_state_buffer[count++] = vkd3d_dynamic_state_list[i].vk_state;
|
||||
}
|
||||
|
||||
dynamic_desc->sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
|
||||
|
@ -2887,7 +2973,37 @@ static HRESULT d3d12_pipeline_state_validate_blend_state(struct d3d12_pipeline_s
|
|||
const struct d3d12_pipeline_state_desc *desc, const struct vkd3d_shader_signature *sig)
|
||||
{
|
||||
const struct vkd3d_format *format;
|
||||
unsigned int i, j;
|
||||
unsigned int i, j, register_index;
|
||||
|
||||
if (is_dual_source_blending(&desc->blend_state.RenderTarget[0]))
|
||||
{
|
||||
/* If we enable dual source blending, we must fail an RT index > 0 which has
|
||||
* an IO-sig entry with non-NULL format. */
|
||||
for (i = 0; i < sig->element_count; i++)
|
||||
{
|
||||
register_index = sig->elements[i].register_index;
|
||||
if (register_index >= ARRAY_SIZE(desc->rtv_formats.RTFormats))
|
||||
{
|
||||
WARN("Register index %u out of bounds.\n", register_index);
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
if (register_index > 0)
|
||||
{
|
||||
if (desc->rtv_formats.RTFormats[register_index] != DXGI_FORMAT_UNKNOWN)
|
||||
{
|
||||
WARN("Cannot enable dual-source blending for active RT %u.\n", register_index);
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
if (desc->blend_state.IndependentBlendEnable && desc->blend_state.RenderTarget[i].BlendEnable)
|
||||
{
|
||||
WARN("Blend enable cannot be set for render target %u when dual source blending is used.\n", i);
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < desc->rtv_formats.NumRenderTargets; i++)
|
||||
{
|
||||
|
@ -2923,10 +3039,10 @@ static HRESULT d3d12_pipeline_state_validate_blend_state(struct d3d12_pipeline_s
|
|||
}
|
||||
|
||||
static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *state,
|
||||
struct d3d12_device *device, const struct d3d12_pipeline_state_desc *desc)
|
||||
struct d3d12_device *device, const struct d3d12_pipeline_state_desc *desc,
|
||||
const struct d3d12_cached_pipeline_state *cached_pso)
|
||||
{
|
||||
const VkPhysicalDeviceFeatures *features = &device->device_info.features2.features;
|
||||
bool have_attachment, is_dsv_format_unknown, can_compile_pipeline_early;
|
||||
unsigned int ps_output_swizzle[D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT];
|
||||
struct vkd3d_shader_compile_arguments compile_args, ps_compile_args;
|
||||
struct d3d12_graphics_pipeline_state *graphics = &state->graphics;
|
||||
|
@ -2939,6 +3055,7 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
|
|||
struct vkd3d_shader_transform_feedback_info xfb_info;
|
||||
struct vkd3d_shader_interface_info shader_interface;
|
||||
const struct d3d12_root_signature *root_signature;
|
||||
bool have_attachment, can_compile_pipeline_early;
|
||||
struct vkd3d_shader_signature output_signature;
|
||||
struct vkd3d_shader_signature input_signature;
|
||||
VkShaderStageFlagBits xfb_stage = 0;
|
||||
|
@ -2986,7 +3103,7 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
|
|||
if (desc->root_signature)
|
||||
root_signature = impl_from_ID3D12RootSignature(desc->root_signature);
|
||||
else
|
||||
root_signature = impl_from_ID3D12RootSignature(state->private_root_signature);
|
||||
root_signature = state->private_root_signature;
|
||||
|
||||
sample_count = vk_samples_from_dxgi_sample_desc(&desc->sample_desc);
|
||||
if (desc->sample_desc.Count != 1 && desc->sample_desc.Quality)
|
||||
|
@ -3000,6 +3117,14 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
|
|||
rt_count = ARRAY_SIZE(graphics->blend_attachments);
|
||||
}
|
||||
|
||||
if (!desc->ps.pShaderBytecode || !desc->ps.BytecodeLength)
|
||||
{
|
||||
/* Avoids validation errors where app might bind bogus RTV format which does not match the PSO.
|
||||
* D3D12 validation does not complain about this when PS is NULL since RTVs are not accessed to begin with.
|
||||
* We can just pretend we have no render targets in this case, which is fine. */
|
||||
rt_count = 0;
|
||||
}
|
||||
|
||||
graphics->null_attachment_mask = 0;
|
||||
graphics->rtv_active_mask = 0;
|
||||
for (i = 0; i < rt_count; ++i)
|
||||
|
@ -3143,25 +3268,9 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
|
|||
* Be defensive about programs which do not do this for us. */
|
||||
memset(graphics->blend_attachments + 1, 0,
|
||||
sizeof(graphics->blend_attachments[0]) * (ARRAY_SIZE(graphics->blend_attachments) - 1));
|
||||
}
|
||||
|
||||
if (compile_args.dual_source_blending && rt_count > 1)
|
||||
{
|
||||
WARN("Only one render target is allowed when dual source blending is used.\n");
|
||||
hr = E_INVALIDARG;
|
||||
goto fail;
|
||||
}
|
||||
if (compile_args.dual_source_blending && desc->blend_state.IndependentBlendEnable)
|
||||
{
|
||||
for (i = 1; i < ARRAY_SIZE(desc->blend_state.RenderTarget); ++i)
|
||||
{
|
||||
if (desc->blend_state.RenderTarget[i].BlendEnable)
|
||||
{
|
||||
WARN("Blend enable cannot be set for render target %u when dual source blending is used.\n", i);
|
||||
hr = E_INVALIDARG;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
/* Only allow RT 0 to be active for dual source blending. */
|
||||
graphics->rtv_active_mask &= 1u << 0;
|
||||
}
|
||||
|
||||
graphics->xfb_enabled = false;
|
||||
|
@ -3274,7 +3383,7 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
|
|||
if (!b->pShaderBytecode)
|
||||
continue;
|
||||
|
||||
if (FAILED(vkd3d_load_spirv_from_cached_state(device, &desc->cached_pso,
|
||||
if (FAILED(vkd3d_load_spirv_from_cached_state(device, cached_pso,
|
||||
shader_stages[i].stage, &graphics->code[stage_count])))
|
||||
{
|
||||
for (j = 0; j < stage_count; j++)
|
||||
|
@ -3484,10 +3593,9 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
|
|||
goto fail;
|
||||
}
|
||||
|
||||
is_dsv_format_unknown = graphics->null_attachment_mask & dsv_attachment_mask(graphics);
|
||||
|
||||
rs_desc_from_d3d12(&graphics->rs_desc, &desc->rasterizer_state);
|
||||
have_attachment = graphics->rt_count || graphics->dsv_format || is_dsv_format_unknown;
|
||||
have_attachment = graphics->rt_count || graphics->dsv_format ||
|
||||
d3d12_graphics_pipeline_state_has_unknown_dsv_format_with_test(graphics);
|
||||
if ((!have_attachment && !(desc->ps.pShaderBytecode && desc->ps.BytecodeLength))
|
||||
|| (graphics->xfb_enabled && so_desc->RasterizedStream == D3D12_SO_NO_RASTERIZED_STREAM))
|
||||
graphics->rs_desc.rasterizerDiscardEnable = VK_TRUE;
|
||||
|
@ -3534,9 +3642,9 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
|
|||
|
||||
if (can_compile_pipeline_early)
|
||||
{
|
||||
if (!device->global_pipeline_cache)
|
||||
if (!(vkd3d_config_flags & VKD3D_CONFIG_FLAG_GLOBAL_PIPELINE_CACHE))
|
||||
{
|
||||
if ((hr = vkd3d_create_pipeline_cache_from_d3d12_desc(device, &desc->cached_pso, &state->vk_pso_cache)) < 0)
|
||||
if ((hr = vkd3d_create_pipeline_cache_from_d3d12_desc(device, cached_pso, &state->vk_pso_cache)) < 0)
|
||||
{
|
||||
ERR("Failed to create pipeline cache, hr %d.\n", hr);
|
||||
goto fail;
|
||||
|
@ -3544,7 +3652,7 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
|
|||
}
|
||||
|
||||
if (!(graphics->pipeline = d3d12_pipeline_state_create_pipeline_variant(state, NULL, graphics->dsv_format,
|
||||
state->vk_pso_cache ? state->vk_pso_cache : device->global_pipeline_cache, &graphics->dynamic_state_flags)))
|
||||
state->vk_pso_cache, &graphics->dynamic_state_flags)))
|
||||
goto fail;
|
||||
}
|
||||
else
|
||||
|
@ -3586,21 +3694,32 @@ bool d3d12_pipeline_state_has_replaced_shaders(struct d3d12_pipeline_state *stat
|
|||
|
||||
static HRESULT d3d12_pipeline_create_private_root_signature(struct d3d12_device *device,
|
||||
VkPipelineBindPoint bind_point, const struct d3d12_pipeline_state_desc *desc,
|
||||
ID3D12RootSignature **root_signature)
|
||||
struct d3d12_root_signature **root_signature)
|
||||
{
|
||||
const struct D3D12_SHADER_BYTECODE *bytecode = bind_point == VK_PIPELINE_BIND_POINT_GRAPHICS ? &desc->vs : &desc->cs;
|
||||
ID3D12RootSignature *object = NULL;
|
||||
HRESULT hr;
|
||||
|
||||
if (!bytecode->BytecodeLength)
|
||||
return E_INVALIDARG;
|
||||
|
||||
return ID3D12Device_CreateRootSignature(&device->ID3D12Device_iface, 0,
|
||||
bytecode->pShaderBytecode, bytecode->BytecodeLength, &IID_ID3D12RootSignature, (void**)root_signature);
|
||||
if (FAILED(hr = ID3D12Device_CreateRootSignature(&device->ID3D12Device_iface, 0,
|
||||
bytecode->pShaderBytecode, bytecode->BytecodeLength,
|
||||
&IID_ID3D12RootSignature, (void**)&object)))
|
||||
return hr;
|
||||
|
||||
*root_signature = impl_from_ID3D12RootSignature(object);
|
||||
d3d12_root_signature_inc_ref(*root_signature);
|
||||
ID3D12RootSignature_Release(object);
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT d3d12_pipeline_state_create(struct d3d12_device *device, VkPipelineBindPoint bind_point,
|
||||
const struct d3d12_pipeline_state_desc *desc, struct d3d12_pipeline_state **state)
|
||||
{
|
||||
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
||||
const struct d3d12_cached_pipeline_state *desc_cached_pso;
|
||||
struct d3d12_cached_pipeline_state cached_pso;
|
||||
struct d3d12_root_signature *root_signature;
|
||||
struct d3d12_pipeline_state *object;
|
||||
HRESULT hr;
|
||||
|
@ -3619,7 +3738,7 @@ HRESULT d3d12_pipeline_state_create(struct d3d12_device *device, VkPipelineBindP
|
|||
vkd3d_free(object);
|
||||
return hr;
|
||||
}
|
||||
root_signature = impl_from_ID3D12RootSignature(object->private_root_signature);
|
||||
root_signature = object->private_root_signature;
|
||||
}
|
||||
else
|
||||
root_signature = impl_from_ID3D12RootSignature(desc->root_signature);
|
||||
|
@ -3628,18 +3747,45 @@ HRESULT d3d12_pipeline_state_create(struct d3d12_device *device, VkPipelineBindP
|
|||
if (root_signature)
|
||||
object->pipeline_cache_compat.root_signature_compat_hash = root_signature->compatibility_hash;
|
||||
|
||||
desc_cached_pso = &desc->cached_pso;
|
||||
|
||||
if (desc->cached_pso.blob.CachedBlobSizeInBytes)
|
||||
{
|
||||
if (FAILED(hr = d3d12_cached_pipeline_state_validate(device, &desc->cached_pso,
|
||||
&object->pipeline_cache_compat)))
|
||||
{
|
||||
if (object->private_root_signature)
|
||||
ID3D12RootSignature_Release(object->private_root_signature);
|
||||
d3d12_root_signature_dec_ref(object->private_root_signature);
|
||||
vkd3d_free(object);
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we rely on internal shader cache, the PSO blob app provides us might be a pure metadata blob,
|
||||
* and therefore kinda useless. Try to use disk cache blob instead.
|
||||
* Also, consider that we might have to serialize this pipeline if we don't find anything in disk cache. */
|
||||
if (d3d12_cached_pipeline_state_is_dummy(&desc->cached_pso))
|
||||
{
|
||||
memset(&cached_pso, 0, sizeof(cached_pso));
|
||||
desc_cached_pso = &cached_pso;
|
||||
}
|
||||
|
||||
if (desc_cached_pso->blob.CachedBlobSizeInBytes == 0 && device->disk_cache.library)
|
||||
{
|
||||
if (SUCCEEDED(vkd3d_pipeline_library_find_cached_blob_from_disk_cache(&device->disk_cache,
|
||||
&object->pipeline_cache_compat, &cached_pso)))
|
||||
{
|
||||
/* Validation is redundant. We only accept disk cache entries if checksum of disk blob passes.
|
||||
* The key is also entirely based on the PSO desc itself. */
|
||||
if ((vkd3d_config_flags & VKD3D_CONFIG_FLAG_PIPELINE_LIBRARY_LOG) &&
|
||||
desc->cached_pso.blob.CachedBlobSizeInBytes)
|
||||
{
|
||||
INFO("Application provided cached PSO blob, but we opted for disk cache blob instead.\n");
|
||||
}
|
||||
desc_cached_pso = &cached_pso;
|
||||
}
|
||||
}
|
||||
|
||||
object->ID3D12PipelineState_iface.lpVtbl = &d3d12_pipeline_state_vtbl;
|
||||
object->refcount = 1;
|
||||
object->internal_refcount = 1;
|
||||
|
@ -3647,11 +3793,11 @@ HRESULT d3d12_pipeline_state_create(struct d3d12_device *device, VkPipelineBindP
|
|||
switch (bind_point)
|
||||
{
|
||||
case VK_PIPELINE_BIND_POINT_COMPUTE:
|
||||
hr = d3d12_pipeline_state_init_compute(object, device, desc);
|
||||
hr = d3d12_pipeline_state_init_compute(object, device, desc, desc_cached_pso);
|
||||
break;
|
||||
|
||||
case VK_PIPELINE_BIND_POINT_GRAPHICS:
|
||||
hr = d3d12_pipeline_state_init_graphics(object, device, desc);
|
||||
hr = d3d12_pipeline_state_init_graphics(object, device, desc, desc_cached_pso);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -3662,7 +3808,7 @@ HRESULT d3d12_pipeline_state_create(struct d3d12_device *device, VkPipelineBindP
|
|||
if (FAILED(hr))
|
||||
{
|
||||
if (object->private_root_signature)
|
||||
ID3D12RootSignature_Release(object->private_root_signature);
|
||||
d3d12_root_signature_dec_ref(object->private_root_signature);
|
||||
d3d12_pipeline_state_free_spirv_code(object);
|
||||
d3d12_pipeline_state_destroy_shader_modules(object, device);
|
||||
VK_CALL(vkDestroyPipelineCache(device->vk_device, object->vk_pso_cache, NULL));
|
||||
|
@ -3680,7 +3826,7 @@ HRESULT d3d12_pipeline_state_create(struct d3d12_device *device, VkPipelineBindP
|
|||
* For graphics pipelines, we have to keep VkShaderModules around in case we need fallback pipelines.
|
||||
* If we keep the SPIR-V around in memory, we can always create shader modules on-demand in case we
|
||||
* need to actually create fallback pipelines. This avoids unnecessary memory bloat. */
|
||||
if (desc->cached_pso.blob.CachedBlobSizeInBytes ||
|
||||
if (desc_cached_pso->blob.CachedBlobSizeInBytes ||
|
||||
(vkd3d_config_flags & VKD3D_CONFIG_FLAG_PIPELINE_LIBRARY_NO_SERIALIZE_SPIRV))
|
||||
d3d12_pipeline_state_free_spirv_code(object);
|
||||
else
|
||||
|
@ -3688,11 +3834,18 @@ HRESULT d3d12_pipeline_state_create(struct d3d12_device *device, VkPipelineBindP
|
|||
|
||||
/* We don't expect to serialize the PSO blob if we loaded it from cache.
|
||||
* Free the cache now to save on memory. */
|
||||
if (desc->cached_pso.blob.CachedBlobSizeInBytes)
|
||||
if (desc_cached_pso->blob.CachedBlobSizeInBytes)
|
||||
{
|
||||
VK_CALL(vkDestroyPipelineCache(device->vk_device, object->vk_pso_cache, NULL));
|
||||
object->vk_pso_cache = VK_NULL_HANDLE;
|
||||
}
|
||||
else if (device->disk_cache.library)
|
||||
{
|
||||
/* We compiled this PSO without any cache (internal or app-provided),
|
||||
* so we should serialize this to internal disk cache.
|
||||
* Pushes work to disk$ thread. */
|
||||
vkd3d_pipeline_library_store_pipeline_to_disk_cache(&device->disk_cache, object);
|
||||
}
|
||||
|
||||
TRACE("Created pipeline state %p.\n", object);
|
||||
|
||||
|
@ -3856,14 +4009,13 @@ VkPipeline d3d12_pipeline_state_create_pipeline_variant(struct d3d12_pipeline_st
|
|||
{
|
||||
VkVertexInputBindingDescription bindings[D3D12_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT];
|
||||
const struct vkd3d_vk_device_procs *vk_procs = &state->device->vk_procs;
|
||||
VkDynamicState dynamic_state_buffer[VKD3D_MAX_DYNAMIC_STATE_COUNT];
|
||||
VkDynamicState dynamic_state_buffer[ARRAY_SIZE(vkd3d_dynamic_state_list)];
|
||||
struct d3d12_graphics_pipeline_state *graphics = &state->graphics;
|
||||
VkPipelineVertexInputDivisorStateCreateInfoEXT input_divisor_info;
|
||||
VkPipelineCreationFeedbackEXT feedbacks[VKD3D_MAX_SHADER_STAGES];
|
||||
VkPipelineShaderStageCreateInfo stages[VKD3D_MAX_SHADER_STAGES];
|
||||
VkFormat rtv_formats[D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT];
|
||||
VkPipelineTessellationStateCreateInfo tessellation_info;
|
||||
VkPipelineDepthStencilStateCreateInfo fallback_ds_desc;
|
||||
VkPipelineCreationFeedbackCreateInfoEXT feedback_info;
|
||||
VkPipelineDynamicStateCreateInfo dynamic_create_info;
|
||||
VkPipelineVertexInputStateCreateInfo input_desc;
|
||||
|
@ -3873,7 +4025,6 @@ VkPipeline d3d12_pipeline_state_create_pipeline_variant(struct d3d12_pipeline_st
|
|||
VkGraphicsPipelineCreateInfo pipeline_desc;
|
||||
VkPipelineViewportStateCreateInfo vp_desc;
|
||||
VkPipelineCreationFeedbackEXT feedback;
|
||||
uint32_t rtv_active_mask;
|
||||
VkPipeline vk_pipeline;
|
||||
unsigned int i;
|
||||
VkResult vr;
|
||||
|
@ -3936,15 +4087,19 @@ VkPipeline d3d12_pipeline_state_create_pipeline_variant(struct d3d12_pipeline_st
|
|||
rendering_info.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR;
|
||||
rendering_info.pNext = NULL;
|
||||
rendering_info.viewMask = 0;
|
||||
rendering_info.colorAttachmentCount = vkd3d_get_color_attachment_count(graphics->rtv_active_mask);
|
||||
rendering_info.colorAttachmentCount = graphics->rt_count;
|
||||
rendering_info.pColorAttachmentFormats = rtv_formats;
|
||||
rendering_info.depthAttachmentFormat = dsv_format ? dsv_format->vk_format : VK_FORMAT_UNDEFINED;
|
||||
rendering_info.stencilAttachmentFormat = dsv_format ? dsv_format->vk_format : VK_FORMAT_UNDEFINED;
|
||||
|
||||
rtv_active_mask = key ? key->rtv_active_mask : graphics->rtv_active_mask;
|
||||
/* From spec: If depthAttachmentFormat is not VK_FORMAT_UNDEFINED, it must be a format that includes a depth aspect. */
|
||||
rendering_info.depthAttachmentFormat = dsv_format && (dsv_format->vk_aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT) ?
|
||||
dsv_format->vk_format : VK_FORMAT_UNDEFINED;
|
||||
/* From spec: If stencilAttachmentFormat is not VK_FORMAT_UNDEFINED, it must be a format that includes a stencil aspect. */
|
||||
rendering_info.stencilAttachmentFormat = dsv_format && (dsv_format->vk_aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT) ?
|
||||
dsv_format->vk_format : VK_FORMAT_UNDEFINED;
|
||||
|
||||
for (i = 0; i < D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT; i++)
|
||||
{
|
||||
if (rtv_active_mask & (1u << i))
|
||||
if (graphics->rtv_active_mask & (1u << i))
|
||||
rtv_formats[i] = graphics->rtv_formats[i];
|
||||
else
|
||||
rtv_formats[i] = VK_FORMAT_UNDEFINED;
|
||||
|
@ -3975,27 +4130,8 @@ VkPipeline d3d12_pipeline_state_create_pipeline_variant(struct d3d12_pipeline_st
|
|||
|
||||
/* A workaround for SottR, which creates pipelines with DSV_UNKNOWN, but still insists on using a depth buffer.
|
||||
* If we notice that the base pipeline's DSV format does not match the dynamic DSV format, we fall-back to create a new render pass. */
|
||||
if (graphics->dsv_format != dsv_format && (graphics->null_attachment_mask & dsv_attachment_mask(graphics)))
|
||||
{
|
||||
TRACE("Compiling %p with fallback DSV format %#x.\n", state,
|
||||
dsv_format ? dsv_format->vk_format : VK_FORMAT_UNDEFINED);
|
||||
}
|
||||
else if (!dsv_format && graphics->dsv_format)
|
||||
{
|
||||
TRACE("Compiling %p with fallback NULL DSV format.\n", state);
|
||||
fallback_ds_desc = graphics->ds_desc;
|
||||
fallback_ds_desc.depthTestEnable = VK_FALSE;
|
||||
fallback_ds_desc.depthWriteEnable = VK_FALSE;
|
||||
fallback_ds_desc.depthBoundsTestEnable = VK_FALSE;
|
||||
fallback_ds_desc.stencilTestEnable = VK_FALSE;
|
||||
pipeline_desc.pDepthStencilState = &fallback_ds_desc;
|
||||
}
|
||||
|
||||
if (graphics->rtv_active_mask != rtv_active_mask)
|
||||
{
|
||||
TRACE("Compiling %p with fallback RTV write mask (PSO = 0x%x, RT = 0x%x).\n", state,
|
||||
state->graphics.rtv_active_mask, key->rtv_active_mask);
|
||||
}
|
||||
if (d3d12_graphics_pipeline_state_has_unknown_dsv_format_with_test(graphics) && dsv_format)
|
||||
TRACE("Compiling %p with fallback DSV format %#x.\n", state, dsv_format->vk_format);
|
||||
|
||||
graphics->dsv_plane_optimal_mask = d3d12_graphics_pipeline_state_get_plane_optimal_mask(graphics, dsv_format);
|
||||
|
||||
|
@ -4092,32 +4228,17 @@ static bool d3d12_pipeline_state_can_use_dynamic_stride(struct d3d12_pipeline_st
|
|||
}
|
||||
|
||||
VkPipeline d3d12_pipeline_state_get_pipeline(struct d3d12_pipeline_state *state,
|
||||
const struct vkd3d_dynamic_state *dyn_state, uint32_t rtv_nonnull_mask,
|
||||
const struct vkd3d_format *dsv_format, uint32_t *dynamic_state_flags)
|
||||
const struct vkd3d_dynamic_state *dyn_state, const struct vkd3d_format *dsv_format,
|
||||
uint32_t *dynamic_state_flags)
|
||||
{
|
||||
struct d3d12_graphics_pipeline_state *graphics = &state->graphics;
|
||||
|
||||
if (!graphics->pipeline)
|
||||
return VK_NULL_HANDLE;
|
||||
|
||||
/* Unknown DSV format workaround. */
|
||||
if ((dsv_format != graphics->dsv_format) && (graphics->dsv_format ||
|
||||
state->graphics.ds_desc.depthTestEnable ||
|
||||
state->graphics.ds_desc.stencilTestEnable ||
|
||||
state->graphics.ds_desc.depthBoundsTestEnable))
|
||||
if (d3d12_graphics_pipeline_state_has_unknown_dsv_format_with_test(graphics) && dsv_format)
|
||||
{
|
||||
TRACE("DSV format mismatch, expected %u, got %u, buggy application!\n",
|
||||
graphics->dsv_format ? graphics->dsv_format->vk_format : VK_FORMAT_UNDEFINED,
|
||||
dsv_format ? dsv_format->vk_format : VK_FORMAT_UNDEFINED);
|
||||
return VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
/* Case where we render to null or unbound RTV.
|
||||
* We'll need to nop out the attachments in the render pass / PSO. */
|
||||
if (state->graphics.rtv_active_mask & ~rtv_nonnull_mask)
|
||||
{
|
||||
TRACE("RTV mismatch. Writing to attachment mask 0x%x, but only 0x%x RTVs are bound.\n",
|
||||
state->graphics.rtv_active_mask, rtv_nonnull_mask);
|
||||
TRACE("Applying unknown DSV workaround with format %u buggy application!\n", dsv_format->vk_format);
|
||||
return VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
|
@ -4145,8 +4266,8 @@ VkPipeline d3d12_pipeline_state_get_pipeline(struct d3d12_pipeline_state *state,
|
|||
}
|
||||
|
||||
VkPipeline d3d12_pipeline_state_get_or_create_pipeline(struct d3d12_pipeline_state *state,
|
||||
const struct vkd3d_dynamic_state *dyn_state, uint32_t rtv_nonnull_mask,
|
||||
const struct vkd3d_format *dsv_format, uint32_t *dynamic_state_flags)
|
||||
const struct vkd3d_dynamic_state *dyn_state, const struct vkd3d_format *dsv_format,
|
||||
uint32_t *dynamic_state_flags)
|
||||
{
|
||||
const struct vkd3d_vk_device_procs *vk_procs = &state->device->vk_procs;
|
||||
struct d3d12_graphics_pipeline_state *graphics = &state->graphics;
|
||||
|
@ -4163,7 +4284,7 @@ VkPipeline d3d12_pipeline_state_get_or_create_pipeline(struct d3d12_pipeline_sta
|
|||
/* Try to keep as much dynamic state as possible so we don't have to rebind state unnecessarily. */
|
||||
|
||||
if (graphics->primitive_topology_type != D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH &&
|
||||
graphics->primitive_topology_type != D3D12_PRIMITIVE_TOPOLOGY_TYPE_UNDEFINED)
|
||||
graphics->primitive_topology_type != D3D12_PRIMITIVE_TOPOLOGY_TYPE_UNDEFINED)
|
||||
pipeline_key.dynamic_topology = true;
|
||||
else
|
||||
pipeline_key.topology = dyn_state->primitive_topology;
|
||||
|
@ -4189,7 +4310,6 @@ VkPipeline d3d12_pipeline_state_get_or_create_pipeline(struct d3d12_pipeline_sta
|
|||
}
|
||||
|
||||
pipeline_key.dsv_format = dsv_format ? dsv_format->vk_format : VK_FORMAT_UNDEFINED;
|
||||
pipeline_key.rtv_active_mask = state->graphics.rtv_active_mask & rtv_nonnull_mask;
|
||||
|
||||
if ((vk_pipeline = d3d12_pipeline_state_find_compiled_pipeline(state, &pipeline_key, dynamic_state_flags)))
|
||||
{
|
||||
|
@ -4594,7 +4714,10 @@ static uint32_t vkd3d_bindless_state_get_bindless_flags(struct d3d12_device *dev
|
|||
{
|
||||
flags |= VKD3D_BINDLESS_RAW_SSBO;
|
||||
|
||||
if (vkd3d_config_flags & VKD3D_CONFIG_FLAG_MUTABLE_SINGLE_SET)
|
||||
/* Intel GPUs have smol descriptor heaps and only way we can fit a D3D12 heap is with
|
||||
* single set mutable. */
|
||||
if ((vkd3d_config_flags & VKD3D_CONFIG_FLAG_MUTABLE_SINGLE_SET) ||
|
||||
device_info->properties2.properties.vendorID == VKD3D_VENDOR_ID_INTEL)
|
||||
{
|
||||
INFO("Enabling single descriptor set path for MUTABLE.\n");
|
||||
flags |= VKD3D_BINDLESS_MUTABLE_TYPE_RAW_SSBO;
|
||||
|
@ -4619,7 +4742,8 @@ static uint32_t vkd3d_bindless_state_get_bindless_flags(struct d3d12_device *dev
|
|||
* The difference in performance is profound (~15% in some cases).
|
||||
* On ACO, BDA with NonWritable can be promoted directly to scalar loads,
|
||||
* which is great. */
|
||||
if (device_info->properties2.properties.vendorID != VKD3D_VENDOR_ID_NVIDIA)
|
||||
if ((vkd3d_config_flags & VKD3D_CONFIG_FLAG_FORCE_RAW_VA_CBV) ||
|
||||
device_info->properties2.properties.vendorID != VKD3D_VENDOR_ID_NVIDIA)
|
||||
flags |= VKD3D_RAW_VA_ROOT_DESCRIPTOR_CBV;
|
||||
}
|
||||
|
||||
|
|
|
@ -804,11 +804,16 @@ static BOOL d3d12_swapchain_is_present_mode_supported(struct d3d12_swapchain *sw
|
|||
return supported;
|
||||
}
|
||||
|
||||
static BOOL d3d12_swapchain_has_user_images(struct d3d12_swapchain *swapchain)
|
||||
static bool d3d12_swapchain_has_user_images(struct d3d12_swapchain *swapchain)
|
||||
{
|
||||
return !!swapchain->vk_images[0];
|
||||
}
|
||||
|
||||
static bool d3d12_swapchain_has_user_descriptors(struct d3d12_swapchain *swapchain)
|
||||
{
|
||||
return swapchain->descriptors.pool != VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
static HRESULT d3d12_swapchain_get_user_graphics_pipeline(struct d3d12_swapchain *swapchain, VkFormat format)
|
||||
{
|
||||
struct d3d12_device *device = d3d12_swapchain_device(swapchain);
|
||||
|
@ -929,9 +934,6 @@ static HRESULT d3d12_swapchain_create_user_buffers(struct d3d12_swapchain *swapc
|
|||
HRESULT hr;
|
||||
UINT i;
|
||||
|
||||
if (d3d12_swapchain_has_user_images(swapchain))
|
||||
return S_OK;
|
||||
|
||||
heap_properties.Type = D3D12_HEAP_TYPE_DEFAULT;
|
||||
heap_properties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
|
||||
heap_properties.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
|
||||
|
@ -951,31 +953,38 @@ static HRESULT d3d12_swapchain_create_user_buffers(struct d3d12_swapchain *swapc
|
|||
resource_desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
|
||||
resource_desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
|
||||
|
||||
for (i = 0; i < swapchain->desc.BufferCount; i++)
|
||||
if (!d3d12_swapchain_has_user_images(swapchain))
|
||||
{
|
||||
if (FAILED(hr = d3d12_resource_create_committed(d3d12_swapchain_device(swapchain),
|
||||
&resource_desc, &heap_properties, D3D12_HEAP_FLAG_NONE,
|
||||
D3D12_RESOURCE_STATE_PRESENT, NULL, &object)))
|
||||
for (i = 0; i < swapchain->desc.BufferCount; i++)
|
||||
{
|
||||
ERR("Failed to create image for swapchain buffer");
|
||||
return hr;
|
||||
if (FAILED(hr = d3d12_resource_create_committed(d3d12_swapchain_device(swapchain),
|
||||
&resource_desc, &heap_properties, D3D12_HEAP_FLAG_NONE,
|
||||
D3D12_RESOURCE_STATE_PRESENT, NULL, NULL, &object)))
|
||||
{
|
||||
ERR("Failed to create image for swapchain buffer");
|
||||
return hr;
|
||||
}
|
||||
|
||||
swapchain->vk_images[i] = object->res.vk_image;
|
||||
swapchain->buffers[i] = (ID3D12Resource *)&object->ID3D12Resource_iface;
|
||||
|
||||
vkd3d_resource_incref(swapchain->buffers[i]);
|
||||
ID3D12Resource_Release(swapchain->buffers[i]);
|
||||
|
||||
/* It is technically possible to just start presenting images without rendering to them.
|
||||
* The initial resource state for swapchain images is PRESENT.
|
||||
* Since presentable images are dedicated allocations, we can safely queue a transition into common state
|
||||
* right away. We will also drain the queue when we release the images, so there is no risk of early delete. */
|
||||
vkd3d_enqueue_initial_transition(&swapchain->command_queue->ID3D12CommandQueue_iface, swapchain->buffers[i]);
|
||||
}
|
||||
|
||||
swapchain->vk_images[i] = object->res.vk_image;
|
||||
swapchain->buffers[i] = (ID3D12Resource *)&object->ID3D12Resource_iface;
|
||||
|
||||
vkd3d_resource_incref(swapchain->buffers[i]);
|
||||
ID3D12Resource_Release(swapchain->buffers[i]);
|
||||
|
||||
/* It is technically possible to just start presenting images without rendering to them.
|
||||
* The initial resource state for swapchain images is PRESENT.
|
||||
* Since presentable images are dedicated allocations, we can safely queue a transition into common state
|
||||
* right away. We will also drain the queue when we release the images, so there is no risk of early delete. */
|
||||
vkd3d_enqueue_initial_transition(&swapchain->command_queue->ID3D12CommandQueue_iface, swapchain->buffers[i]);
|
||||
}
|
||||
|
||||
if (FAILED(hr = d3d12_swapchain_create_user_descriptors(swapchain, vk_format)))
|
||||
return hr;
|
||||
/* If we don't have a swapchain pipeline layout yet (0x0 surface on first frame),
|
||||
* we cannot allocate any descriptors yet. We'll create the descriptors eventually
|
||||
* when we get a proper swapchain working. */
|
||||
if (!d3d12_swapchain_has_user_descriptors(swapchain) && swapchain->pipeline.vk_set_layout)
|
||||
if (FAILED(hr = d3d12_swapchain_create_user_descriptors(swapchain, vk_format)))
|
||||
return hr;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
@ -1226,8 +1235,6 @@ static HRESULT d3d12_swapchain_create_buffers(struct d3d12_swapchain *swapchain,
|
|||
VkResult vr;
|
||||
HRESULT hr;
|
||||
|
||||
d3d12_swapchain_destroy_views(swapchain);
|
||||
|
||||
if ((vr = VK_CALL(vkGetSwapchainImagesKHR(vk_device, vk_swapchain, &image_count, NULL))) < 0)
|
||||
{
|
||||
WARN("Failed to get Vulkan swapchain images, vr %d.\n", vr);
|
||||
|
@ -1320,7 +1327,7 @@ end:
|
|||
return vr;
|
||||
}
|
||||
|
||||
static void d3d12_swapchain_destroy_buffers(struct d3d12_swapchain *swapchain, BOOL destroy_user_buffers)
|
||||
static void d3d12_swapchain_destroy_resources(struct d3d12_swapchain *swapchain, bool destroy_user_buffers)
|
||||
{
|
||||
const struct vkd3d_vk_device_procs *vk_procs = d3d12_swapchain_procs(swapchain);
|
||||
VkQueue vk_queue;
|
||||
|
@ -1349,18 +1356,20 @@ static void d3d12_swapchain_destroy_buffers(struct d3d12_swapchain *swapchain, B
|
|||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < swapchain->desc.BufferCount; ++i)
|
||||
{
|
||||
if (swapchain->buffers[i] && destroy_user_buffers)
|
||||
{
|
||||
vkd3d_resource_decref(swapchain->buffers[i]);
|
||||
swapchain->buffers[i] = NULL;
|
||||
swapchain->vk_images[i] = VK_NULL_HANDLE;
|
||||
}
|
||||
}
|
||||
|
||||
if (destroy_user_buffers)
|
||||
{
|
||||
for (i = 0; i < swapchain->desc.BufferCount; ++i)
|
||||
{
|
||||
if (swapchain->buffers[i])
|
||||
{
|
||||
vkd3d_resource_decref(swapchain->buffers[i]);
|
||||
swapchain->buffers[i] = NULL;
|
||||
swapchain->vk_images[i] = VK_NULL_HANDLE;
|
||||
}
|
||||
}
|
||||
|
||||
d3d12_swapchain_destroy_user_descriptors(swapchain);
|
||||
}
|
||||
|
||||
if (swapchain->command_queue && swapchain->command_queue->device->vk_device)
|
||||
{
|
||||
|
@ -1379,6 +1388,8 @@ static void d3d12_swapchain_destroy_buffers(struct d3d12_swapchain *swapchain, B
|
|||
VK_CALL(vkDestroyCommandPool(swapchain->command_queue->device->vk_device, swapchain->vk_cmd_pool, NULL));
|
||||
swapchain->vk_cmd_pool = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
d3d12_swapchain_destroy_views(swapchain);
|
||||
}
|
||||
|
||||
static bool d3d12_swapchain_has_nonzero_surface_size(struct d3d12_swapchain *swapchain)
|
||||
|
@ -1398,7 +1409,7 @@ static bool d3d12_swapchain_has_nonzero_surface_size(struct d3d12_swapchain *swa
|
|||
return surface_caps.maxImageExtent.width != 0 && surface_caps.maxImageExtent.height != 0;
|
||||
}
|
||||
|
||||
static HRESULT d3d12_swapchain_create_vulkan_swapchain(struct d3d12_swapchain *swapchain)
|
||||
static HRESULT d3d12_swapchain_create_vulkan_swapchain(struct d3d12_swapchain *swapchain, bool force_surface_lost)
|
||||
{
|
||||
VkPhysicalDevice vk_physical_device = d3d12_swapchain_device(swapchain)->vk_physical_device;
|
||||
const struct vkd3d_vk_device_procs *vk_procs = d3d12_swapchain_procs(swapchain);
|
||||
|
@ -1409,9 +1420,9 @@ static HRESULT d3d12_swapchain_create_vulkan_swapchain(struct d3d12_swapchain *s
|
|||
unsigned int width, height, image_count;
|
||||
VkSurfaceCapabilitiesKHR surface_caps;
|
||||
unsigned int override_image_count;
|
||||
char count_env[VKD3D_PATH_MAX];
|
||||
VkSwapchainKHR vk_swapchain;
|
||||
VkImageUsageFlags usage;
|
||||
const char *count_env;
|
||||
VkResult vr;
|
||||
HRESULT hr;
|
||||
|
||||
|
@ -1425,8 +1436,19 @@ static HRESULT d3d12_swapchain_create_vulkan_swapchain(struct d3d12_swapchain *s
|
|||
swapchain->vk_surface, &swapchain->desc, &vk_swapchain_format)))
|
||||
return hr;
|
||||
|
||||
vr = VK_CALL(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(vk_physical_device,
|
||||
swapchain->vk_surface, &surface_caps));
|
||||
if (force_surface_lost)
|
||||
{
|
||||
/* If we cannot successfully present after 2 attempts, we must assume the swapchain
|
||||
* is in an unstable state with many resizes happening async. Until things stabilize,
|
||||
* force a dummy swapchain for now so that we can make forward progress.
|
||||
* When we don't have a proper swapchain, we will attempt again next present. */
|
||||
vr = VK_ERROR_SURFACE_LOST_KHR;
|
||||
}
|
||||
else
|
||||
{
|
||||
vr = VK_CALL(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(vk_physical_device,
|
||||
swapchain->vk_surface, &surface_caps));
|
||||
}
|
||||
|
||||
if (vr == VK_ERROR_SURFACE_LOST_KHR)
|
||||
{
|
||||
|
@ -1454,8 +1476,8 @@ static HRESULT d3d12_swapchain_create_vulkan_swapchain(struct d3d12_swapchain *s
|
|||
image_count = swapchain->desc.BufferCount + 1;
|
||||
image_count = max(image_count, surface_caps.minImageCount);
|
||||
|
||||
count_env = getenv("VKD3D_SWAPCHAIN_IMAGES");
|
||||
if (count_env)
|
||||
vkd3d_get_env_var("VKD3D_SWAPCHAIN_IMAGES", count_env, sizeof(count_env));
|
||||
if (strlen(count_env) > 0)
|
||||
{
|
||||
override_image_count = strtoul(count_env, NULL, 0);
|
||||
image_count = max(image_count, override_image_count);
|
||||
|
@ -1581,23 +1603,12 @@ static HRESULT d3d12_swapchain_create_vulkan_swapchain(struct d3d12_swapchain *s
|
|||
if (FAILED(hr = d3d12_swapchain_create_user_buffers(swapchain, vk_format)))
|
||||
return hr;
|
||||
|
||||
d3d12_swapchain_destroy_buffers(swapchain, FALSE);
|
||||
d3d12_swapchain_destroy_views(swapchain);
|
||||
d3d12_swapchain_destroy_resources(swapchain, false);
|
||||
swapchain->buffer_count = 0;
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT d3d12_swapchain_recreate_vulkan_swapchain(struct d3d12_swapchain *swapchain)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (FAILED(hr = d3d12_swapchain_create_vulkan_swapchain(swapchain)))
|
||||
ERR("Failed to recreate Vulkan swapchain, hr %#x.\n", hr);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static inline struct d3d12_swapchain *d3d12_swapchain_from_IDXGISwapChain(dxgi_swapchain_iface *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, struct d3d12_swapchain, IDXGISwapChain_iface);
|
||||
|
@ -1643,8 +1654,7 @@ static void d3d12_swapchain_destroy(struct d3d12_swapchain *swapchain)
|
|||
{
|
||||
const struct vkd3d_vk_device_procs *vk_procs = d3d12_swapchain_procs(swapchain);
|
||||
|
||||
d3d12_swapchain_destroy_buffers(swapchain, TRUE);
|
||||
d3d12_swapchain_destroy_views(swapchain);
|
||||
d3d12_swapchain_destroy_resources(swapchain, true);
|
||||
|
||||
if (swapchain->frame_latency_event)
|
||||
CloseHandle(swapchain->frame_latency_event);
|
||||
|
@ -1776,9 +1786,9 @@ static HRESULT d3d12_swapchain_set_sync_interval(struct d3d12_swapchain *swapcha
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
d3d12_swapchain_destroy_buffers(swapchain, FALSE);
|
||||
d3d12_swapchain_destroy_resources(swapchain, false);
|
||||
swapchain->present_mode = present_mode;
|
||||
return d3d12_swapchain_recreate_vulkan_swapchain(swapchain);
|
||||
return d3d12_swapchain_create_vulkan_swapchain(swapchain, false);
|
||||
}
|
||||
|
||||
static VkResult d3d12_swapchain_queue_present(struct d3d12_swapchain *swapchain, VkQueue vk_queue)
|
||||
|
@ -1796,6 +1806,11 @@ static VkResult d3d12_swapchain_queue_present(struct d3d12_swapchain *swapchain,
|
|||
if (swapchain->vk_swapchain == VK_NULL_HANDLE)
|
||||
return VK_SUCCESS;
|
||||
|
||||
/* If we know we're already suboptimal, e.g. observed in present or acquire after present,
|
||||
* just recreate the swapchain right away. */
|
||||
if (swapchain->is_suboptimal)
|
||||
return VK_ERROR_OUT_OF_DATE_KHR;
|
||||
|
||||
if (swapchain->vk_image_index == INVALID_VK_IMAGE_INDEX)
|
||||
{
|
||||
/* If we hit SUBOPTIMAL path last AcquireNextImageKHR, we will have a pending acquire we did not
|
||||
|
@ -1816,8 +1831,8 @@ static VkResult d3d12_swapchain_queue_present(struct d3d12_swapchain *swapchain,
|
|||
swapchain->vk_acquire_semaphores_signaled[swapchain->frame_id] = true;
|
||||
/* If we have observed suboptimal once, guarantees that we keep observing it
|
||||
* until we have recreated the swapchain. */
|
||||
if (swapchain->is_suboptimal)
|
||||
vr = VK_SUBOPTIMAL_KHR;
|
||||
if (vr == VK_SUBOPTIMAL_KHR)
|
||||
swapchain->is_suboptimal = true;
|
||||
}
|
||||
|
||||
if (vr == VK_SUBOPTIMAL_KHR)
|
||||
|
@ -1893,12 +1908,11 @@ static VkResult d3d12_swapchain_queue_present(struct d3d12_swapchain *swapchain,
|
|||
swapchain->frame_id = (swapchain->frame_id + 1) % swapchain->buffer_count;
|
||||
swapchain->vk_image_index = INVALID_VK_IMAGE_INDEX;
|
||||
|
||||
if (vr == VK_SUBOPTIMAL_KHR)
|
||||
swapchain->is_suboptimal = true;
|
||||
|
||||
/* If we have observed suboptimal once, guarantees that we keep observing it
|
||||
* until we have recreated the swapchain. */
|
||||
if (swapchain->is_suboptimal)
|
||||
if (vr == VK_SUBOPTIMAL_KHR)
|
||||
swapchain->is_suboptimal = true;
|
||||
else if (swapchain->is_suboptimal)
|
||||
vr = VK_SUBOPTIMAL_KHR;
|
||||
|
||||
/* Could get SUBOPTIMAL here. Defer acquiring if we hit that path.
|
||||
|
@ -1931,6 +1945,8 @@ static VkResult d3d12_swapchain_queue_present(struct d3d12_swapchain *swapchain,
|
|||
swapchain->vk_image_index = INVALID_VK_IMAGE_INDEX;
|
||||
}
|
||||
}
|
||||
|
||||
/* Not being able to successfully acquire here is okay, we'll defer the acquire to next frame. */
|
||||
vr = VK_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1974,15 +1990,17 @@ static HRESULT d3d12_swapchain_present(struct d3d12_swapchain *swapchain,
|
|||
return E_FAIL;
|
||||
}
|
||||
|
||||
/* We must have some kind of forward progress here. Keep trying until we exhaust all possible avenues. */
|
||||
vr = d3d12_swapchain_queue_present(swapchain, vk_queue);
|
||||
if (vr == VK_ERROR_OUT_OF_DATE_KHR)
|
||||
if (vr < 0)
|
||||
{
|
||||
vkd3d_release_vk_queue(d3d12_swapchain_queue_iface(swapchain));
|
||||
|
||||
TRACE("Recreating Vulkan swapchain.\n");
|
||||
|
||||
d3d12_swapchain_destroy_buffers(swapchain, FALSE);
|
||||
if (FAILED(hr = d3d12_swapchain_recreate_vulkan_swapchain(swapchain)))
|
||||
d3d12_swapchain_destroy_resources(swapchain, false);
|
||||
|
||||
if (FAILED(hr = d3d12_swapchain_create_vulkan_swapchain(swapchain, false)))
|
||||
return hr;
|
||||
|
||||
if (!(vk_queue = vkd3d_acquire_vk_queue(d3d12_swapchain_queue_iface(swapchain))))
|
||||
|
@ -1992,7 +2010,22 @@ static HRESULT d3d12_swapchain_present(struct d3d12_swapchain *swapchain,
|
|||
}
|
||||
|
||||
if ((vr = d3d12_swapchain_queue_present(swapchain, vk_queue)) < 0)
|
||||
ERR("Failed to present after recreating swapchain, vr %d.\n", vr);
|
||||
{
|
||||
ERR("Failed to present after recreating swapchain, vr %d. Attempting fallback swapchain.\n", vr);
|
||||
vkd3d_release_vk_queue(d3d12_swapchain_queue_iface(swapchain));
|
||||
d3d12_swapchain_destroy_resources(swapchain, false);
|
||||
if (FAILED(hr = d3d12_swapchain_create_vulkan_swapchain(swapchain, true)))
|
||||
return hr;
|
||||
|
||||
if (!(vk_queue = vkd3d_acquire_vk_queue(d3d12_swapchain_queue_iface(swapchain))))
|
||||
{
|
||||
ERR("Failed to acquire Vulkan queue.\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
if ((vr = d3d12_swapchain_queue_present(swapchain, vk_queue)) < 0)
|
||||
ERR("Failed to present even after creating dummy swapchain, vr %d. This should not be possible.\n", vr);
|
||||
}
|
||||
}
|
||||
|
||||
vkd3d_release_vk_queue(d3d12_swapchain_queue_iface(swapchain));
|
||||
|
@ -2272,9 +2305,9 @@ static HRESULT d3d12_swapchain_resize_buffers(struct d3d12_swapchain *swapchain,
|
|||
&& desc->Format == new_desc.Format && desc->BufferCount == new_desc.BufferCount)
|
||||
return S_OK;
|
||||
|
||||
d3d12_swapchain_destroy_buffers(swapchain, TRUE);
|
||||
d3d12_swapchain_destroy_resources(swapchain, true);
|
||||
swapchain->desc = new_desc;
|
||||
return d3d12_swapchain_recreate_vulkan_swapchain(swapchain);
|
||||
return d3d12_swapchain_create_vulkan_swapchain(swapchain, false);
|
||||
}
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE d3d12_swapchain_ResizeBuffers(dxgi_swapchain_iface *iface,
|
||||
|
@ -2855,7 +2888,7 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IDXGIFact
|
|||
ID3D12CommandQueue_AddRef(&queue->ID3D12CommandQueue_iface);
|
||||
d3d12_device_add_ref(queue->device);
|
||||
|
||||
if (FAILED(hr = d3d12_swapchain_create_vulkan_swapchain(swapchain)))
|
||||
if (FAILED(hr = d3d12_swapchain_create_vulkan_swapchain(swapchain, false)))
|
||||
{
|
||||
d3d12_swapchain_destroy(swapchain);
|
||||
return hr;
|
||||
|
|
|
@ -1018,6 +1018,16 @@ HRESULT hresult_from_errno(int rc)
|
|||
|
||||
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)
|
||||
{
|
||||
case VK_SUCCESS:
|
||||
|
|
|
@ -165,15 +165,28 @@ static CONST_VTBL struct ID3D12RootSignatureDeserializerVtbl d3d12_root_signatur
|
|||
|
||||
static int vkd3d_parse_root_signature_for_version(const struct vkd3d_shader_code *dxbc,
|
||||
struct vkd3d_versioned_root_signature_desc *out_desc,
|
||||
enum vkd3d_root_signature_version target_version)
|
||||
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;
|
||||
int ret;
|
||||
|
||||
if ((ret = vkd3d_shader_parse_root_signature(dxbc, &desc)) < 0)
|
||||
if (raw_payload)
|
||||
{
|
||||
WARN("Failed to parse root signature, vkd3d result %d.\n", ret);
|
||||
return ret;
|
||||
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);
|
||||
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)
|
||||
|
@ -197,15 +210,27 @@ static int vkd3d_parse_root_signature_for_version(const struct vkd3d_shader_code
|
|||
}
|
||||
|
||||
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,
|
||||
vkd3d_shader_hash_t *compatibility_hash)
|
||||
{
|
||||
return vkd3d_parse_root_signature_for_version(dxbc, out_desc, VKD3D_ROOT_SIGNATURE_VERSION_1_0);
|
||||
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)
|
||||
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);
|
||||
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,
|
||||
|
@ -216,7 +241,7 @@ static HRESULT d3d12_root_signature_deserializer_init(struct d3d12_root_signatur
|
|||
deserializer->ID3D12RootSignatureDeserializer_iface.lpVtbl = &d3d12_root_signature_deserializer_vtbl;
|
||||
deserializer->refcount = 1;
|
||||
|
||||
if ((ret = vkd3d_parse_root_signature_v_1_0(dxbc, &deserializer->desc.vkd3d)) < 0)
|
||||
if ((ret = vkd3d_parse_root_signature_v_1_0(dxbc, &deserializer->desc.vkd3d, NULL)) < 0)
|
||||
return hresult_from_vkd3d_result(ret);
|
||||
|
||||
return S_OK;
|
||||
|
@ -394,7 +419,7 @@ static HRESULT d3d12_versioned_root_signature_deserializer_init(struct d3d12_ver
|
|||
deserializer->ID3D12VersionedRootSignatureDeserializer_iface.lpVtbl = &d3d12_versioned_root_signature_deserializer_vtbl;
|
||||
deserializer->refcount = 1;
|
||||
|
||||
if ((ret = vkd3d_shader_parse_root_signature(dxbc, &deserializer->desc.vkd3d)) < 0)
|
||||
if ((ret = vkd3d_shader_parse_root_signature(dxbc, &deserializer->desc.vkd3d, NULL)) < 0)
|
||||
{
|
||||
WARN("Failed to parse root signature, vkd3d result %d.\n", ret);
|
||||
return hresult_from_vkd3d_result(ret);
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include "vkd3d_command_list_vkd3d_ext.h"
|
||||
#include "vkd3d_device_vkd3d_ext.h"
|
||||
#include "vkd3d_string.h"
|
||||
#include "vkd3d_file_utils.h"
|
||||
#include <assert.h>
|
||||
#include <inttypes.h>
|
||||
#include <limits.h>
|
||||
|
@ -49,7 +50,6 @@
|
|||
#define MAKE_MAGIC(a,b,c,d) (((uint32_t)a) | (((uint32_t)b) << 8) | (((uint32_t)c) << 16) | (((uint32_t)d) << 24))
|
||||
|
||||
#define VKD3D_MAX_COMPATIBLE_FORMAT_COUNT 10u
|
||||
#define VKD3D_MAX_SHADER_EXTENSIONS 6u
|
||||
#define VKD3D_MAX_SHADER_STAGES 5u
|
||||
#define VKD3D_MAX_VK_SYNC_OBJECTS 4u
|
||||
|
||||
|
@ -61,6 +61,8 @@
|
|||
|
||||
#define VKD3D_TILE_SIZE 65536
|
||||
|
||||
typedef ID3D12Fence1 d3d12_fence_iface;
|
||||
|
||||
struct d3d12_command_list;
|
||||
struct d3d12_device;
|
||||
struct d3d12_resource;
|
||||
|
@ -129,7 +131,14 @@ struct vkd3d_vulkan_info
|
|||
bool KHR_bind_memory2;
|
||||
bool KHR_copy_commands2;
|
||||
bool KHR_dynamic_rendering;
|
||||
bool KHR_depth_stencil_resolve;
|
||||
bool KHR_driver_properties;
|
||||
bool KHR_uniform_buffer_standard_layout;
|
||||
bool KHR_maintenance4;
|
||||
bool KHR_ray_tracing_maintenance1;
|
||||
bool KHR_fragment_shader_barycentric;
|
||||
bool KHR_external_memory_win32;
|
||||
bool KHR_external_semaphore_win32;
|
||||
/* EXT device extensions */
|
||||
bool EXT_calibrated_timestamps;
|
||||
bool EXT_conditional_rendering;
|
||||
|
@ -149,6 +158,7 @@ struct vkd3d_vulkan_info
|
|||
bool EXT_transform_feedback;
|
||||
bool EXT_vertex_attribute_divisor;
|
||||
bool EXT_extended_dynamic_state;
|
||||
bool EXT_extended_dynamic_state2;
|
||||
bool EXT_external_memory_host;
|
||||
bool EXT_4444_formats;
|
||||
bool EXT_shader_image_atomic_int64;
|
||||
|
@ -166,6 +176,7 @@ struct vkd3d_vulkan_info
|
|||
bool NV_fragment_shader_barycentric;
|
||||
bool NV_compute_shader_derivatives;
|
||||
bool NV_device_diagnostic_checkpoints;
|
||||
bool NV_device_generated_commands;
|
||||
/* VALVE extensions */
|
||||
bool VALVE_mutable_descriptor_type;
|
||||
bool VALVE_descriptor_set_host_mapping;
|
||||
|
@ -182,7 +193,7 @@ struct vkd3d_vulkan_info
|
|||
VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT texel_buffer_alignment_properties;
|
||||
|
||||
unsigned int shader_extension_count;
|
||||
enum vkd3d_shader_target_extension shader_extensions[VKD3D_MAX_SHADER_EXTENSIONS];
|
||||
enum vkd3d_shader_target_extension shader_extensions[VKD3D_SHADER_TARGET_EXTENSION_COUNT];
|
||||
};
|
||||
|
||||
struct vkd3d_instance
|
||||
|
@ -219,8 +230,12 @@ HRESULT vkd3d_join_thread(struct vkd3d_instance *instance, union vkd3d_thread_ha
|
|||
|
||||
struct vkd3d_waiting_fence
|
||||
{
|
||||
struct d3d12_fence *fence;
|
||||
d3d12_fence_iface *fence;
|
||||
VkSemaphore submission_timeline;
|
||||
uint64_t value;
|
||||
LONG **submission_counters;
|
||||
size_t num_submission_counts;
|
||||
bool signal;
|
||||
};
|
||||
|
||||
struct vkd3d_fence_worker
|
||||
|
@ -501,8 +516,6 @@ static inline HRESULT vkd3d_set_private_data_interface(struct vkd3d_private_stor
|
|||
HRESULT STDMETHODCALLTYPE d3d12_object_SetName(ID3D12Object *iface, const WCHAR *name);
|
||||
|
||||
/* ID3D12Fence */
|
||||
typedef ID3D12Fence1 d3d12_fence_iface;
|
||||
|
||||
struct d3d12_fence_value
|
||||
{
|
||||
uint64_t virtual_value;
|
||||
|
@ -572,6 +585,52 @@ HRESULT d3d12_fence_create(struct d3d12_device *device,
|
|||
HRESULT d3d12_fence_set_event_on_completion(struct d3d12_fence *fence,
|
||||
UINT64 value, HANDLE event, enum vkd3d_waiting_event_type type);
|
||||
|
||||
struct d3d12_shared_fence
|
||||
{
|
||||
d3d12_fence_iface ID3D12Fence_iface;
|
||||
LONG refcount_internal;
|
||||
LONG refcount;
|
||||
|
||||
D3D12_FENCE_FLAGS d3d12_flags;
|
||||
|
||||
VkSemaphore timeline_semaphore;
|
||||
|
||||
struct d3d12_device *device;
|
||||
|
||||
struct vkd3d_private_store private_store;
|
||||
};
|
||||
|
||||
static inline struct d3d12_shared_fence *shared_impl_from_ID3D12Fence1(ID3D12Fence1 *iface)
|
||||
{
|
||||
extern CONST_VTBL struct ID3D12Fence1Vtbl d3d12_shared_fence_vtbl;
|
||||
if (!iface)
|
||||
return NULL;
|
||||
assert(iface->lpVtbl == &d3d12_shared_fence_vtbl);
|
||||
return CONTAINING_RECORD(iface, struct d3d12_shared_fence, ID3D12Fence_iface);
|
||||
}
|
||||
|
||||
static inline struct d3d12_shared_fence *shared_impl_from_ID3D12Fence(ID3D12Fence *iface)
|
||||
{
|
||||
return shared_impl_from_ID3D12Fence1((ID3D12Fence1 *)iface);
|
||||
}
|
||||
|
||||
HRESULT d3d12_shared_fence_create(struct d3d12_device *device,
|
||||
uint64_t initial_value, D3D12_FENCE_FLAGS flags, struct d3d12_shared_fence **fence);
|
||||
|
||||
static inline bool is_shared_ID3D12Fence1(ID3D12Fence1 *iface)
|
||||
{
|
||||
extern CONST_VTBL struct ID3D12Fence1Vtbl d3d12_shared_fence_vtbl;
|
||||
extern CONST_VTBL struct ID3D12Fence1Vtbl d3d12_fence_vtbl;
|
||||
assert(iface->lpVtbl == &d3d12_shared_fence_vtbl || iface->lpVtbl == &d3d12_fence_vtbl);
|
||||
|
||||
return iface->lpVtbl == &d3d12_shared_fence_vtbl;
|
||||
}
|
||||
|
||||
static inline bool is_shared_ID3D12Fence(ID3D12Fence *iface)
|
||||
{
|
||||
return is_shared_ID3D12Fence1((ID3D12Fence1 *)iface);
|
||||
}
|
||||
|
||||
enum vkd3d_allocation_flag
|
||||
{
|
||||
VKD3D_ALLOCATION_FLAG_GLOBAL_BUFFER = (1u << 0),
|
||||
|
@ -580,6 +639,10 @@ enum vkd3d_allocation_flag
|
|||
VKD3D_ALLOCATION_FLAG_ALLOW_WRITE_WATCH = (1u << 3),
|
||||
VKD3D_ALLOCATION_FLAG_NO_FALLBACK = (1u << 4),
|
||||
VKD3D_ALLOCATION_FLAG_DEDICATED = (1u << 5),
|
||||
/* Intended for internal allocation of scratch buffers.
|
||||
* They are never suballocated since we do that ourselves,
|
||||
* and we do not consume space in the VA map. */
|
||||
VKD3D_ALLOCATION_FLAG_INTERNAL_SCRATCH = (1u << 6),
|
||||
};
|
||||
|
||||
#define VKD3D_MEMORY_CHUNK_SIZE (VKD3D_VA_BLOCK_SIZE * 8)
|
||||
|
@ -601,6 +664,7 @@ struct vkd3d_allocate_heap_memory_info
|
|||
{
|
||||
D3D12_HEAP_DESC heap_desc;
|
||||
void *host_ptr;
|
||||
uint32_t extra_allocation_flags;
|
||||
};
|
||||
|
||||
struct vkd3d_allocate_resource_memory_info
|
||||
|
@ -892,7 +956,7 @@ VkImageSubresource vk_image_subresource_from_d3d12(
|
|||
|
||||
HRESULT d3d12_resource_create_committed(struct d3d12_device *device, const D3D12_RESOURCE_DESC1 *desc,
|
||||
const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags, D3D12_RESOURCE_STATES initial_state,
|
||||
const D3D12_CLEAR_VALUE *optimized_clear_value, struct d3d12_resource **resource);
|
||||
const D3D12_CLEAR_VALUE *optimized_clear_value, HANDLE shared_handle, struct d3d12_resource **resource);
|
||||
HRESULT d3d12_resource_create_placed(struct d3d12_device *device, const D3D12_RESOURCE_DESC1 *desc,
|
||||
struct d3d12_heap *heap, uint64_t heap_offset, D3D12_RESOURCE_STATES initial_state,
|
||||
const D3D12_CLEAR_VALUE *optimized_clear_value, struct d3d12_resource **resource);
|
||||
|
@ -986,6 +1050,7 @@ struct vkd3d_texture_view_desc
|
|||
VkImage image;
|
||||
VkImageViewType view_type;
|
||||
VkImageAspectFlags aspect_mask;
|
||||
VkImageUsageFlags image_usage;
|
||||
const struct vkd3d_format *format;
|
||||
unsigned int miplevel_idx;
|
||||
unsigned int miplevel_count;
|
||||
|
@ -1069,6 +1134,9 @@ void d3d12_desc_create_uav(vkd3d_cpu_descriptor_va_t descriptor, struct d3d12_de
|
|||
void d3d12_desc_create_sampler(vkd3d_cpu_descriptor_va_t sampler,
|
||||
struct d3d12_device *device, const D3D12_SAMPLER_DESC *desc);
|
||||
|
||||
bool vkd3d_create_vk_buffer_view(struct d3d12_device *device,
|
||||
VkBuffer vk_buffer, const struct vkd3d_format *format,
|
||||
VkDeviceSize offset, VkDeviceSize range, VkBufferView *vk_view);
|
||||
bool vkd3d_create_raw_buffer_view(struct d3d12_device *device,
|
||||
D3D12_GPU_VIRTUAL_ADDRESS gpu_address, VkBufferView *vk_buffer_view);
|
||||
HRESULT d3d12_create_static_sampler(struct d3d12_device *device,
|
||||
|
@ -1327,6 +1395,7 @@ struct d3d12_root_signature
|
|||
{
|
||||
ID3D12RootSignature ID3D12RootSignature_iface;
|
||||
LONG refcount;
|
||||
LONG internal_refcount;
|
||||
|
||||
vkd3d_shader_hash_t compatibility_hash;
|
||||
|
||||
|
@ -1386,6 +1455,13 @@ struct d3d12_root_signature
|
|||
|
||||
HRESULT d3d12_root_signature_create(struct d3d12_device *device, const void *bytecode,
|
||||
size_t bytecode_length, struct d3d12_root_signature **root_signature);
|
||||
HRESULT d3d12_root_signature_create_raw(struct d3d12_device *device, const void *payload,
|
||||
size_t payload_size, struct d3d12_root_signature **root_signature);
|
||||
HRESULT d3d12_root_signature_create_empty(struct d3d12_device *device,
|
||||
struct d3d12_root_signature **root_signature);
|
||||
/* Private ref counts, for pipeline library. */
|
||||
void d3d12_root_signature_inc_ref(struct d3d12_root_signature *state);
|
||||
void d3d12_root_signature_dec_ref(struct d3d12_root_signature *state);
|
||||
|
||||
static inline struct d3d12_root_signature *impl_from_ID3D12RootSignature(ID3D12RootSignature *iface)
|
||||
{
|
||||
|
@ -1405,9 +1481,14 @@ HRESULT vkd3d_create_pipeline_layout(struct d3d12_device *device,
|
|||
VkPipelineLayout *pipeline_layout);
|
||||
|
||||
int vkd3d_parse_root_signature_v_1_0(const struct vkd3d_shader_code *dxbc,
|
||||
struct vkd3d_versioned_root_signature_desc *desc);
|
||||
struct vkd3d_versioned_root_signature_desc *desc,
|
||||
vkd3d_shader_hash_t *compatibility_hash);
|
||||
int vkd3d_parse_root_signature_v_1_1(const struct vkd3d_shader_code *dxbc,
|
||||
struct vkd3d_versioned_root_signature_desc *desc);
|
||||
struct vkd3d_versioned_root_signature_desc *desc,
|
||||
vkd3d_shader_hash_t *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 *desc,
|
||||
vkd3d_shader_hash_t *compatibility_hash);
|
||||
|
||||
VkShaderStageFlags vkd3d_vk_stage_flags_from_visibility(D3D12_SHADER_VISIBILITY visibility);
|
||||
enum vkd3d_shader_visibility vkd3d_shader_visibility_from_d3d12(D3D12_SHADER_VISIBILITY visibility);
|
||||
|
@ -1415,8 +1496,6 @@ HRESULT vkd3d_create_descriptor_set_layout(struct d3d12_device *device,
|
|||
VkDescriptorSetLayoutCreateFlags flags, unsigned int binding_count,
|
||||
const VkDescriptorSetLayoutBinding *bindings, VkDescriptorSetLayout *set_layout);
|
||||
|
||||
#define VKD3D_MAX_DYNAMIC_STATE_COUNT (7)
|
||||
|
||||
enum vkd3d_dynamic_state_flag
|
||||
{
|
||||
VKD3D_DYNAMIC_STATE_VIEWPORT = (1 << 0),
|
||||
|
@ -1428,6 +1507,7 @@ enum vkd3d_dynamic_state_flag
|
|||
VKD3D_DYNAMIC_STATE_VERTEX_BUFFER = (1 << 6),
|
||||
VKD3D_DYNAMIC_STATE_VERTEX_BUFFER_STRIDE = (1 << 7),
|
||||
VKD3D_DYNAMIC_STATE_FRAGMENT_SHADING_RATE = (1 << 8),
|
||||
VKD3D_DYNAMIC_STATE_PRIMITIVE_RESTART = (1 << 9),
|
||||
};
|
||||
|
||||
struct vkd3d_shader_debug_ring_spec_constants
|
||||
|
@ -1438,10 +1518,11 @@ struct vkd3d_shader_debug_ring_spec_constants
|
|||
uint32_t ring_words;
|
||||
};
|
||||
|
||||
#define VKD3D_SHADER_DEBUG_RING_SPEC_INFO_MAP_ENTRIES 4
|
||||
struct vkd3d_shader_debug_ring_spec_info
|
||||
{
|
||||
struct vkd3d_shader_debug_ring_spec_constants constants;
|
||||
VkSpecializationMapEntry map_entries[4];
|
||||
VkSpecializationMapEntry map_entries[VKD3D_SHADER_DEBUG_RING_SPEC_INFO_MAP_ENTRIES];
|
||||
VkSpecializationInfo spec_info;
|
||||
};
|
||||
|
||||
|
@ -1537,7 +1618,7 @@ struct d3d12_pipeline_state
|
|||
spinlock_t lock;
|
||||
|
||||
struct vkd3d_pipeline_cache_compatibility pipeline_cache_compat;
|
||||
ID3D12RootSignature *private_root_signature;
|
||||
struct d3d12_root_signature *private_root_signature;
|
||||
struct d3d12_device *device;
|
||||
|
||||
struct vkd3d_private_store private_store;
|
||||
|
@ -1553,7 +1634,9 @@ static inline bool d3d12_pipeline_state_is_graphics(const struct d3d12_pipeline_
|
|||
return state && state->vk_bind_point == VK_PIPELINE_BIND_POINT_GRAPHICS;
|
||||
}
|
||||
|
||||
static inline bool d3d12_graphics_pipeline_state_has_unknown_dsv_format(
|
||||
/* This returns true for invalid D3D12 API usage. Game intends to use depth-stencil tests,
|
||||
* but we don't know the format until bind time. Some games like SottR rely on this to work ... somehow. */
|
||||
static inline bool d3d12_graphics_pipeline_state_has_unknown_dsv_format_with_test(
|
||||
const struct d3d12_graphics_pipeline_state *graphics)
|
||||
{
|
||||
return graphics->null_attachment_mask & dsv_attachment_mask(graphics);
|
||||
|
@ -1605,12 +1688,26 @@ HRESULT vkd3d_pipeline_state_desc_from_d3d12_compute_desc(struct d3d12_pipeline_
|
|||
HRESULT vkd3d_pipeline_state_desc_from_d3d12_stream_desc(struct d3d12_pipeline_state_desc *desc,
|
||||
const D3D12_PIPELINE_STATE_STREAM_DESC *d3d12_desc, VkPipelineBindPoint *vk_bind_point);
|
||||
|
||||
static inline bool vk_primitive_topology_supports_restart(VkPrimitiveTopology topology)
|
||||
{
|
||||
switch (topology)
|
||||
{
|
||||
case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
|
||||
case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:
|
||||
case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
|
||||
case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
struct vkd3d_pipeline_key
|
||||
{
|
||||
D3D12_PRIMITIVE_TOPOLOGY topology;
|
||||
uint32_t viewport_count;
|
||||
uint32_t strides[D3D12_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT];
|
||||
uint32_t rtv_active_mask;
|
||||
VkFormat dsv_format;
|
||||
|
||||
bool dynamic_stride;
|
||||
|
@ -1621,11 +1718,11 @@ bool d3d12_pipeline_state_has_replaced_shaders(struct d3d12_pipeline_state *stat
|
|||
HRESULT d3d12_pipeline_state_create(struct d3d12_device *device, VkPipelineBindPoint bind_point,
|
||||
const struct d3d12_pipeline_state_desc *desc, struct d3d12_pipeline_state **state);
|
||||
VkPipeline d3d12_pipeline_state_get_or_create_pipeline(struct d3d12_pipeline_state *state,
|
||||
const struct vkd3d_dynamic_state *dyn_state, uint32_t rtv_nonnull_mask,
|
||||
const struct vkd3d_format *dsv_format, uint32_t *dynamic_state_flags);
|
||||
const struct vkd3d_dynamic_state *dyn_state, const struct vkd3d_format *dsv_format,
|
||||
uint32_t *dynamic_state_flags);
|
||||
VkPipeline d3d12_pipeline_state_get_pipeline(struct d3d12_pipeline_state *state,
|
||||
const struct vkd3d_dynamic_state *dyn_state, uint32_t rtv_nonnull_mask,
|
||||
const struct vkd3d_format *dsv_format, uint32_t *dynamic_state_flags);
|
||||
const struct vkd3d_dynamic_state *dyn_state, const struct vkd3d_format *dsv_format,
|
||||
uint32_t *dynamic_state_flags);
|
||||
VkPipeline d3d12_pipeline_state_create_pipeline_variant(struct d3d12_pipeline_state *state,
|
||||
const struct vkd3d_pipeline_key *key, const struct vkd3d_format *dsv_format,
|
||||
VkPipelineCache vk_cache, uint32_t *dynamic_state_flags);
|
||||
|
@ -1642,11 +1739,43 @@ static inline struct d3d12_pipeline_state *impl_from_ID3D12PipelineState(ID3D12P
|
|||
/* ID3D12PipelineLibrary */
|
||||
typedef ID3D12PipelineLibrary1 d3d12_pipeline_library_iface;
|
||||
|
||||
struct vkd3d_pipeline_library_disk_cache_item
|
||||
{
|
||||
struct d3d12_pipeline_state *state;
|
||||
};
|
||||
|
||||
struct vkd3d_pipeline_library_disk_cache
|
||||
{
|
||||
/* This memory is generally mapped with MapViewOfFile() or mmap(),
|
||||
* and must remain mapped for the duration of the library. */
|
||||
struct vkd3d_memory_mapped_file mapped_file;
|
||||
struct d3d12_pipeline_library *library;
|
||||
|
||||
pthread_t thread;
|
||||
condvar_reltime_t cond;
|
||||
pthread_mutex_t lock;
|
||||
bool thread_active;
|
||||
|
||||
struct vkd3d_pipeline_library_disk_cache_item *items;
|
||||
size_t items_count;
|
||||
size_t items_size;
|
||||
|
||||
char read_path[VKD3D_PATH_MAX];
|
||||
char write_path[VKD3D_PATH_MAX];
|
||||
|
||||
/* The stream archive is designed to be safe against concurrent readers and writers, ala Fossilize.
|
||||
* There is a read-only portion, and a write-only portion which can be merged back to the read-only archive
|
||||
* on demand. */
|
||||
FILE *stream_archive_write_file;
|
||||
bool stream_archive_attempted_write;
|
||||
};
|
||||
|
||||
struct d3d12_pipeline_library
|
||||
{
|
||||
d3d12_pipeline_library_iface ID3D12PipelineLibrary_iface;
|
||||
LONG refcount;
|
||||
LONG internal_refcount;
|
||||
uint32_t flags;
|
||||
|
||||
struct d3d12_device *device;
|
||||
|
||||
|
@ -1662,11 +1791,30 @@ struct d3d12_pipeline_library
|
|||
size_t total_name_table_size;
|
||||
size_t total_blob_size;
|
||||
|
||||
/* Non-owned pointer. Calls back into the disk cache when blobs are added. */
|
||||
struct vkd3d_pipeline_library_disk_cache *disk_cache_listener;
|
||||
/* Useful if parsing a huge archive in the disk thread from a cold cache.
|
||||
* If we want to tear down device immediately after device creation (not too uncommon),
|
||||
* we can end up blocking for a long time. */
|
||||
uint32_t stream_archive_cancellation_point;
|
||||
|
||||
struct vkd3d_private_store private_store;
|
||||
};
|
||||
|
||||
enum vkd3d_pipeline_library_flags
|
||||
{
|
||||
VKD3D_PIPELINE_LIBRARY_FLAG_SAVE_FULL_SPIRV = 1 << 0,
|
||||
VKD3D_PIPELINE_LIBRARY_FLAG_SAVE_PSO_BLOB = 1 << 1,
|
||||
VKD3D_PIPELINE_LIBRARY_FLAG_INTERNAL_KEYS = 1 << 2,
|
||||
VKD3D_PIPELINE_LIBRARY_FLAG_USE_PIPELINE_CACHE_UUID = 1 << 3,
|
||||
VKD3D_PIPELINE_LIBRARY_FLAG_STREAM_ARCHIVE = 1 << 4,
|
||||
/* We expect to parse archive from thread, so consider thread safety and cancellation points. */
|
||||
VKD3D_PIPELINE_LIBRARY_FLAG_STREAM_ARCHIVE_PARSE_ASYNC = 1 << 5,
|
||||
};
|
||||
|
||||
HRESULT d3d12_pipeline_library_create(struct d3d12_device *device, const void *blob,
|
||||
size_t blob_length, struct d3d12_pipeline_library **pipeline_library);
|
||||
size_t blob_length, uint32_t flags, /* vkd3d_pipeline_library_flags */
|
||||
struct d3d12_pipeline_library **pipeline_library);
|
||||
|
||||
VkResult vkd3d_create_pipeline_cache(struct d3d12_device *device,
|
||||
size_t size, const void *data, VkPipelineCache *cache);
|
||||
|
@ -1681,6 +1829,7 @@ VkResult vkd3d_serialize_pipeline_state(struct d3d12_pipeline_library *pipeline_
|
|||
HRESULT d3d12_cached_pipeline_state_validate(struct d3d12_device *device,
|
||||
const struct d3d12_cached_pipeline_state *state,
|
||||
const struct vkd3d_pipeline_cache_compatibility *compat);
|
||||
bool d3d12_cached_pipeline_state_is_dummy(const struct d3d12_cached_pipeline_state *state);
|
||||
void vkd3d_pipeline_cache_compat_from_state_desc(struct vkd3d_pipeline_cache_compatibility *compat,
|
||||
const struct d3d12_pipeline_state_desc *desc);
|
||||
|
||||
|
@ -1689,6 +1838,22 @@ ULONG d3d12_pipeline_library_dec_public_ref(struct d3d12_pipeline_library *state
|
|||
void d3d12_pipeline_library_inc_ref(struct d3d12_pipeline_library *state);
|
||||
void d3d12_pipeline_library_dec_ref(struct d3d12_pipeline_library *state);
|
||||
|
||||
/* For internal on-disk pipeline cache fallback. The key to Load/StorePipeline is implied by the PSO cache compatibility. */
|
||||
HRESULT vkd3d_pipeline_library_store_pipeline_to_disk_cache(struct vkd3d_pipeline_library_disk_cache *pipeline_library,
|
||||
struct d3d12_pipeline_state *state);
|
||||
HRESULT vkd3d_pipeline_library_find_cached_blob_from_disk_cache(struct vkd3d_pipeline_library_disk_cache *pipeline_library,
|
||||
const struct vkd3d_pipeline_cache_compatibility *compat,
|
||||
struct d3d12_cached_pipeline_state *cached_state);
|
||||
void vkd3d_pipeline_library_disk_cache_notify_blob_insert(struct vkd3d_pipeline_library_disk_cache *disk_cache,
|
||||
uint64_t hash, uint32_t type /* vkd3d_serialized_pipeline_stream_entry_type */,
|
||||
const void *data, size_t size);
|
||||
|
||||
/* Called on device init. */
|
||||
HRESULT vkd3d_pipeline_library_init_disk_cache(struct vkd3d_pipeline_library_disk_cache *cache,
|
||||
struct d3d12_device *device);
|
||||
/* Called on device destroy. */
|
||||
void vkd3d_pipeline_library_flush_disk_cache(struct vkd3d_pipeline_library_disk_cache *cache);
|
||||
|
||||
struct vkd3d_buffer
|
||||
{
|
||||
VkBuffer vk_buffer;
|
||||
|
@ -1727,7 +1892,9 @@ struct vkd3d_scratch_buffer
|
|||
#define VKD3D_QUERY_TYPE_INDEX_TRANSFORM_FEEDBACK (2u)
|
||||
#define VKD3D_QUERY_TYPE_INDEX_RT_COMPACTED_SIZE (3u)
|
||||
#define VKD3D_QUERY_TYPE_INDEX_RT_SERIALIZE_SIZE (4u)
|
||||
#define VKD3D_VIRTUAL_QUERY_TYPE_COUNT (5u)
|
||||
#define VKD3D_QUERY_TYPE_INDEX_RT_CURRENT_SIZE (5u)
|
||||
#define VKD3D_QUERY_TYPE_INDEX_RT_SERIALIZE_SIZE_BOTTOM_LEVEL_POINTERS (6u)
|
||||
#define VKD3D_VIRTUAL_QUERY_TYPE_COUNT (7u)
|
||||
#define VKD3D_VIRTUAL_QUERY_POOL_COUNT (128u)
|
||||
|
||||
struct vkd3d_query_pool
|
||||
|
@ -1738,6 +1905,20 @@ struct vkd3d_query_pool
|
|||
uint32_t next_index;
|
||||
};
|
||||
|
||||
struct d3d12_command_allocator_scratch_pool
|
||||
{
|
||||
struct vkd3d_scratch_buffer *scratch_buffers;
|
||||
size_t scratch_buffers_size;
|
||||
size_t scratch_buffer_count;
|
||||
};
|
||||
|
||||
enum vkd3d_scratch_pool_kind
|
||||
{
|
||||
VKD3D_SCRATCH_POOL_KIND_DEVICE_STORAGE = 0,
|
||||
VKD3D_SCRATCH_POOL_KIND_INDIRECT_PREPROCESS,
|
||||
VKD3D_SCRATCH_POOL_KIND_COUNT
|
||||
};
|
||||
|
||||
/* ID3D12CommandAllocator */
|
||||
struct d3d12_command_allocator
|
||||
{
|
||||
|
@ -1764,9 +1945,7 @@ struct d3d12_command_allocator
|
|||
size_t command_buffers_size;
|
||||
size_t command_buffer_count;
|
||||
|
||||
struct vkd3d_scratch_buffer *scratch_buffers;
|
||||
size_t scratch_buffers_size;
|
||||
size_t scratch_buffer_count;
|
||||
struct d3d12_command_allocator_scratch_pool scratch_pools[VKD3D_SCRATCH_POOL_KIND_COUNT];
|
||||
|
||||
struct vkd3d_query_pool *query_pools;
|
||||
size_t query_pools_size;
|
||||
|
@ -1954,6 +2133,39 @@ struct d3d12_buffer_copy_tracked_buffer
|
|||
VkDeviceSize hazard_end;
|
||||
};
|
||||
|
||||
enum vkd3d_batch_type
|
||||
{
|
||||
VKD3D_BATCH_TYPE_NONE,
|
||||
VKD3D_BATCH_TYPE_COPY_BUFFER_TO_IMAGE,
|
||||
VKD3D_BATCH_TYPE_COPY_IMAGE_TO_BUFFER,
|
||||
VKD3D_BATCH_TYPE_COPY_IMAGE,
|
||||
};
|
||||
|
||||
struct vkd3d_image_copy_info
|
||||
{
|
||||
D3D12_TEXTURE_COPY_LOCATION src, dst;
|
||||
const struct vkd3d_format *src_format, *dst_format;
|
||||
enum vkd3d_batch_type batch_type;
|
||||
union
|
||||
{
|
||||
VkBufferImageCopy2KHR buffer_image;
|
||||
VkImageCopy2KHR image;
|
||||
} copy;
|
||||
/* TODO: split d3d12_command_list_copy_image too, so this can be a local variable of before_copy_texture_region. */
|
||||
bool writes_full_subresource;
|
||||
VkImageLayout src_layout;
|
||||
VkImageLayout dst_layout;
|
||||
};
|
||||
|
||||
#define VKD3D_COPY_TEXTURE_REGION_MAX_BATCH_SIZE 16
|
||||
|
||||
struct d3d12_transfer_batch_state
|
||||
{
|
||||
enum vkd3d_batch_type batch_type;
|
||||
struct vkd3d_image_copy_info batch[VKD3D_COPY_TEXTURE_REGION_MAX_BATCH_SIZE];
|
||||
size_t batch_len;
|
||||
};
|
||||
|
||||
struct d3d12_command_list
|
||||
{
|
||||
d3d12_command_list_iface ID3D12GraphicsCommandList_iface;
|
||||
|
@ -1967,15 +2179,27 @@ struct d3d12_command_list
|
|||
bool is_valid;
|
||||
bool debug_capture;
|
||||
bool has_replaced_shaders;
|
||||
bool has_valid_index_buffer;
|
||||
|
||||
struct
|
||||
{
|
||||
VkBuffer buffer;
|
||||
VkDeviceSize offset;
|
||||
DXGI_FORMAT dxgi_format;
|
||||
VkIndexType vk_type;
|
||||
bool is_dirty;
|
||||
} index_buffer;
|
||||
|
||||
struct
|
||||
{
|
||||
bool has_observed_transition_to_indirect;
|
||||
bool has_emitted_indirect_to_compute_barrier;
|
||||
} execute_indirect;
|
||||
|
||||
VkCommandBuffer vk_command_buffer;
|
||||
VkCommandBuffer vk_init_commands;
|
||||
|
||||
DXGI_FORMAT index_buffer_format;
|
||||
|
||||
struct d3d12_rtv_desc rtvs[D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT];
|
||||
struct d3d12_rtv_desc dsv;
|
||||
uint32_t rtv_nonnull_mask;
|
||||
uint32_t dsv_plane_optimal_mask;
|
||||
VkImageLayout dsv_layout;
|
||||
unsigned int fb_width;
|
||||
|
@ -2041,13 +2265,7 @@ struct d3d12_command_list
|
|||
struct d3d12_buffer_copy_tracked_buffer tracked_copy_buffers[VKD3D_BUFFER_COPY_TRACKING_BUFFER_COUNT];
|
||||
unsigned int tracked_copy_buffer_count;
|
||||
|
||||
/* Hackery needed for game workarounds. */
|
||||
struct
|
||||
{
|
||||
/* Used to keep track of COLOR write -> COMPUTE where game forget to insert barrier
|
||||
* before the dispatch. */
|
||||
bool has_pending_color_write;
|
||||
} workaround_state;
|
||||
struct d3d12_transfer_batch_state transfer_batch;
|
||||
|
||||
struct vkd3d_private_store private_store;
|
||||
|
||||
|
@ -2121,6 +2339,8 @@ struct vkd3d_queue
|
|||
VkCommandPool barrier_pool;
|
||||
VkCommandBuffer barrier_command_buffer;
|
||||
VkSemaphore serializing_binary_semaphore;
|
||||
VkSemaphore submission_timeline;
|
||||
uint64_t submission_timeline_count;
|
||||
|
||||
uint32_t vk_family_index;
|
||||
VkQueueFlags vk_queue_flags;
|
||||
|
@ -2133,6 +2353,8 @@ struct vkd3d_queue
|
|||
size_t wait_values_size;
|
||||
VkPipelineStageFlags *wait_stages;
|
||||
size_t wait_stages_size;
|
||||
d3d12_fence_iface **wait_fences;
|
||||
size_t wait_fences_size;
|
||||
uint32_t wait_count;
|
||||
};
|
||||
|
||||
|
@ -2141,7 +2363,7 @@ HRESULT vkd3d_queue_create(struct d3d12_device *device, uint32_t family_index, u
|
|||
const VkQueueFamilyProperties *properties, struct vkd3d_queue **queue);
|
||||
void vkd3d_queue_destroy(struct vkd3d_queue *queue, struct d3d12_device *device);
|
||||
void vkd3d_queue_release(struct vkd3d_queue *queue);
|
||||
void vkd3d_queue_add_wait(struct vkd3d_queue *queue, VkSemaphore semaphore, uint64_t value);
|
||||
void vkd3d_queue_add_wait(struct vkd3d_queue *queue, d3d12_fence_iface *waiter, VkSemaphore semaphore, uint64_t value);
|
||||
|
||||
enum vkd3d_submission_type
|
||||
{
|
||||
|
@ -2177,13 +2399,13 @@ struct vkd3d_sparse_memory_bind_range
|
|||
|
||||
struct d3d12_command_queue_submission_wait
|
||||
{
|
||||
struct d3d12_fence *fence;
|
||||
d3d12_fence_iface *fence;
|
||||
UINT64 value;
|
||||
};
|
||||
|
||||
struct d3d12_command_queue_submission_signal
|
||||
{
|
||||
struct d3d12_fence *fence;
|
||||
d3d12_fence_iface *fence;
|
||||
UINT64 value;
|
||||
};
|
||||
|
||||
|
@ -2270,6 +2492,35 @@ HRESULT d3d12_command_queue_create(struct d3d12_device *device,
|
|||
const D3D12_COMMAND_QUEUE_DESC *desc, struct d3d12_command_queue **queue);
|
||||
void d3d12_command_queue_submit_stop(struct d3d12_command_queue *queue);
|
||||
|
||||
struct vkd3d_execute_indirect_info
|
||||
{
|
||||
VkPipelineLayout vk_pipeline_layout;
|
||||
VkPipeline vk_pipeline;
|
||||
};
|
||||
|
||||
enum vkd3d_patch_command_token
|
||||
{
|
||||
VKD3D_PATCH_COMMAND_TOKEN_COPY_CONST_U32 = 0,
|
||||
VKD3D_PATCH_COMMAND_TOKEN_COPY_IBO_VA_LO = 1,
|
||||
VKD3D_PATCH_COMMAND_TOKEN_COPY_IBO_VA_HI = 2,
|
||||
VKD3D_PATCH_COMMAND_TOKEN_COPY_IBO_SIZE = 3,
|
||||
VKD3D_PATCH_COMMAND_TOKEN_COPY_INDEX_FORMAT = 4,
|
||||
VKD3D_PATCH_COMMAND_TOKEN_COPY_VBO_VA_LO = 5,
|
||||
VKD3D_PATCH_COMMAND_TOKEN_COPY_VBO_VA_HI = 6,
|
||||
VKD3D_PATCH_COMMAND_TOKEN_COPY_VBO_SIZE = 7,
|
||||
VKD3D_PATCH_COMMAND_TOKEN_COPY_VBO_STRIDE = 8,
|
||||
VKD3D_PATCH_COMMAND_TOKEN_COPY_ROOT_VA_LO = 9,
|
||||
VKD3D_PATCH_COMMAND_TOKEN_COPY_ROOT_VA_HI = 10,
|
||||
VKD3D_PATCH_COMMAND_TOKEN_COPY_VERTEX_COUNT = 11,
|
||||
VKD3D_PATCH_COMMAND_TOKEN_COPY_INDEX_COUNT = 12,
|
||||
VKD3D_PATCH_COMMAND_TOKEN_COPY_INSTANCE_COUNT = 13,
|
||||
VKD3D_PATCH_COMMAND_TOKEN_COPY_FIRST_INDEX = 14,
|
||||
VKD3D_PATCH_COMMAND_TOKEN_COPY_FIRST_VERTEX = 15,
|
||||
VKD3D_PATCH_COMMAND_TOKEN_COPY_FIRST_INSTANCE = 16,
|
||||
VKD3D_PATCH_COMMAND_TOKEN_COPY_VERTEX_OFFSET = 17,
|
||||
VKD3D_PATCH_COMMAND_INT_MAX = 0x7fffffff
|
||||
};
|
||||
|
||||
/* ID3D12CommandSignature */
|
||||
struct d3d12_command_signature
|
||||
{
|
||||
|
@ -2277,13 +2528,27 @@ struct d3d12_command_signature
|
|||
LONG refcount;
|
||||
|
||||
D3D12_COMMAND_SIGNATURE_DESC desc;
|
||||
uint32_t argument_buffer_offset;
|
||||
|
||||
/* Complex command signatures require some work to stamp out device generated commands. */
|
||||
struct
|
||||
{
|
||||
VkBuffer buffer;
|
||||
VkDeviceAddress buffer_va;
|
||||
struct vkd3d_device_memory_allocation memory;
|
||||
VkIndirectCommandsLayoutNV layout;
|
||||
uint32_t stride;
|
||||
struct vkd3d_execute_indirect_info pipeline;
|
||||
} state_template;
|
||||
bool requires_state_template;
|
||||
|
||||
struct d3d12_device *device;
|
||||
|
||||
struct vkd3d_private_store private_store;
|
||||
};
|
||||
|
||||
HRESULT d3d12_command_signature_create(struct d3d12_device *device, const D3D12_COMMAND_SIGNATURE_DESC *desc,
|
||||
HRESULT d3d12_command_signature_create(struct d3d12_device *device, struct d3d12_root_signature *root_signature,
|
||||
const D3D12_COMMAND_SIGNATURE_DESC *desc,
|
||||
struct d3d12_command_signature **signature);
|
||||
|
||||
static inline struct d3d12_command_signature *impl_from_ID3D12CommandSignature(ID3D12CommandSignature *iface)
|
||||
|
@ -2360,6 +2625,7 @@ enum vkd3d_breadcrumb_command_type
|
|||
VKD3D_BREADCRUMB_COMMAND_DRAW_INDEXED,
|
||||
VKD3D_BREADCRUMB_COMMAND_DISPATCH,
|
||||
VKD3D_BREADCRUMB_COMMAND_EXECUTE_INDIRECT,
|
||||
VKD3D_BREADCRUMB_COMMAND_EXECUTE_INDIRECT_TEMPLATE,
|
||||
VKD3D_BREADCRUMB_COMMAND_COPY,
|
||||
VKD3D_BREADCRUMB_COMMAND_RESOLVE,
|
||||
VKD3D_BREADCRUMB_COMMAND_WBI,
|
||||
|
@ -2376,6 +2642,7 @@ enum vkd3d_breadcrumb_command_type
|
|||
VKD3D_BREADCRUMB_COMMAND_IBO,
|
||||
VKD3D_BREADCRUMB_COMMAND_ROOT_DESC,
|
||||
VKD3D_BREADCRUMB_COMMAND_ROOT_CONST,
|
||||
VKD3D_BREADCRUMB_COMMAND_TAG,
|
||||
};
|
||||
|
||||
#ifdef VKD3D_ENABLE_BREADCRUMBS
|
||||
|
@ -2399,6 +2666,8 @@ struct vkd3d_breadcrumb_command
|
|||
uint32_t word_32bit;
|
||||
uint64_t word_64bit;
|
||||
uint32_t count;
|
||||
/* Pointer must remain alive. */
|
||||
const char *tag;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -2856,6 +3125,41 @@ HRESULT vkd3d_predicate_ops_init(struct vkd3d_predicate_ops *meta_predicate_ops,
|
|||
void vkd3d_predicate_ops_cleanup(struct vkd3d_predicate_ops *meta_predicate_ops,
|
||||
struct d3d12_device *device);
|
||||
|
||||
struct vkd3d_execute_indirect_args
|
||||
{
|
||||
VkDeviceAddress template_va;
|
||||
VkDeviceAddress api_buffer_va;
|
||||
VkDeviceAddress device_generated_commands_va;
|
||||
VkDeviceAddress indirect_count_va;
|
||||
VkDeviceAddress dst_indirect_count_va;
|
||||
uint32_t api_buffer_word_stride;
|
||||
uint32_t device_generated_commands_word_stride;
|
||||
|
||||
/* Arbitrary tag used for debug version of state patcher. Debug messages from tag 0 are ignored. */
|
||||
uint32_t debug_tag;
|
||||
uint32_t implicit_instance;
|
||||
};
|
||||
|
||||
struct vkd3d_execute_indirect_pipeline
|
||||
{
|
||||
VkPipeline vk_pipeline;
|
||||
uint32_t workgroup_size_x;
|
||||
};
|
||||
|
||||
struct vkd3d_execute_indirect_ops
|
||||
{
|
||||
VkPipelineLayout vk_pipeline_layout;
|
||||
struct vkd3d_execute_indirect_pipeline *pipelines;
|
||||
size_t pipelines_count;
|
||||
size_t pipelines_size;
|
||||
pthread_mutex_t mutex;
|
||||
};
|
||||
|
||||
HRESULT vkd3d_execute_indirect_ops_init(struct vkd3d_execute_indirect_ops *meta_indirect_ops,
|
||||
struct d3d12_device *device);
|
||||
void vkd3d_execute_indirect_ops_cleanup(struct vkd3d_execute_indirect_ops *meta_indirect_ops,
|
||||
struct d3d12_device *device);
|
||||
|
||||
struct vkd3d_meta_ops_common
|
||||
{
|
||||
VkShaderModule vk_module_fullscreen_vs;
|
||||
|
@ -2871,6 +3175,7 @@ struct vkd3d_meta_ops
|
|||
struct vkd3d_swapchain_ops swapchain;
|
||||
struct vkd3d_query_ops query;
|
||||
struct vkd3d_predicate_ops predicate;
|
||||
struct vkd3d_execute_indirect_ops execute_indirect;
|
||||
};
|
||||
|
||||
HRESULT vkd3d_meta_ops_init(struct vkd3d_meta_ops *meta_ops, struct d3d12_device *device);
|
||||
|
@ -2903,6 +3208,9 @@ bool vkd3d_meta_get_query_gather_pipeline(struct vkd3d_meta_ops *meta_ops,
|
|||
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);
|
||||
|
||||
HRESULT vkd3d_meta_get_execute_indirect_pipeline(struct vkd3d_meta_ops *meta_ops,
|
||||
uint32_t patch_command_count, struct vkd3d_execute_indirect_info *info);
|
||||
|
||||
enum vkd3d_time_domain_flag
|
||||
{
|
||||
VKD3D_TIME_DOMAIN_DEVICE = 0x00000001u,
|
||||
|
@ -2936,6 +3244,8 @@ struct vkd3d_physical_device_info
|
|||
VkPhysicalDeviceConservativeRasterizationPropertiesEXT conservative_rasterization_properties;
|
||||
VkPhysicalDeviceShaderIntegerDotProductPropertiesKHR shader_integer_dot_product_properties;
|
||||
VkPhysicalDeviceDriverPropertiesKHR driver_properties;
|
||||
VkPhysicalDeviceMaintenance4PropertiesKHR maintenance4_properties;
|
||||
VkPhysicalDeviceDeviceGeneratedCommandsPropertiesNV device_generated_commands_properties_nv;
|
||||
|
||||
VkPhysicalDeviceProperties2KHR properties2;
|
||||
|
||||
|
@ -2957,6 +3267,7 @@ struct vkd3d_physical_device_info
|
|||
VkPhysicalDeviceShaderSubgroupExtendedTypesFeaturesKHR subgroup_extended_types_features;
|
||||
VkPhysicalDeviceRobustness2FeaturesEXT robustness2_features;
|
||||
VkPhysicalDeviceExtendedDynamicStateFeaturesEXT extended_dynamic_state_features;
|
||||
VkPhysicalDeviceExtendedDynamicState2FeaturesEXT extended_dynamic_state2_features;
|
||||
VkPhysicalDeviceMutableDescriptorTypeFeaturesVALVE mutable_descriptor_features;
|
||||
VkPhysicalDeviceRayTracingPipelineFeaturesKHR ray_tracing_pipeline_features;
|
||||
VkPhysicalDeviceAccelerationStructureFeaturesKHR acceleration_structure_features;
|
||||
|
@ -2966,15 +3277,20 @@ struct vkd3d_physical_device_info
|
|||
VkPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR separate_depth_stencil_layout_features;
|
||||
VkPhysicalDeviceShaderIntegerDotProductFeaturesKHR shader_integer_dot_product_features;
|
||||
VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV barycentric_features_nv;
|
||||
VkPhysicalDeviceFragmentShaderBarycentricFeaturesKHR barycentric_features_khr;
|
||||
VkPhysicalDeviceRayQueryFeaturesKHR ray_query_features;
|
||||
VkPhysicalDeviceComputeShaderDerivativesFeaturesNV compute_shader_derivatives_features_nv;
|
||||
VkPhysicalDeviceShaderAtomicInt64FeaturesKHR shader_atomic_int64_features;
|
||||
VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT shader_image_atomic_int64_features;
|
||||
VkPhysicalDeviceScalarBlockLayoutFeaturesEXT scalar_block_layout_features;
|
||||
VkPhysicalDeviceUniformBufferStandardLayoutFeatures uniform_buffer_standard_layout_features;
|
||||
VkPhysicalDeviceImageViewMinLodFeaturesEXT image_view_min_lod_features;
|
||||
VkPhysicalDeviceDescriptorSetHostMappingFeaturesVALVE descriptor_set_host_mapping_features;
|
||||
VkPhysicalDeviceDynamicRenderingFeaturesKHR dynamic_rendering_features;
|
||||
VkPhysicalDeviceCoherentMemoryFeaturesAMD device_coherent_memory_features_amd;
|
||||
VkPhysicalDeviceMaintenance4FeaturesKHR maintenance4_features;
|
||||
VkPhysicalDeviceRayTracingMaintenance1FeaturesKHR ray_tracing_maintenance1_features;
|
||||
VkPhysicalDeviceDeviceGeneratedCommandsFeaturesNV device_generated_commands_features_nv;
|
||||
|
||||
VkPhysicalDeviceFeatures2 features2;
|
||||
|
||||
|
@ -3040,6 +3356,12 @@ struct vkd3d_descriptor_qa_heap_buffer_data;
|
|||
/* ID3D12DeviceExt */
|
||||
typedef ID3D12DeviceExt d3d12_device_vkd3d_ext_iface;
|
||||
|
||||
struct d3d12_device_scratch_pool
|
||||
{
|
||||
struct vkd3d_scratch_buffer scratch_buffers[VKD3D_SCRATCH_BUFFER_COUNT];
|
||||
size_t scratch_buffer_count;
|
||||
};
|
||||
|
||||
struct d3d12_device
|
||||
{
|
||||
d3d12_device_iface ID3D12Device_iface;
|
||||
|
@ -3074,8 +3396,7 @@ struct d3d12_device
|
|||
|
||||
struct vkd3d_memory_allocator memory_allocator;
|
||||
|
||||
struct vkd3d_scratch_buffer scratch_buffers[VKD3D_SCRATCH_BUFFER_COUNT];
|
||||
size_t scratch_buffer_count;
|
||||
struct d3d12_device_scratch_pool scratch_pools[VKD3D_SCRATCH_POOL_KIND_COUNT];
|
||||
|
||||
struct vkd3d_query_pool query_pools[VKD3D_VIRTUAL_QUERY_POOL_COUNT];
|
||||
size_t query_pool_count;
|
||||
|
@ -3100,13 +3421,13 @@ struct d3d12_device
|
|||
struct vkd3d_view_map sampler_map;
|
||||
struct vkd3d_sampler_state sampler_state;
|
||||
struct vkd3d_shader_debug_ring debug_ring;
|
||||
struct vkd3d_pipeline_library_disk_cache disk_cache;
|
||||
#ifdef VKD3D_ENABLE_BREADCRUMBS
|
||||
struct vkd3d_breadcrumb_tracer breadcrumb_tracer;
|
||||
#endif
|
||||
#ifdef VKD3D_ENABLE_DESCRIPTOR_QA
|
||||
struct vkd3d_descriptor_qa_global_info *descriptor_qa_global_info;
|
||||
#endif
|
||||
VkPipelineCache global_pipeline_cache;
|
||||
uint64_t shader_interface_key;
|
||||
};
|
||||
|
||||
|
@ -3148,8 +3469,10 @@ static inline struct d3d12_device *impl_from_ID3D12Device(d3d12_device_iface *if
|
|||
|
||||
bool d3d12_device_validate_shader_meta(struct d3d12_device *device, const struct vkd3d_shader_meta *meta);
|
||||
|
||||
HRESULT d3d12_device_get_scratch_buffer(struct d3d12_device *device, VkDeviceSize min_size, struct vkd3d_scratch_buffer *scratch);
|
||||
void d3d12_device_return_scratch_buffer(struct d3d12_device *device, const struct vkd3d_scratch_buffer *scratch);
|
||||
HRESULT d3d12_device_get_scratch_buffer(struct d3d12_device *device, enum vkd3d_scratch_pool_kind kind,
|
||||
VkDeviceSize min_size, uint32_t memory_types, struct vkd3d_scratch_buffer *scratch);
|
||||
void d3d12_device_return_scratch_buffer(struct d3d12_device *device, enum vkd3d_scratch_pool_kind kind,
|
||||
const struct vkd3d_scratch_buffer *scratch);
|
||||
|
||||
HRESULT d3d12_device_get_query_pool(struct d3d12_device *device, uint32_t type_index, struct vkd3d_query_pool *pool);
|
||||
void d3d12_device_return_query_pool(struct d3d12_device *device, const struct vkd3d_query_pool *pool);
|
||||
|
@ -3275,6 +3598,14 @@ struct d3d12_state_object_identifier
|
|||
|
||||
/* The index into vkGetShaderStackSize and friends for pGroups[]. */
|
||||
uint32_t group_index;
|
||||
|
||||
/* For AddToStateObject(). We need to return the identifier pointer
|
||||
* for the parent, not the child. This makes it easy to validate that
|
||||
* we observe the same SBT handles as specified by DXR 1.1. */
|
||||
|
||||
/* If -1, ignore, otherwise, redirect. */
|
||||
int inherited_collection_index;
|
||||
uint32_t inherited_collection_export_index;
|
||||
};
|
||||
|
||||
struct d3d12_state_object_stack_info
|
||||
|
@ -3287,6 +3618,15 @@ struct d3d12_state_object_stack_info
|
|||
uint32_t max_closest;
|
||||
};
|
||||
|
||||
#ifdef VKD3D_ENABLE_BREADCRUMBS
|
||||
struct d3d12_state_object_breadcrumb_shader
|
||||
{
|
||||
vkd3d_shader_hash_t hash;
|
||||
VkShaderStageFlagBits stage;
|
||||
char name[64];
|
||||
};
|
||||
#endif
|
||||
|
||||
struct d3d12_state_object
|
||||
{
|
||||
d3d12_state_object_iface ID3D12StateObject_iface;
|
||||
|
@ -3308,7 +3648,14 @@ struct d3d12_state_object
|
|||
/* Normally stages_count == entry_points_count, but entry_points is the entry points we
|
||||
* export externally, and stages_count matches pStages[] size for purposes of index fixups. */
|
||||
|
||||
/* Can be bound. */
|
||||
VkPipeline pipeline;
|
||||
/* Can be used as a library. */
|
||||
VkPipeline pipeline_library;
|
||||
|
||||
/* Can be inherited by AddToStateObject(). */
|
||||
D3D12_RAYTRACING_PIPELINE_CONFIG1 pipeline_config;
|
||||
D3D12_RAYTRACING_SHADER_CONFIG shader_config;
|
||||
|
||||
struct
|
||||
{
|
||||
|
@ -3317,6 +3664,8 @@ struct d3d12_state_object
|
|||
VkDescriptorSet desc_set;
|
||||
VkDescriptorPool desc_pool;
|
||||
uint32_t set_index;
|
||||
uint64_t compatibility_hash;
|
||||
bool owned_handles;
|
||||
} local_static_sampler;
|
||||
|
||||
UINT64 pipeline_stack_size;
|
||||
|
@ -3325,10 +3674,23 @@ struct d3d12_state_object
|
|||
struct d3d12_state_object **collections;
|
||||
size_t collections_count;
|
||||
|
||||
struct d3d12_root_signature *global_root_signature;
|
||||
|
||||
#ifdef VKD3D_ENABLE_BREADCRUMBS
|
||||
/* For breadcrumbs. */
|
||||
struct d3d12_state_object_breadcrumb_shader *breadcrumb_shaders;
|
||||
size_t breadcrumb_shaders_size;
|
||||
size_t breadcrumb_shaders_count;
|
||||
#endif
|
||||
|
||||
struct vkd3d_private_store private_store;
|
||||
};
|
||||
|
||||
HRESULT d3d12_state_object_create(struct d3d12_device *device, const D3D12_STATE_OBJECT_DESC *desc,
|
||||
struct d3d12_state_object *parent,
|
||||
struct d3d12_state_object **object);
|
||||
HRESULT d3d12_state_object_add(struct d3d12_device *device, const D3D12_STATE_OBJECT_DESC *desc,
|
||||
struct d3d12_state_object *parent,
|
||||
struct d3d12_state_object **object);
|
||||
|
||||
static inline struct d3d12_state_object *impl_from_ID3D12StateObject(ID3D12StateObject *iface)
|
||||
|
@ -3403,16 +3765,6 @@ static inline const struct vkd3d_format *vkd3d_format_from_d3d12_resource_desc(
|
|||
desc->Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL);
|
||||
}
|
||||
|
||||
static inline unsigned int vkd3d_get_color_attachment_count(unsigned int attachment_mask)
|
||||
{
|
||||
unsigned int count = 0;
|
||||
|
||||
while (attachment_mask >> count)
|
||||
count++;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static inline VkImageSubresourceRange vk_subresource_range_from_layers(const VkImageSubresourceLayers *layers)
|
||||
{
|
||||
VkImageSubresourceRange range;
|
||||
|
@ -3610,6 +3962,74 @@ void vkd3d_acceleration_structure_copy(
|
|||
D3D12_GPU_VIRTUAL_ADDRESS dst, D3D12_GPU_VIRTUAL_ADDRESS src,
|
||||
D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE mode);
|
||||
|
||||
typedef enum D3D11_USAGE
|
||||
{
|
||||
D3D11_USAGE_DEFAULT,
|
||||
D3D11_USAGE_IMMUTABLE,
|
||||
D3D11_USAGE_DYNAMIC,
|
||||
D3D11_USAGE_STAGING,
|
||||
} D3D11_USAGE;
|
||||
|
||||
typedef enum D3D11_BIND_FLAG
|
||||
{
|
||||
D3D11_BIND_VERTEX_BUFFER = 0x0001,
|
||||
D3D11_BIND_INDEX_BUFFER = 0x0002,
|
||||
D3D11_BIND_CONSTANT_BUFFER = 0x0004,
|
||||
D3D11_BIND_SHADER_RESOURCE = 0x0008,
|
||||
D3D11_BIND_STREAM_OUTPUT = 0x0010,
|
||||
D3D11_BIND_RENDER_TARGET = 0x0020,
|
||||
D3D11_BIND_DEPTH_STENCIL = 0x0040,
|
||||
D3D11_BIND_UNORDERED_ACCESS = 0x0080,
|
||||
D3D11_BIND_DECODER = 0x0200,
|
||||
D3D11_BIND_VIDEO_ENCODER = 0x0400
|
||||
} D3D11_BIND_FLAG;
|
||||
|
||||
typedef enum D3D11_TEXTURE_LAYOUT
|
||||
{
|
||||
D3D11_TEXTURE_LAYOUT_UNDEFINED = 0x0,
|
||||
D3D11_TEXTURE_LAYOUT_ROW_MAJOR = 0x1,
|
||||
D3D11_TEXTURE_LAYOUT_64K_STANDARD_SWIZZLE = 0x2,
|
||||
} D3D11_TEXTURE_LAYOUT;
|
||||
|
||||
typedef enum D3D11_RESOURCE_MISC_FLAG
|
||||
{
|
||||
D3D11_RESOURCE_MISC_GENERATE_MIPS = 0x1,
|
||||
D3D11_RESOURCE_MISC_SHARED = 0x2,
|
||||
D3D11_RESOURCE_MISC_TEXTURECUBE = 0x4,
|
||||
D3D11_RESOURCE_MISC_DRAWINDIRECT_ARGS = 0x10,
|
||||
D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS = 0x20,
|
||||
D3D11_RESOURCE_MISC_BUFFER_STRUCTURED = 0x40,
|
||||
D3D11_RESOURCE_MISC_RESOURCE_CLAMP = 0x80,
|
||||
D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX = 0x100,
|
||||
D3D11_RESOURCE_MISC_GDI_COMPATIBLE = 0x200,
|
||||
D3D11_RESOURCE_MISC_SHARED_NTHANDLE = 0x800,
|
||||
D3D11_RESOURCE_MISC_RESTRICTED_CONTENT = 0x1000,
|
||||
D3D11_RESOURCE_MISC_RESTRICT_SHARED_RESOURCE = 0x2000,
|
||||
D3D11_RESOURCE_MISC_RESTRICT_SHARED_RESOURCE_DRIVER = 0x4000,
|
||||
D3D11_RESOURCE_MISC_GUARDED = 0x8000,
|
||||
D3D11_RESOURCE_MISC_TILE_POOL = 0x20000,
|
||||
D3D11_RESOURCE_MISC_TILED = 0x40000,
|
||||
D3D11_RESOURCE_MISC_HW_PROTECTED = 0x80000,
|
||||
} D3D11_RESOURCE_MISC_FLAG;
|
||||
|
||||
struct DxvkSharedTextureMetadata {
|
||||
UINT Width;
|
||||
UINT Height;
|
||||
UINT MipLevels;
|
||||
UINT ArraySize;
|
||||
DXGI_FORMAT Format;
|
||||
DXGI_SAMPLE_DESC SampleDesc;
|
||||
D3D11_USAGE Usage;
|
||||
UINT BindFlags;
|
||||
UINT CPUAccessFlags;
|
||||
UINT MiscFlags;
|
||||
D3D11_TEXTURE_LAYOUT TextureLayout;
|
||||
};
|
||||
|
||||
bool vkd3d_set_shared_metadata(HANDLE handle, void *buf, uint32_t buf_size);
|
||||
bool vkd3d_get_shared_metadata(HANDLE handle, void *buf, uint32_t buf_size, uint32_t *metadata_size);
|
||||
HANDLE vkd3d_open_kmt_handle(HANDLE kmt_handle);
|
||||
|
||||
#define VKD3D_VENDOR_ID_NVIDIA 0x10DE
|
||||
#define VKD3D_VENDOR_ID_AMD 0x1002
|
||||
#define VKD3D_VENDOR_ID_INTEL 0x8086
|
||||
|
|
|
@ -45,6 +45,8 @@ enum vkd3d_meta_copy_mode
|
|||
#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.h>
|
||||
#include <gs_fullscreen.h>
|
||||
|
|
|
@ -49,6 +49,7 @@ VK_INSTANCE_PFN(vkGetPhysicalDeviceQueueFamilyProperties)
|
|||
VK_INSTANCE_PFN(vkGetPhysicalDeviceSparseImageFormatProperties)
|
||||
VK_INSTANCE_PFN(vkGetPhysicalDeviceFeatures2)
|
||||
VK_INSTANCE_PFN(vkGetPhysicalDeviceProperties2)
|
||||
VK_INSTANCE_PFN(vkGetPhysicalDeviceExternalSemaphoreProperties)
|
||||
|
||||
/* VK_EXT_debug_utils */
|
||||
VK_INSTANCE_EXT_PFN(vkCreateDebugUtilsMessengerEXT)
|
||||
|
@ -218,6 +219,23 @@ 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_DEVICE_EXT_PFN(vkGetCalibratedTimestampsEXT)
|
||||
VK_INSTANCE_EXT_PFN(vkGetPhysicalDeviceCalibrateableTimeDomainsEXT)
|
||||
|
@ -245,6 +263,9 @@ VK_DEVICE_EXT_PFN(vkCmdSetPrimitiveTopologyEXT)
|
|||
VK_DEVICE_EXT_PFN(vkCmdSetScissorWithCountEXT)
|
||||
VK_DEVICE_EXT_PFN(vkCmdSetViewportWithCountEXT)
|
||||
|
||||
/* VK_EXT_extended_dynamic_state2 */
|
||||
VK_DEVICE_EXT_PFN(vkCmdSetPrimitiveRestartEnableEXT)
|
||||
|
||||
/* VK_EXT_external_memory_host */
|
||||
VK_DEVICE_EXT_PFN(vkGetMemoryHostPointerPropertiesEXT)
|
||||
|
||||
|
@ -272,6 +293,9 @@ VK_DEVICE_EXT_PFN(vkQueuePresentKHR)
|
|||
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_DEVICE_EXT_PFN(vkCmdWriteBufferMarkerAMD)
|
||||
|
||||
|
@ -294,6 +318,12 @@ VK_DEVICE_EXT_PFN(vkGetImageViewAddressNVX)
|
|||
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_EXT_PFN
|
||||
#undef VK_DEVICE_PFN
|
||||
|
|
|
@ -83,7 +83,7 @@ idl_generator = generator(idl_compiler,
|
|||
arguments : [ '-h', '-o', '@OUTPUT@', '@INPUT@' ])
|
||||
|
||||
glsl_compiler = find_program('glslangValidator')
|
||||
glsl_args = [ '-V', '--vn', '@BASENAME@', '@INPUT@', '-o', '@OUTPUT@' ]
|
||||
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
|
||||
|
|
|
@ -75,17 +75,35 @@ def main():
|
|||
parser.add_argument('--per-iteration', action = 'store_true', help = 'Represent ticks in terms of ticks / iteration. Cannot be used with --divider.')
|
||||
parser.add_argument('--name', nargs = '+', type = str, help = 'Only display data for certain counters.')
|
||||
parser.add_argument('--sort', type = str, default = 'none', help = 'Sorts input data according to "iterations" or "ticks".')
|
||||
parser.add_argument('--delta', type = str, help = 'Subtract iterations and timing from other profile blob.')
|
||||
parser.add_argument('profile', help = 'The profile binary blob.')
|
||||
|
||||
args = parser.parse_args()
|
||||
if not args.profile:
|
||||
raise AssertionError('Need profile folder.')
|
||||
|
||||
delta_map = {}
|
||||
if args.delta is not None:
|
||||
with open(args.delta, 'rb') as f:
|
||||
for block in iter(lambda: f.read(64), b''):
|
||||
if is_valid_block(block):
|
||||
b = parse_block(block)
|
||||
delta_map[b.name] = b
|
||||
|
||||
blocks = []
|
||||
with open(args.profile, 'rb') as f:
|
||||
for block in iter(lambda: f.read(64), b''):
|
||||
if is_valid_block(block):
|
||||
blocks.append(parse_block(block))
|
||||
b = parse_block(block)
|
||||
if b.name in delta_map:
|
||||
d = delta_map[b.name]
|
||||
b = ProfileCase(ticks = b.ticks - d.ticks,
|
||||
iterations = b.iterations - d.iterations,
|
||||
name = b.name)
|
||||
if b.iterations < 0 or b.ticks < 0:
|
||||
raise AssertionError('After subtracting, iterations or ticks became negative.')
|
||||
if b.iterations > 0:
|
||||
blocks.append(b)
|
||||
|
||||
if args.divider is not None:
|
||||
if args.per_iteration:
|
||||
|
@ -114,11 +132,11 @@ def main():
|
|||
print(' Iterations:', block.iterations)
|
||||
|
||||
if args.divider is not None:
|
||||
print(' Time spent per iteration of {}: {:.3f}'.format(args.divider, block.ticks / 1000.0), "us")
|
||||
print(' Time spent per iteration of {}: {:.3f}'.format(args.divider, block.ticks / 1000.0), "Kcycles")
|
||||
elif args.per_iteration:
|
||||
print(' Time spent per iteration: {:.3f}'.format(block.ticks / 1000.0), "us")
|
||||
print(' Time spent per iteration: {:.3f}'.format(block.ticks / 1000.0), "Kcycles")
|
||||
else:
|
||||
print(' Total time spent: {:.3f}'.format(block.ticks / 1000.0), "us")
|
||||
print(' Total time spent: {:.3f}'.format(block.ticks / 1000.0), "Kcycles")
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 6eb8fc3598ed2a9777677fbe59038c8d0664a434
|
||||
Subproject commit 245d25ce8c3337919dc7916d0e62e31a0d8748ab
|
|
@ -1 +1 @@
|
|||
Subproject commit b537bbb91bccdbc695cb7e5211d608f8d1c205bd
|
||||
Subproject commit 9f2fd6356c14376ab5b88518d6dd4e6787084525
|
|
@ -141,7 +141,7 @@ void test_clear_depth_stencil_view(void)
|
|||
void test_clear_render_target_view(void)
|
||||
{
|
||||
static const unsigned int array_expected_colors[] = {0xff00ff00, 0xff0000ff, 0xffff0000};
|
||||
static const struct vec4 array_colors[] =
|
||||
static const float array_colors[][4] =
|
||||
{
|
||||
{0.0f, 1.0f, 0.0f, 1.0f},
|
||||
{1.0f, 0.0f, 0.0f, 1.0f},
|
||||
|
@ -324,8 +324,7 @@ void test_clear_render_target_view(void)
|
|||
rtv_desc.Texture2DArray.ArraySize = 1;
|
||||
|
||||
ID3D12Device_CreateRenderTargetView(device, resource, &rtv_desc, rtv_handle);
|
||||
|
||||
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, rtv_handle, &array_colors[i].x, 0, NULL);
|
||||
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, rtv_handle, array_colors[i], 0, NULL);
|
||||
}
|
||||
|
||||
transition_resource_state(command_list, resource,
|
||||
|
@ -355,8 +354,7 @@ void test_clear_render_target_view(void)
|
|||
rtv_desc.Texture2DMSArray.ArraySize = 1;
|
||||
|
||||
ID3D12Device_CreateRenderTargetView(device, resource, &rtv_desc, rtv_handle);
|
||||
|
||||
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, rtv_handle, &array_colors[i].x, 0, NULL);
|
||||
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, rtv_handle, array_colors[i], 0, NULL);
|
||||
}
|
||||
|
||||
transition_resource_state(command_list, resource,
|
||||
|
@ -704,6 +702,7 @@ void test_clear_unordered_access_view_image(void)
|
|||
{DXGI_FORMAT_R8G8B8A8_UINT, 1, 1, 0, 0, 1, 0, {{0}}, {1, 2, 3, 4}, 0x04030201},
|
||||
{DXGI_FORMAT_R8G8B8A8_UINT, 1, 1, 0, 0, 1, 0, {{0}}, {0x123, 0, 0, 0}, 0x00000023},
|
||||
{DXGI_FORMAT_R8G8B8A8_UNORM, 1, 1, 0, 0, 1, 0, {{0}}, {1, 2, 3, 4}, 0x04030201},
|
||||
{DXGI_FORMAT_R11G11B10_FLOAT, 1, 1, 0, 0, 1, 0, {{0}}, {0, 0, 0, 0}, 0x00000000},
|
||||
{DXGI_FORMAT_R11G11B10_FLOAT, 1, 1, 0, 0, 1, 0, {{0}}, {1, 2, 3, 4}, 0x00c01001},
|
||||
/* Test float clears with formats. */
|
||||
{DXGI_FORMAT_R16G16_UNORM, 1, 1, 0, 0, 1, 0, {{0}},
|
||||
|
|
|
@ -1159,8 +1159,8 @@ void test_bundle_state_inheritance(void)
|
|||
D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
|
||||
check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0);
|
||||
|
||||
ID3D12CommandAllocator_Release(bundle_allocator);
|
||||
ID3D12GraphicsCommandList_Release(bundle);
|
||||
ID3D12CommandAllocator_Release(bundle_allocator);
|
||||
destroy_test_context(&context);
|
||||
}
|
||||
|
||||
|
@ -1449,6 +1449,721 @@ void test_vbv_stride_edge_cases(void)
|
|||
destroy_test_context(&context);
|
||||
}
|
||||
|
||||
void test_execute_indirect_state(void)
|
||||
{
|
||||
static const struct vec4 values = { 1000.0f, 2000.0f, 3000.0f, 4000.0f };
|
||||
D3D12_INDIRECT_ARGUMENT_DESC indirect_argument_descs[2];
|
||||
D3D12_COMMAND_SIGNATURE_DESC command_signature_desc;
|
||||
D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
|
||||
D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
|
||||
ID3D12CommandSignature *command_signature;
|
||||
D3D12_SO_DECLARATION_ENTRY so_entries[1];
|
||||
ID3D12GraphicsCommandList *command_list;
|
||||
D3D12_ROOT_PARAMETER root_parameters[4];
|
||||
ID3D12RootSignature *root_signatures[2];
|
||||
ID3D12Resource *argument_buffer_late;
|
||||
D3D12_STREAM_OUTPUT_BUFFER_VIEW sov;
|
||||
ID3D12Resource *streamout_buffer;
|
||||
D3D12_VERTEX_BUFFER_VIEW vbvs[2];
|
||||
ID3D12Resource *argument_buffer;
|
||||
struct test_context_desc desc;
|
||||
ID3D12PipelineState *psos[2];
|
||||
struct test_context context;
|
||||
struct resource_readback rb;
|
||||
D3D12_INDEX_BUFFER_VIEW ibv;
|
||||
ID3D12CommandQueue *queue;
|
||||
const UINT so_stride = 16;
|
||||
ID3D12Resource *vbo[3];
|
||||
ID3D12Resource *ibo[2];
|
||||
unsigned int i, j, k;
|
||||
ID3D12Resource *cbv;
|
||||
ID3D12Resource *srv;
|
||||
ID3D12Resource *uav;
|
||||
HRESULT hr;
|
||||
|
||||
static const D3D12_INPUT_ELEMENT_DESC layout_desc[] =
|
||||
{
|
||||
{"COLOR", 0, DXGI_FORMAT_R32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
|
||||
{"COLOR", 1, DXGI_FORMAT_R32_FLOAT, 1, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
|
||||
};
|
||||
|
||||
struct test
|
||||
{
|
||||
const D3D12_INDIRECT_ARGUMENT_DESC *indirect_arguments;
|
||||
uint32_t indirect_argument_count;
|
||||
const void *argument_buffer_data;
|
||||
size_t argument_buffer_size;
|
||||
uint32_t api_max_count;
|
||||
const struct vec4 *expected_output;
|
||||
uint32_t expected_output_count;
|
||||
uint32_t stride;
|
||||
uint32_t pso_index;
|
||||
bool needs_root_sig;
|
||||
};
|
||||
|
||||
/* Modify root parameters. */
|
||||
struct root_constant_data
|
||||
{
|
||||
float constants[2];
|
||||
D3D12_DRAW_INDEXED_ARGUMENTS indexed;
|
||||
};
|
||||
|
||||
static const D3D12_INDIRECT_ARGUMENT_DESC root_constant_sig[2] =
|
||||
{
|
||||
{ .Type = D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT, .Constant = {
|
||||
.RootParameterIndex = 0, .DestOffsetIn32BitValues = 1, .Num32BitValuesToSet = 2 }},
|
||||
{ .Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED }
|
||||
};
|
||||
|
||||
static const struct root_constant_data root_constant_data[] =
|
||||
{
|
||||
{
|
||||
.constants = { 100.0f, 500.0f },
|
||||
.indexed = { .IndexCountPerInstance = 2, .InstanceCount = 1 }
|
||||
},
|
||||
{
|
||||
.constants = { 200.0f, 800.0f },
|
||||
.indexed = { .IndexCountPerInstance = 1, .InstanceCount = 2,
|
||||
.StartIndexLocation = 1, .StartInstanceLocation = 100, }
|
||||
},
|
||||
};
|
||||
|
||||
static const struct vec4 root_constant_expected[] =
|
||||
{
|
||||
{ 1000.0f, 64.0f + 100.0f, 500.0f, 4000.0f },
|
||||
{ 1001.0f, 65.0f + 100.0f, 500.0f, 4000.0f },
|
||||
{ 1001.0f, 65.0f + 200.0f, 800.0f, 4000.0f },
|
||||
{ 1001.0f, 65.0f + 200.0f, 800.0f, 4001.0f },
|
||||
};
|
||||
|
||||
/* Modify root parameters, but very large root signature to test boundary conditions. */
|
||||
static const D3D12_INDIRECT_ARGUMENT_DESC root_constant_spill_sig[2] =
|
||||
{
|
||||
{ .Type = D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT, .Constant = {
|
||||
.RootParameterIndex = 0, .DestOffsetIn32BitValues = 44 + 1, .Num32BitValuesToSet = 2 }},
|
||||
{ .Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED }
|
||||
};
|
||||
|
||||
static const struct root_constant_data root_constant_spill_data[] =
|
||||
{
|
||||
{
|
||||
.constants = { 100.0f, 500.0f },
|
||||
.indexed = { .IndexCountPerInstance = 2, .InstanceCount = 1 }
|
||||
},
|
||||
{
|
||||
.constants = { 200.0f, 800.0f },
|
||||
.indexed = { .IndexCountPerInstance = 1, .InstanceCount = 2,
|
||||
.StartIndexLocation = 1, .StartInstanceLocation = 100, }
|
||||
},
|
||||
};
|
||||
|
||||
static const struct vec4 root_constant_spill_expected[] =
|
||||
{
|
||||
{ 1000.0f, 64.0f + 100.0f, 500.0f, 4000.0f },
|
||||
{ 1001.0f, 65.0f + 100.0f, 500.0f, 4000.0f },
|
||||
{ 1001.0f, 65.0f + 200.0f, 800.0f, 4000.0f },
|
||||
{ 1001.0f, 65.0f + 200.0f, 800.0f, 4001.0f },
|
||||
};
|
||||
|
||||
/* Modify VBOs. */
|
||||
struct indirect_vbo_data
|
||||
{
|
||||
D3D12_VERTEX_BUFFER_VIEW view[2];
|
||||
D3D12_DRAW_INDEXED_ARGUMENTS indexed;
|
||||
};
|
||||
|
||||
static const D3D12_INDIRECT_ARGUMENT_DESC indirect_vbo_sig[3] =
|
||||
{
|
||||
{ .Type = D3D12_INDIRECT_ARGUMENT_TYPE_VERTEX_BUFFER_VIEW, .VertexBuffer = { .Slot = 0 }},
|
||||
{ .Type = D3D12_INDIRECT_ARGUMENT_TYPE_VERTEX_BUFFER_VIEW, .VertexBuffer = { .Slot = 1 }},
|
||||
{ .Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED },
|
||||
};
|
||||
|
||||
/* Fill buffer locations later. */
|
||||
struct indirect_vbo_data indirect_vbo_data[] =
|
||||
{
|
||||
{
|
||||
.view = { { 0, 64, 8 }, { 0, 64, 16 } },
|
||||
.indexed = { .IndexCountPerInstance = 2, .InstanceCount = 2 }
|
||||
},
|
||||
{
|
||||
/* Test indirectly binding NULL descriptor and 0 stride. */
|
||||
.view = { { 0, 0, 0 }, { 0, 64, 0 } },
|
||||
.indexed = { .IndexCountPerInstance = 2, .InstanceCount = 1 }
|
||||
}
|
||||
};
|
||||
|
||||
static const struct vec4 indirect_vbo_expected[] =
|
||||
{
|
||||
{ 1064.0f, 2128.0f, 3000.0f, 4000.0f },
|
||||
{ 1066.0f, 2132.0f, 3000.0f, 4000.0f },
|
||||
{ 1064.0f, 2128.0f, 3000.0f, 4001.0f },
|
||||
{ 1066.0f, 2132.0f, 3000.0f, 4001.0f },
|
||||
{ 1000.0f, 2016.0f, 3000.0f, 4000.0f }, /* This is buggy on WARP and AMD. We seem to get null descriptor instead. */
|
||||
{ 1000.0f, 2016.0f, 3000.0f, 4000.0f }, /* This is buggy on WARP and AMD. */
|
||||
};
|
||||
|
||||
/* Modify just one VBO. */
|
||||
struct indirect_vbo_one_data
|
||||
{
|
||||
D3D12_VERTEX_BUFFER_VIEW view;
|
||||
D3D12_DRAW_INDEXED_ARGUMENTS indexed;
|
||||
};
|
||||
|
||||
static const D3D12_INDIRECT_ARGUMENT_DESC indirect_vbo_one_sig[2] =
|
||||
{
|
||||
{ .Type = D3D12_INDIRECT_ARGUMENT_TYPE_VERTEX_BUFFER_VIEW, .VertexBuffer = { .Slot = 0 }},
|
||||
{ .Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED },
|
||||
};
|
||||
|
||||
/* Fill buffer locations later. */
|
||||
struct indirect_vbo_one_data indirect_vbo_one_data[] =
|
||||
{
|
||||
{
|
||||
.view = { 0, 64, 8 },
|
||||
.indexed = { .IndexCountPerInstance = 2, .InstanceCount = 1 }
|
||||
},
|
||||
{
|
||||
.indexed = { .IndexCountPerInstance = 1, .InstanceCount = 1 }
|
||||
}
|
||||
};
|
||||
|
||||
static const struct vec4 indirect_vbo_one_expected[] =
|
||||
{
|
||||
{ 1128.0f, 2064.0f, 3000.0f, 4000.0f },
|
||||
{ 1130.0f, 2065.0f, 3000.0f, 4000.0f },
|
||||
{ 1000.0f, 2064.0f, 3000.0f, 4000.0f },
|
||||
};
|
||||
|
||||
/* Indirect IBO */
|
||||
struct indirect_ibo_data
|
||||
{
|
||||
D3D12_INDEX_BUFFER_VIEW view;
|
||||
D3D12_DRAW_INDEXED_ARGUMENTS indexed;
|
||||
};
|
||||
|
||||
static const D3D12_INDIRECT_ARGUMENT_DESC indirect_ibo_sig[2] =
|
||||
{
|
||||
{ .Type = D3D12_INDIRECT_ARGUMENT_TYPE_INDEX_BUFFER_VIEW },
|
||||
{ .Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED },
|
||||
};
|
||||
|
||||
struct indirect_ibo_data indirect_ibo_data[] =
|
||||
{
|
||||
{
|
||||
.view = { 0, 0, DXGI_FORMAT_R32_UINT },
|
||||
.indexed = { .IndexCountPerInstance = 2, .InstanceCount = 1 }
|
||||
},
|
||||
{
|
||||
.view = { 0, 64, DXGI_FORMAT_R16_UINT },
|
||||
.indexed = { .IndexCountPerInstance = 4, .InstanceCount = 1 }
|
||||
},
|
||||
};
|
||||
|
||||
static const struct vec4 indirect_ibo_expected[] =
|
||||
{
|
||||
{ 1000.0f, 2064.0f, 3000.0f, 4000.0f },
|
||||
{ 1000.0f, 2064.0f, 3000.0f, 4000.0f },
|
||||
{ 1016.0f, 2080.0f, 3000.0f, 4000.0f },
|
||||
{ 1000.0f, 2064.0f, 3000.0f, 4000.0f },
|
||||
{ 1017.0f, 2081.0f, 3000.0f, 4000.0f },
|
||||
{ 1000.0f, 2064.0f, 3000.0f, 4000.0f },
|
||||
};
|
||||
|
||||
/* Indirect root arguments */
|
||||
struct indirect_root_descriptor_data
|
||||
{
|
||||
D3D12_GPU_VIRTUAL_ADDRESS cbv;
|
||||
D3D12_GPU_VIRTUAL_ADDRESS srv;
|
||||
D3D12_GPU_VIRTUAL_ADDRESS uav;
|
||||
D3D12_DRAW_ARGUMENTS array;
|
||||
};
|
||||
|
||||
static const D3D12_INDIRECT_ARGUMENT_DESC indirect_root_descriptor_sig[4] =
|
||||
{
|
||||
{ .Type = D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT_BUFFER_VIEW, .ConstantBufferView = { .RootParameterIndex = 1 } },
|
||||
{ .Type = D3D12_INDIRECT_ARGUMENT_TYPE_SHADER_RESOURCE_VIEW, .ShaderResourceView = { .RootParameterIndex = 2 } },
|
||||
{ .Type = D3D12_INDIRECT_ARGUMENT_TYPE_UNORDERED_ACCESS_VIEW, .UnorderedAccessView = { .RootParameterIndex = 3 } },
|
||||
{ .Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW },
|
||||
};
|
||||
|
||||
struct indirect_root_descriptor_data indirect_root_descriptor_data[] =
|
||||
{
|
||||
{ .array = { .VertexCountPerInstance = 1, .InstanceCount = 1 } },
|
||||
{ .array = { .VertexCountPerInstance = 1, .InstanceCount = 1 } },
|
||||
};
|
||||
|
||||
static const struct vec4 indirect_root_descriptor_expected[] =
|
||||
{
|
||||
{ 1000.0f, 2064.0f, 3000.0f + 64.0f, 4000.0f + 2.0f },
|
||||
{ 1000.0f, 2064.0f, 3000.0f + 128.0f, 4000.0f + 3.0f },
|
||||
};
|
||||
|
||||
/* Test packing rules.
|
||||
* 64-bit aligned values are tightly packed with 32-bit alignment when they are in indirect command buffers. */
|
||||
struct indirect_alignment_data
|
||||
{
|
||||
float value;
|
||||
uint32_t cbv_va[2];
|
||||
D3D12_DRAW_ARGUMENTS arrays;
|
||||
};
|
||||
static const D3D12_INDIRECT_ARGUMENT_DESC indirect_alignment_sig[3] =
|
||||
{
|
||||
{ .Type = D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT, .Constant = {
|
||||
.RootParameterIndex = 0, .DestOffsetIn32BitValues = 1, .Num32BitValuesToSet = 1 }},
|
||||
{ .Type = D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT_BUFFER_VIEW, .ConstantBufferView = { .RootParameterIndex = 1 }},
|
||||
{ .Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW },
|
||||
};
|
||||
|
||||
struct indirect_alignment_data indirect_alignment_data[] =
|
||||
{
|
||||
{
|
||||
.value = 5.0f,
|
||||
.arrays = { .VertexCountPerInstance = 1, .InstanceCount = 1 }
|
||||
},
|
||||
{
|
||||
.value = 6.0f,
|
||||
.arrays = { .VertexCountPerInstance = 1, .InstanceCount = 1 }
|
||||
},
|
||||
};
|
||||
|
||||
static const struct vec4 indirect_alignment_expected[] =
|
||||
{
|
||||
{ 1000.0f, 69.0f, 3064.0f, 4000.0f },
|
||||
{ 1000.0f, 70.0f, 3128.0f, 4000.0f },
|
||||
};
|
||||
|
||||
#define DECL_TEST(t, pso_index, needs_root_sig) { t##_sig, ARRAY_SIZE(t##_sig), t##_data, sizeof(t##_data), ARRAY_SIZE(t##_data), \
|
||||
t##_expected, ARRAY_SIZE(t##_expected), sizeof(*(t##_data)), pso_index, needs_root_sig }
|
||||
const struct test tests[] =
|
||||
{
|
||||
DECL_TEST(root_constant, 0, true),
|
||||
DECL_TEST(indirect_vbo, 0, false),
|
||||
DECL_TEST(indirect_vbo_one, 0, false),
|
||||
DECL_TEST(indirect_ibo, 0, false),
|
||||
DECL_TEST(indirect_root_descriptor, 0, true),
|
||||
DECL_TEST(indirect_alignment, 0, true),
|
||||
DECL_TEST(root_constant_spill, 1, true),
|
||||
DECL_TEST(indirect_root_descriptor, 1, true),
|
||||
};
|
||||
#undef DECL_TEST
|
||||
|
||||
uint32_t ibo_data[ARRAY_SIZE(ibo)][64];
|
||||
float vbo_data[ARRAY_SIZE(vbo)][64];
|
||||
float generic_data[4096];
|
||||
|
||||
static const DWORD vs_code_small_cbv[] =
|
||||
{
|
||||
#if 0
|
||||
cbuffer RootCBV : register(b0)
|
||||
{
|
||||
float a;
|
||||
};
|
||||
|
||||
StructuredBuffer<float> RootSRV : register(t0);
|
||||
|
||||
cbuffer RootConstants : register(b0, space1)
|
||||
{
|
||||
float4 root;
|
||||
};
|
||||
|
||||
float4 main(float c0 : COLOR0, float c1 : COLOR1, uint iid : SV_InstanceID) : SV_Position
|
||||
{
|
||||
return float4(c0, c1, a, RootSRV[0] + float(iid)) + root;
|
||||
}
|
||||
#endif
|
||||
0x43425844, 0x33b7b302, 0x34259b9b, 0x3e8568d9, 0x5a5e0c3e, 0x00000001, 0x00000268, 0x00000003,
|
||||
0x0000002c, 0x00000098, 0x000000cc, 0x4e475349, 0x00000064, 0x00000003, 0x00000008, 0x00000050,
|
||||
0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000101, 0x00000050, 0x00000001, 0x00000000,
|
||||
0x00000003, 0x00000001, 0x00000101, 0x00000056, 0x00000000, 0x00000008, 0x00000001, 0x00000002,
|
||||
0x00000101, 0x4f4c4f43, 0x56530052, 0x736e495f, 0x636e6174, 0x00444965, 0x4e47534f, 0x0000002c,
|
||||
0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f,
|
||||
0x505f5653, 0x7469736f, 0x006e6f69, 0x58454853, 0x00000194, 0x00010051, 0x00000065, 0x0100086a,
|
||||
0x07000059, 0x00308e46, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x07000059,
|
||||
0x00308e46, 0x00000001, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x070000a2, 0x00307e46,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00000000, 0x0300005f, 0x00101012, 0x00000000,
|
||||
0x0300005f, 0x00101012, 0x00000001, 0x04000060, 0x00101012, 0x00000002, 0x00000008, 0x04000067,
|
||||
0x001020f2, 0x00000000, 0x00000001, 0x02000068, 0x00000001, 0x0a0000a7, 0x00100012, 0x00000000,
|
||||
0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x00207006, 0x00000000, 0x00000000, 0x05000056,
|
||||
0x00100022, 0x00000000, 0x0010100a, 0x00000002, 0x07000000, 0x00100012, 0x00000000, 0x0010001a,
|
||||
0x00000000, 0x0010000a, 0x00000000, 0x09000000, 0x00102012, 0x00000000, 0x0010100a, 0x00000000,
|
||||
0x0030800a, 0x00000001, 0x00000000, 0x00000000, 0x09000000, 0x00102022, 0x00000000, 0x0010100a,
|
||||
0x00000001, 0x0030801a, 0x00000001, 0x00000000, 0x00000000, 0x0b000000, 0x00102042, 0x00000000,
|
||||
0x0030800a, 0x00000000, 0x00000000, 0x00000000, 0x0030802a, 0x00000001, 0x00000000, 0x00000000,
|
||||
0x09000000, 0x00102082, 0x00000000, 0x0010000a, 0x00000000, 0x0030803a, 0x00000001, 0x00000000,
|
||||
0x00000000, 0x0100003e,
|
||||
};
|
||||
|
||||
static const DWORD vs_code_large_cbv[] =
|
||||
{
|
||||
#if 0
|
||||
cbuffer RootCBV : register(b0)
|
||||
{
|
||||
float a;
|
||||
};
|
||||
|
||||
StructuredBuffer<float> RootSRV : register(t0);
|
||||
|
||||
cbuffer RootConstants : register(b0, space1)
|
||||
{
|
||||
// Cannot use arrays for root constants in D3D12.
|
||||
float4 pad0, pad1, pad2, pad3, pad4, pad5, pad6, pad7, pad8, pad9, pad10;
|
||||
float4 root;
|
||||
};
|
||||
|
||||
float4 main(float c0 : COLOR0, float c1 : COLOR1, uint iid : SV_InstanceID) : SV_Position
|
||||
{
|
||||
return float4(c0, c1, a, RootSRV[0] + float(iid)) + root;
|
||||
}
|
||||
#endif
|
||||
0x43425844, 0x99a057e8, 0x20344569, 0x434f8a7a, 0xf9171e08, 0x00000001, 0x00000268, 0x00000003,
|
||||
0x0000002c, 0x00000098, 0x000000cc, 0x4e475349, 0x00000064, 0x00000003, 0x00000008, 0x00000050,
|
||||
0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000101, 0x00000050, 0x00000001, 0x00000000,
|
||||
0x00000003, 0x00000001, 0x00000101, 0x00000056, 0x00000000, 0x00000008, 0x00000001, 0x00000002,
|
||||
0x00000101, 0x4f4c4f43, 0x56530052, 0x736e495f, 0x636e6174, 0x00444965, 0x4e47534f, 0x0000002c,
|
||||
0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f,
|
||||
0x505f5653, 0x7469736f, 0x006e6f69, 0x58454853, 0x00000194, 0x00010051, 0x00000065, 0x0100086a,
|
||||
0x07000059, 0x00308e46, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x07000059,
|
||||
0x00308e46, 0x00000001, 0x00000000, 0x00000000, 0x0000000c, 0x00000001, 0x070000a2, 0x00307e46,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00000000, 0x0300005f, 0x00101012, 0x00000000,
|
||||
0x0300005f, 0x00101012, 0x00000001, 0x04000060, 0x00101012, 0x00000002, 0x00000008, 0x04000067,
|
||||
0x001020f2, 0x00000000, 0x00000001, 0x02000068, 0x00000001, 0x0a0000a7, 0x00100012, 0x00000000,
|
||||
0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x00207006, 0x00000000, 0x00000000, 0x05000056,
|
||||
0x00100022, 0x00000000, 0x0010100a, 0x00000002, 0x07000000, 0x00100012, 0x00000000, 0x0010001a,
|
||||
0x00000000, 0x0010000a, 0x00000000, 0x09000000, 0x00102012, 0x00000000, 0x0010100a, 0x00000000,
|
||||
0x0030800a, 0x00000001, 0x00000000, 0x0000000b, 0x09000000, 0x00102022, 0x00000000, 0x0010100a,
|
||||
0x00000001, 0x0030801a, 0x00000001, 0x00000000, 0x0000000b, 0x0b000000, 0x00102042, 0x00000000,
|
||||
0x0030800a, 0x00000000, 0x00000000, 0x00000000, 0x0030802a, 0x00000001, 0x00000000, 0x0000000b,
|
||||
0x09000000, 0x00102082, 0x00000000, 0x0010000a, 0x00000000, 0x0030803a, 0x00000001, 0x00000000,
|
||||
0x0000000b, 0x0100003e,
|
||||
};
|
||||
|
||||
memset(&desc, 0, sizeof(desc));
|
||||
desc.no_root_signature = true;
|
||||
desc.no_pipeline = true;
|
||||
if (!init_test_context(&context, &desc))
|
||||
return;
|
||||
command_list = context.list;
|
||||
queue = context.queue;
|
||||
|
||||
for (j = 0; j < ARRAY_SIZE(ibo); j++)
|
||||
for (i = 0; i < ARRAY_SIZE(ibo_data[j]); i++)
|
||||
ibo_data[j][i] = j * 16 + i;
|
||||
|
||||
for (j = 0; j < ARRAY_SIZE(vbo); j++)
|
||||
for (i = 0; i < ARRAY_SIZE(vbo_data[j]); i++)
|
||||
vbo_data[j][i] = (float)(j * ARRAY_SIZE(vbo_data[j]) + i);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(generic_data); i++)
|
||||
generic_data[i] = (float)i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ibo); i++)
|
||||
ibo[i] = create_upload_buffer(context.device, sizeof(ibo_data[i]), ibo_data[i]);
|
||||
for (i = 0; i < ARRAY_SIZE(vbo); i++)
|
||||
vbo[i] = create_upload_buffer(context.device, sizeof(vbo_data[i]), vbo_data[i]);
|
||||
cbv = create_upload_buffer(context.device, sizeof(generic_data), generic_data);
|
||||
srv = create_upload_buffer(context.device, sizeof(generic_data), generic_data);
|
||||
uav = create_default_buffer(context.device, sizeof(generic_data),
|
||||
D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS,
|
||||
D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
|
||||
|
||||
indirect_vbo_data[0].view[0].BufferLocation = ID3D12Resource_GetGPUVirtualAddress(vbo[1]);
|
||||
indirect_vbo_data[0].view[1].BufferLocation = ID3D12Resource_GetGPUVirtualAddress(vbo[2]);
|
||||
indirect_vbo_data[1].view[0].BufferLocation = 0;
|
||||
indirect_vbo_data[1].view[1].BufferLocation = ID3D12Resource_GetGPUVirtualAddress(vbo[0]) + 64;
|
||||
|
||||
indirect_vbo_one_data[0].view.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(vbo[2]);
|
||||
indirect_vbo_one_data[1].view.BufferLocation = 0;
|
||||
|
||||
indirect_ibo_data[1].view.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(ibo[1]);
|
||||
|
||||
indirect_root_descriptor_data[0].cbv = ID3D12Resource_GetGPUVirtualAddress(cbv) + 256;
|
||||
indirect_root_descriptor_data[0].srv = ID3D12Resource_GetGPUVirtualAddress(srv) + 8;
|
||||
indirect_root_descriptor_data[0].uav = ID3D12Resource_GetGPUVirtualAddress(uav) + 4;
|
||||
indirect_root_descriptor_data[1].cbv = ID3D12Resource_GetGPUVirtualAddress(cbv) + 512;
|
||||
indirect_root_descriptor_data[1].srv = ID3D12Resource_GetGPUVirtualAddress(srv) + 12;
|
||||
indirect_root_descriptor_data[1].uav = ID3D12Resource_GetGPUVirtualAddress(uav) + 8;
|
||||
|
||||
memcpy(indirect_alignment_data[0].cbv_va, &indirect_root_descriptor_data[0].cbv, sizeof(D3D12_GPU_VIRTUAL_ADDRESS));
|
||||
memcpy(indirect_alignment_data[1].cbv_va, &indirect_root_descriptor_data[1].cbv, sizeof(D3D12_GPU_VIRTUAL_ADDRESS));
|
||||
|
||||
memset(&root_signature_desc, 0, sizeof(root_signature_desc));
|
||||
root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |
|
||||
D3D12_ROOT_SIGNATURE_FLAG_ALLOW_STREAM_OUTPUT;
|
||||
|
||||
memset(root_parameters, 0, sizeof(root_parameters));
|
||||
root_signature_desc.pParameters = root_parameters;
|
||||
root_signature_desc.NumParameters = ARRAY_SIZE(root_parameters);
|
||||
root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
|
||||
root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
|
||||
root_parameters[0].Constants.RegisterSpace = 1;
|
||||
root_parameters[0].Constants.Num32BitValues = 4;
|
||||
root_parameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
|
||||
root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV;
|
||||
root_parameters[2].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
|
||||
root_parameters[2].ParameterType = D3D12_ROOT_PARAMETER_TYPE_SRV;
|
||||
root_parameters[3].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
|
||||
root_parameters[3].ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV;
|
||||
hr = create_root_signature(context.device, &root_signature_desc, &root_signatures[0]);
|
||||
ok(SUCCEEDED(hr), "Failed to create root signature, hr #%x.\n", hr);
|
||||
root_parameters[0].Constants.Num32BitValues = 48;
|
||||
hr = create_root_signature(context.device, &root_signature_desc, &root_signatures[1]);
|
||||
ok(SUCCEEDED(hr), "Failed to create root signature, hr #%x.\n", hr);
|
||||
|
||||
memset(so_entries, 0, sizeof(so_entries));
|
||||
so_entries[0].ComponentCount = 4;
|
||||
so_entries[0].SemanticName = "SV_Position";
|
||||
|
||||
memset(&pso_desc, 0, sizeof(pso_desc));
|
||||
pso_desc.VS.pShaderBytecode = vs_code_small_cbv;
|
||||
pso_desc.VS.BytecodeLength = sizeof(vs_code_small_cbv);
|
||||
pso_desc.StreamOutput.NumStrides = 1;
|
||||
pso_desc.StreamOutput.pBufferStrides = &so_stride;
|
||||
pso_desc.StreamOutput.pSODeclaration = so_entries;
|
||||
pso_desc.StreamOutput.NumEntries = ARRAY_SIZE(so_entries);
|
||||
pso_desc.StreamOutput.RasterizedStream = D3D12_SO_NO_RASTERIZED_STREAM;
|
||||
pso_desc.pRootSignature = root_signatures[0];
|
||||
pso_desc.SampleDesc.Count = 1;
|
||||
pso_desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT;
|
||||
pso_desc.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID;
|
||||
pso_desc.RasterizerState.CullMode = D3D12_CULL_MODE_NONE;
|
||||
pso_desc.InputLayout.NumElements = ARRAY_SIZE(layout_desc);
|
||||
pso_desc.InputLayout.pInputElementDescs = layout_desc;
|
||||
hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc, &IID_ID3D12PipelineState, (void**)&psos[0]);
|
||||
ok(SUCCEEDED(hr), "Failed to create PSO, hr #%x.\n", hr);
|
||||
pso_desc.VS.pShaderBytecode = vs_code_large_cbv;
|
||||
pso_desc.VS.BytecodeLength = sizeof(vs_code_large_cbv);
|
||||
pso_desc.pRootSignature = root_signatures[1];
|
||||
hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc, &IID_ID3D12PipelineState, (void**)&psos[1]);
|
||||
ok(SUCCEEDED(hr), "Failed to create PSO, hr #%x.\n", hr);
|
||||
|
||||
/* Verify sanity checks.
|
||||
* As per validation layers, there must be exactly one command in the signature.
|
||||
* It must come last. Verify that we check for this. */
|
||||
memset(&command_signature_desc, 0, sizeof(command_signature_desc));
|
||||
command_signature_desc.NumArgumentDescs = 1;
|
||||
command_signature_desc.pArgumentDescs = indirect_argument_descs;
|
||||
command_signature_desc.ByteStride = sizeof(D3D12_VERTEX_BUFFER_VIEW);
|
||||
indirect_argument_descs[0].Type = D3D12_INDIRECT_ARGUMENT_TYPE_VERTEX_BUFFER_VIEW;
|
||||
hr = ID3D12Device_CreateCommandSignature(context.device, &command_signature_desc, NULL,
|
||||
&IID_ID3D12CommandSignature, (void**)&command_signature);
|
||||
ok(hr == E_INVALIDARG, "Unexpected hr #%x.\n", hr);
|
||||
|
||||
command_signature_desc.NumArgumentDescs = 2;
|
||||
command_signature_desc.pArgumentDescs = indirect_argument_descs;
|
||||
command_signature_desc.ByteStride = sizeof(D3D12_DRAW_INDEXED_ARGUMENTS) + sizeof(D3D12_VERTEX_BUFFER_VIEW);
|
||||
indirect_argument_descs[0].Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED;
|
||||
indirect_argument_descs[1].Type = D3D12_INDIRECT_ARGUMENT_TYPE_VERTEX_BUFFER_VIEW;
|
||||
hr = ID3D12Device_CreateCommandSignature(context.device, &command_signature_desc, NULL,
|
||||
&IID_ID3D12CommandSignature, (void**)&command_signature);
|
||||
ok(hr == E_INVALIDARG, "Unexpected hr #%x.\n", hr);
|
||||
|
||||
command_signature_desc.ByteStride = sizeof(D3D12_DRAW_INDEXED_ARGUMENTS) + sizeof(D3D12_DRAW_INDEXED_ARGUMENTS);
|
||||
indirect_argument_descs[0].Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED;
|
||||
indirect_argument_descs[1].Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED;
|
||||
hr = ID3D12Device_CreateCommandSignature(context.device, &command_signature_desc, NULL,
|
||||
&IID_ID3D12CommandSignature, (void**)&command_signature);
|
||||
ok(hr == E_INVALIDARG, "Unexpected hr #%x.\n", hr);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(tests); i++)
|
||||
{
|
||||
struct vec4 expect_reset_state[2];
|
||||
const struct vec4 *expect, *v;
|
||||
uint32_t expected_output_size;
|
||||
uint32_t clear_vbo_mask;
|
||||
bool root_cbv;
|
||||
uint32_t size;
|
||||
|
||||
vkd3d_test_set_context("Test %u", i);
|
||||
|
||||
command_signature_desc.ByteStride = tests[i].stride;
|
||||
command_signature_desc.pArgumentDescs = tests[i].indirect_arguments;
|
||||
command_signature_desc.NumArgumentDescs = tests[i].indirect_argument_count;
|
||||
command_signature_desc.NodeMask = 0;
|
||||
hr = ID3D12Device_CreateCommandSignature(context.device, &command_signature_desc,
|
||||
tests[i].needs_root_sig ? root_signatures[tests[i].pso_index] : NULL,
|
||||
&IID_ID3D12CommandSignature, (void**)&command_signature);
|
||||
|
||||
/* Updating root CBV requires push BDA path, which we don't enable on NV by default yet. */
|
||||
root_cbv = false;
|
||||
for (j = 0; j < tests[i].indirect_argument_count; j++)
|
||||
{
|
||||
if (tests[i].indirect_arguments[j].Type == D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT_BUFFER_VIEW)
|
||||
{
|
||||
root_cbv = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
if (root_cbv && is_nvidia_device(context.device))
|
||||
skip("Creating indirect root CBV update failed. If the GPU is NVIDIA, try VKD3D_CONFIG=force_raw_va_cbv.\n");
|
||||
else
|
||||
skip("Failed creating command signature, skipping test.\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
argument_buffer = create_upload_buffer(context.device, 256 * 1024, NULL);
|
||||
argument_buffer_late = create_default_buffer(context.device, 256 * 1024,
|
||||
D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COPY_DEST);
|
||||
|
||||
#define UNALIGNED_ARGUMENT_BUFFER_OFFSET (64 * 1024 + 4)
|
||||
#define UNALIGNED_COUNT_BUFFER_OFFSET (128 * 1024 + 4)
|
||||
#define ALIGNED_COUNT_BUFFER_OFFSET (128 * 1024 + 4 * 1024)
|
||||
{
|
||||
uint8_t *ptr;
|
||||
ID3D12Resource_Map(argument_buffer, 0, NULL, (void**)&ptr);
|
||||
memcpy(ptr, tests[i].argument_buffer_data, tests[i].argument_buffer_size);
|
||||
memcpy(ptr + UNALIGNED_ARGUMENT_BUFFER_OFFSET, tests[i].argument_buffer_data, tests[i].argument_buffer_size);
|
||||
memcpy(ptr + UNALIGNED_COUNT_BUFFER_OFFSET, &tests[i].api_max_count, sizeof(tests[i].api_max_count));
|
||||
memcpy(ptr + ALIGNED_COUNT_BUFFER_OFFSET, &tests[i].api_max_count, sizeof(tests[i].api_max_count));
|
||||
ID3D12Resource_Unmap(argument_buffer, 0, NULL);
|
||||
}
|
||||
|
||||
streamout_buffer = create_default_buffer(context.device, 64 * 1024,
|
||||
D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_STREAM_OUT);
|
||||
|
||||
ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, root_signatures[tests[i].pso_index]);
|
||||
ID3D12GraphicsCommandList_SetPipelineState(command_list, psos[tests[i].pso_index]);
|
||||
sov.SizeInBytes = 64 * 1024 - sizeof(struct vec4);
|
||||
sov.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(streamout_buffer) + sizeof(struct vec4);
|
||||
sov.BufferFilledSizeLocation = ID3D12Resource_GetGPUVirtualAddress(streamout_buffer);
|
||||
ID3D12GraphicsCommandList_SOSetTargets(command_list, 0, 1, &sov);
|
||||
|
||||
/* Set up default rendering state. */
|
||||
ibv.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(ibo[0]);
|
||||
ibv.SizeInBytes = sizeof(ibo_data[0]);
|
||||
ibv.Format = DXGI_FORMAT_R32_UINT;
|
||||
vbvs[0].BufferLocation = ID3D12Resource_GetGPUVirtualAddress(vbo[0]);
|
||||
vbvs[0].SizeInBytes = sizeof(vbo_data[0]);
|
||||
vbvs[0].StrideInBytes = 4;
|
||||
vbvs[1].BufferLocation = ID3D12Resource_GetGPUVirtualAddress(vbo[1]);
|
||||
vbvs[1].SizeInBytes = sizeof(vbo_data[1]);
|
||||
vbvs[1].StrideInBytes = 4;
|
||||
|
||||
ID3D12GraphicsCommandList_IASetIndexBuffer(command_list, &ibv);
|
||||
ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_POINTLIST);
|
||||
ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, 2, vbvs);
|
||||
|
||||
for (j = 0; j < (tests[i].pso_index ? 12 : 1); j++)
|
||||
ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 0, 4, &values, 4 * j);
|
||||
|
||||
ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list, 1,
|
||||
ID3D12Resource_GetGPUVirtualAddress(cbv));
|
||||
ID3D12GraphicsCommandList_SetGraphicsRootShaderResourceView(command_list, 2,
|
||||
ID3D12Resource_GetGPUVirtualAddress(srv));
|
||||
ID3D12GraphicsCommandList_SetGraphicsRootUnorderedAccessView(command_list, 3,
|
||||
ID3D12Resource_GetGPUVirtualAddress(uav));
|
||||
ID3D12GraphicsCommandList_ExecuteIndirect(command_list, command_signature, tests[i].api_max_count,
|
||||
argument_buffer, 0, NULL, 0);
|
||||
/* Test equivalent call with indirect count. */
|
||||
ID3D12GraphicsCommandList_ExecuteIndirect(command_list, command_signature, 1024,
|
||||
argument_buffer, UNALIGNED_ARGUMENT_BUFFER_OFFSET,
|
||||
argument_buffer, UNALIGNED_COUNT_BUFFER_OFFSET);
|
||||
/* Test equivalent, but now with late transition to INDIRECT. */
|
||||
ID3D12GraphicsCommandList_CopyResource(command_list, argument_buffer_late, argument_buffer);
|
||||
transition_resource_state(command_list, argument_buffer_late, D3D12_RESOURCE_STATE_COPY_DEST,
|
||||
D3D12_RESOURCE_STATE_INDIRECT_ARGUMENT);
|
||||
ID3D12GraphicsCommandList_ExecuteIndirect(command_list, command_signature, 1024,
|
||||
argument_buffer_late, 0, argument_buffer_late, ALIGNED_COUNT_BUFFER_OFFSET);
|
||||
|
||||
/* Root descriptors which are part of the state block are cleared to NULL. Recover them here
|
||||
* since attempting to draw next test will crash GPU. */
|
||||
ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list, 1,
|
||||
ID3D12Resource_GetGPUVirtualAddress(cbv));
|
||||
ID3D12GraphicsCommandList_SetGraphicsRootShaderResourceView(command_list, 2,
|
||||
ID3D12Resource_GetGPUVirtualAddress(srv));
|
||||
ID3D12GraphicsCommandList_SetGraphicsRootUnorderedAccessView(command_list, 3,
|
||||
ID3D12Resource_GetGPUVirtualAddress(uav));
|
||||
|
||||
/* Other state is cleared to 0. */
|
||||
|
||||
ID3D12GraphicsCommandList_DrawInstanced(command_list, 2, 1, 0, 0);
|
||||
transition_resource_state(command_list, streamout_buffer, D3D12_RESOURCE_STATE_STREAM_OUT, D3D12_RESOURCE_STATE_COPY_SOURCE);
|
||||
|
||||
get_buffer_readback_with_command_list(streamout_buffer, DXGI_FORMAT_R32G32B32A32_FLOAT, &rb, queue, command_list);
|
||||
reset_command_list(command_list, context.allocator);
|
||||
|
||||
expected_output_size = (tests[i].expected_output_count * 3 + 2) * sizeof(struct vec4);
|
||||
size = get_readback_uint(&rb, 0, 0, 0);
|
||||
ok(size == expected_output_size, "Expected size %u, got %u.\n", expected_output_size, size);
|
||||
|
||||
for (j = 0; j < tests[i].expected_output_count; j++)
|
||||
{
|
||||
expect = &tests[i].expected_output[j];
|
||||
v = get_readback_vec4(&rb, j + 1, 0);
|
||||
ok(compare_vec4(v, expect, 0), "Element (direct count) %u failed: (%f, %f, %f, %f) != (%f, %f, %f, %f)\n",
|
||||
j, v->x, v->y, v->z, v->w, expect->x, expect->y, expect->z, expect->w);
|
||||
|
||||
v = get_readback_vec4(&rb, j + tests[i].expected_output_count + 1, 0);
|
||||
ok(compare_vec4(v, expect, 0), "Element (indirect count) %u failed: (%f, %f, %f, %f) != (%f, %f, %f, %f)\n",
|
||||
j, v->x, v->y, v->z, v->w, expect->x, expect->y, expect->z, expect->w);
|
||||
|
||||
v = get_readback_vec4(&rb, j + 2 * tests[i].expected_output_count + 1, 0);
|
||||
ok(compare_vec4(v, expect, 0), "Element (late latch) %u failed: (%f, %f, %f, %f) != (%f, %f, %f, %f)\n",
|
||||
j, v->x, v->y, v->z, v->w, expect->x, expect->y, expect->z, expect->w);
|
||||
}
|
||||
|
||||
clear_vbo_mask = 0;
|
||||
expect_reset_state[0] = values;
|
||||
|
||||
/* Root constant state is cleared to zero if it's part of the signature. */
|
||||
for (j = 0; j < tests[i].indirect_argument_count; j++)
|
||||
{
|
||||
if (tests[i].indirect_arguments[j].Type == D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT)
|
||||
{
|
||||
for (k = 0; k < tests[i].indirect_arguments[j].Constant.Num32BitValuesToSet; k++)
|
||||
(&expect_reset_state[0].x)[(tests[i].indirect_arguments[j].Constant.DestOffsetIn32BitValues + k) % 4] = 0.0f;
|
||||
}
|
||||
else if (tests[i].indirect_arguments[j].Type == D3D12_INDIRECT_ARGUMENT_TYPE_VERTEX_BUFFER_VIEW)
|
||||
clear_vbo_mask |= 1u << tests[i].indirect_arguments[j].VertexBuffer.Slot;
|
||||
}
|
||||
|
||||
expect_reset_state[1] = expect_reset_state[0];
|
||||
|
||||
/* VBO/IBO state is cleared to zero if it's part of the signature.
|
||||
* A NULL IBO should be seen as a IBO which only reads 0 index. */
|
||||
if (!(clear_vbo_mask & (1u << 0)))
|
||||
expect_reset_state[1].x += 1.0f;
|
||||
|
||||
if (!(clear_vbo_mask & (1u << 1)))
|
||||
{
|
||||
expect_reset_state[0].y += 64.0f;
|
||||
expect_reset_state[1].y += 65.0f;
|
||||
}
|
||||
|
||||
for (j = 0; j < 2; j++)
|
||||
{
|
||||
v = get_readback_vec4(&rb, j + 1 + 3 * tests[i].expected_output_count, 0);
|
||||
expect = &expect_reset_state[j];
|
||||
ok(compare_vec4(v, expect, 0), "Post-reset element %u failed: (%f, %f, %f, %f) != (%f, %f, %f, %f)\n",
|
||||
j, v->x, v->y, v->z, v->w, expect->x, expect->y, expect->z, expect->w);
|
||||
}
|
||||
|
||||
ID3D12CommandSignature_Release(command_signature);
|
||||
ID3D12Resource_Release(argument_buffer);
|
||||
ID3D12Resource_Release(argument_buffer_late);
|
||||
ID3D12Resource_Release(streamout_buffer);
|
||||
release_resource_readback(&rb);
|
||||
}
|
||||
vkd3d_test_set_context(NULL);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(psos); i++)
|
||||
ID3D12PipelineState_Release(psos[i]);
|
||||
for (i = 0; i < ARRAY_SIZE(root_signatures); i++)
|
||||
ID3D12RootSignature_Release(root_signatures[i]);
|
||||
for (i = 0; i < ARRAY_SIZE(vbo); i++)
|
||||
ID3D12Resource_Release(vbo[i]);
|
||||
for (i = 0; i < ARRAY_SIZE(ibo); i++)
|
||||
ID3D12Resource_Release(ibo[i]);
|
||||
ID3D12Resource_Release(cbv);
|
||||
ID3D12Resource_Release(srv);
|
||||
ID3D12Resource_Release(uav);
|
||||
|
||||
destroy_test_context(&context);
|
||||
}
|
||||
|
||||
void test_execute_indirect(void)
|
||||
{
|
||||
ID3D12Resource *argument_buffer, *count_buffer, *uav;
|
||||
|
@ -2860,9 +3575,9 @@ void test_conditional_rendering(void)
|
|||
|
||||
void test_write_buffer_immediate(void)
|
||||
{
|
||||
D3D12_WRITEBUFFERIMMEDIATE_PARAMETER parameters[2];
|
||||
D3D12_WRITEBUFFERIMMEDIATE_PARAMETER parameters[3];
|
||||
ID3D12GraphicsCommandList2 *command_list2;
|
||||
D3D12_WRITEBUFFERIMMEDIATE_MODE modes[2];
|
||||
D3D12_WRITEBUFFERIMMEDIATE_MODE modes[3];
|
||||
ID3D12GraphicsCommandList *command_list;
|
||||
struct resource_readback rb;
|
||||
struct test_context context;
|
||||
|
@ -2872,7 +3587,7 @@ void test_write_buffer_immediate(void)
|
|||
unsigned int value;
|
||||
HRESULT hr;
|
||||
|
||||
static const unsigned int data_values[] = {0xdeadbeef, 0xf00baa};
|
||||
static const unsigned int data_values[] = {0xdeadbeef, 0xf00baa, 0xdeadbeef, 0xf00baa};
|
||||
|
||||
if (!init_test_context(&context, NULL))
|
||||
return;
|
||||
|
@ -2897,6 +3612,8 @@ void test_write_buffer_immediate(void)
|
|||
parameters[0].Value = 0x1020304;
|
||||
parameters[1].Dest = parameters[0].Dest + sizeof(data_values[0]);
|
||||
parameters[1].Value = 0xc0d0e0f;
|
||||
parameters[2].Dest = parameters[0].Dest + sizeof(data_values[0]) * 3;
|
||||
parameters[2].Value = 0x5060708;
|
||||
ID3D12GraphicsCommandList2_WriteBufferImmediate(command_list2, ARRAY_SIZE(parameters), parameters, NULL);
|
||||
hr = ID3D12GraphicsCommandList_Close(command_list);
|
||||
ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
|
||||
|
@ -2909,13 +3626,19 @@ void test_write_buffer_immediate(void)
|
|||
ok(value == parameters[0].Value, "Got unexpected value %#x, expected %#x.\n", value, parameters[0].Value);
|
||||
value = get_readback_uint(&rb, 1, 0, 0);
|
||||
ok(value == parameters[1].Value, "Got unexpected value %#x, expected %#x.\n", value, parameters[1].Value);
|
||||
value = get_readback_uint(&rb, 2, 0, 0);
|
||||
ok(value == data_values[2], "Got unexpected value %#x, expected %#x.\n", value, data_values[2]);
|
||||
value = get_readback_uint(&rb, 3, 0, 0);
|
||||
ok(value == parameters[2].Value, "Got unexpected value %#x, expected %#x.\n", value, parameters[2].Value);
|
||||
release_resource_readback(&rb);
|
||||
reset_command_list(command_list, context.allocator);
|
||||
|
||||
parameters[0].Value = 0x2030405;
|
||||
parameters[1].Value = 0xb0c0d0e;
|
||||
modes[0] = D3D12_WRITEBUFFERIMMEDIATE_MODE_MARKER_IN;
|
||||
modes[1] = D3D12_WRITEBUFFERIMMEDIATE_MODE_MARKER_OUT;
|
||||
parameters[2].Value = 0x708090a;
|
||||
modes[0] = D3D12_WRITEBUFFERIMMEDIATE_MODE_DEFAULT;
|
||||
modes[1] = D3D12_WRITEBUFFERIMMEDIATE_MODE_MARKER_IN;
|
||||
modes[2] = D3D12_WRITEBUFFERIMMEDIATE_MODE_MARKER_OUT;
|
||||
ID3D12GraphicsCommandList2_WriteBufferImmediate(command_list2, ARRAY_SIZE(parameters), parameters, modes);
|
||||
hr = ID3D12GraphicsCommandList_Close(command_list);
|
||||
ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
|
||||
|
@ -2928,6 +3651,8 @@ void test_write_buffer_immediate(void)
|
|||
ok(value == parameters[0].Value, "Got unexpected value %#x, expected %#x.\n", value, parameters[0].Value);
|
||||
value = get_readback_uint(&rb, 1, 0, 0);
|
||||
ok(value == parameters[1].Value, "Got unexpected value %#x, expected %#x.\n", value, parameters[1].Value);
|
||||
value = get_readback_uint(&rb, 3, 0, 0);
|
||||
ok(value == parameters[2].Value, "Got unexpected value %#x, expected %#x.\n", value, parameters[2].Value);
|
||||
release_resource_readback(&rb);
|
||||
reset_command_list(command_list, context.allocator);
|
||||
|
||||
|
|
|
@ -554,9 +554,9 @@ void test_copy_texture_buffer(void)
|
|||
|
||||
void test_copy_buffer_to_depth_stencil(void)
|
||||
{
|
||||
ID3D12Resource *src_buffer_stencil = NULL;
|
||||
ID3D12GraphicsCommandList *command_list;
|
||||
struct resource_readback rb_stencil;
|
||||
ID3D12Resource *src_buffer_stencil;
|
||||
struct resource_readback rb_depth;
|
||||
ID3D12Resource *src_buffer_depth;
|
||||
struct test_context_desc desc;
|
||||
|
|
|
@ -4552,31 +4552,41 @@ void test_typed_srv_uav_cast(void)
|
|||
{ DXGI_FORMAT_R16_UINT, DXGI_FORMAT_R16_FLOAT, false, false },
|
||||
{ DXGI_FORMAT_R16_SINT, DXGI_FORMAT_R16_FLOAT, false, false },
|
||||
|
||||
/* Special D3D11 magic. For UAVs, we can reinterpret formats as the "always supported" types R32{U,I,F}.
|
||||
* If typeless, we can cast to any R32U/I/F format.
|
||||
* If not typeless, we follow float <-> non-float ban. */
|
||||
{ DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R32_UINT, false, true },
|
||||
{ DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R32_SINT, false, true },
|
||||
{ DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R32_FLOAT, false, false },
|
||||
{ DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R32_UINT, false, true },
|
||||
{ DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R32_SINT, false, true },
|
||||
{ DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R32_FLOAT, false, false },
|
||||
/* 5.3.9.5 from D3D11 functional spec. 32-bit typeless formats
|
||||
* can be viewed as R32{U,I,F}. The D3D12 validation runtime appears to be buggy
|
||||
* and also allows fully typed views even if bits per component don't match.
|
||||
* This feature is derived from legacy D3D11 jank, so assume the validation layers are
|
||||
* just buggy. */
|
||||
|
||||
{ DXGI_FORMAT_R8G8B8A8_TYPELESS, DXGI_FORMAT_R32_UINT, false, true },
|
||||
{ DXGI_FORMAT_R8G8B8A8_TYPELESS, DXGI_FORMAT_R32_SINT, false, true },
|
||||
{ DXGI_FORMAT_R8G8B8A8_TYPELESS, DXGI_FORMAT_R32_FLOAT, false, true },
|
||||
|
||||
{ DXGI_FORMAT_R16G16_UNORM, DXGI_FORMAT_R32_UINT, false, true },
|
||||
{ DXGI_FORMAT_R16G16_UNORM, DXGI_FORMAT_R32_SINT, false, true },
|
||||
{ DXGI_FORMAT_R16G16_UNORM, DXGI_FORMAT_R32_FLOAT, false, false },
|
||||
{ DXGI_FORMAT_R16G16_UINT, DXGI_FORMAT_R32_UINT, false, true },
|
||||
{ DXGI_FORMAT_R16G16_UINT, DXGI_FORMAT_R32_SINT, false, true },
|
||||
{ DXGI_FORMAT_R16G16_UINT, DXGI_FORMAT_R32_FLOAT, false, false },
|
||||
{ DXGI_FORMAT_R16G16_FLOAT, DXGI_FORMAT_R32_UINT, false, false },
|
||||
{ DXGI_FORMAT_R16G16_FLOAT, DXGI_FORMAT_R32_SINT, false, false },
|
||||
{ DXGI_FORMAT_R16G16_FLOAT, DXGI_FORMAT_R32_FLOAT, false, true },
|
||||
{ DXGI_FORMAT_R16G16_TYPELESS, DXGI_FORMAT_R32_UINT, false, true },
|
||||
{ DXGI_FORMAT_R16G16_TYPELESS, DXGI_FORMAT_R32_SINT, false, true },
|
||||
{ DXGI_FORMAT_R16G16_TYPELESS, DXGI_FORMAT_R32_FLOAT, false, true },
|
||||
|
||||
{ DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R32_FLOAT, false, false },
|
||||
{ DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R32_FLOAT, false, false },
|
||||
{ DXGI_FORMAT_R16G16_UNORM, DXGI_FORMAT_R32_FLOAT, false, false },
|
||||
{ DXGI_FORMAT_R16G16_UINT, DXGI_FORMAT_R32_FLOAT, false, false },
|
||||
{ DXGI_FORMAT_R16G16_FLOAT, DXGI_FORMAT_R32_UINT, false, false },
|
||||
{ DXGI_FORMAT_R16G16_FLOAT, DXGI_FORMAT_R32_SINT, false, false },
|
||||
|
||||
/* D3D12 validation does not complain about these, but it should according to D3D11 functional spec.
|
||||
* No docs for D3D12 say otherwise.
|
||||
* These tests can trip assertions in drivers since we will not emit MUTABLE at all
|
||||
* for some of these tests. */
|
||||
#if 0
|
||||
{ DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R32_UINT, false, true },
|
||||
{ DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R32_SINT, false, true },
|
||||
{ DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R32_UINT, false, true },
|
||||
{ DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R32_SINT, false, true },
|
||||
{ DXGI_FORMAT_R16G16_UNORM, DXGI_FORMAT_R32_UINT, false, true },
|
||||
{ DXGI_FORMAT_R16G16_UNORM, DXGI_FORMAT_R32_SINT, false, true },
|
||||
{ DXGI_FORMAT_R16G16_UINT, DXGI_FORMAT_R32_UINT, false, true },
|
||||
{ DXGI_FORMAT_R16G16_UINT, DXGI_FORMAT_R32_SINT, false, true },
|
||||
{ DXGI_FORMAT_R16G16_FLOAT, DXGI_FORMAT_R32_FLOAT, false, true },
|
||||
#endif
|
||||
};
|
||||
|
||||
if (!init_compute_test_context(&context))
|
||||
|
@ -4877,3 +4887,633 @@ void test_typed_srv_cast_clear(void)
|
|||
ID3D12DescriptorHeap_Release(heap);
|
||||
destroy_test_context(&context);
|
||||
}
|
||||
|
||||
void test_uav_3d_sliced_view(void)
|
||||
{
|
||||
D3D12_UNORDERED_ACCESS_VIEW_DESC uav;
|
||||
D3D12_ROOT_SIGNATURE_DESC rs_desc;
|
||||
D3D12_ROOT_PARAMETER root_params[2];
|
||||
ID3D12PipelineState *pso_poison;
|
||||
ID3D12PipelineState *pso_actual;
|
||||
struct resource_readback rb[2];
|
||||
D3D12_DESCRIPTOR_RANGE range;
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE h;
|
||||
uint32_t reference[16][4][4];
|
||||
struct test_context context;
|
||||
ID3D12DescriptorHeap *heap;
|
||||
ID3D12Resource *resource;
|
||||
unsigned int x, y, z;
|
||||
unsigned int i;
|
||||
|
||||
static const DWORD cs_actual_dxbc[] =
|
||||
{
|
||||
#if 0
|
||||
cbuffer C : register(b0) { uint value; }
|
||||
RWTexture3D<uint> T : register(u0);
|
||||
|
||||
[numthreads(4, 4, 16)]
|
||||
void main(uint3 thr : SV_DispatchThreadID)
|
||||
{
|
||||
uint w, h, d;
|
||||
T.GetDimensions(w, h, d);
|
||||
if (thr.z < d)
|
||||
T[thr] = value | (w << 8) | (h << 16) | (d << 24);
|
||||
}
|
||||
#endif
|
||||
0x43425844, 0xf1736792, 0x8492219a, 0x6751cced, 0xf0219682, 0x00000001, 0x00000188, 0x00000003,
|
||||
0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
|
||||
0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x00000134, 0x00050050, 0x0000004d, 0x0100086a,
|
||||
0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x0400289c, 0x0011e000, 0x00000000, 0x00004444,
|
||||
0x0200005f, 0x00020072, 0x02000068, 0x00000001, 0x0400009b, 0x00000004, 0x00000004, 0x00000010,
|
||||
0x8900103d, 0x80000142, 0x00111103, 0x00100072, 0x00000000, 0x00004001, 0x00000000, 0x0011ee46,
|
||||
0x00000000, 0x0600004f, 0x00100082, 0x00000000, 0x0002002a, 0x0010002a, 0x00000000, 0x0304001f,
|
||||
0x0010003a, 0x00000000, 0x0a000029, 0x00100072, 0x00000000, 0x00100246, 0x00000000, 0x00004002,
|
||||
0x00000008, 0x00000010, 0x00000018, 0x00000000, 0x0800003c, 0x00100012, 0x00000000, 0x0010000a,
|
||||
0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x0700003c, 0x00100012, 0x00000000, 0x0010001a,
|
||||
0x00000000, 0x0010000a, 0x00000000, 0x0700003c, 0x00100012, 0x00000000, 0x0010002a, 0x00000000,
|
||||
0x0010000a, 0x00000000, 0x060000a4, 0x0011e0f2, 0x00000000, 0x00020a46, 0x00100006, 0x00000000,
|
||||
0x01000015, 0x0100003e,
|
||||
};
|
||||
static const D3D12_SHADER_BYTECODE cs_actual = SHADER_BYTECODE(cs_actual_dxbc);
|
||||
|
||||
static const DWORD cs_poison_dxbc[] =
|
||||
{
|
||||
#if 0
|
||||
cbuffer C : register(b0) { uint value; }
|
||||
RWTexture3D<uint> T : register(u0);
|
||||
|
||||
[numthreads(4, 4, 16)]
|
||||
void main(uint3 thr : SV_DispatchThreadID)
|
||||
{
|
||||
T[thr] = 0xdeadca7;
|
||||
}
|
||||
#endif
|
||||
0x43425844, 0x4c99e486, 0x7707bd40, 0xceb3b496, 0xe22f4397, 0x00000001, 0x000000b0, 0x00000003,
|
||||
0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
|
||||
0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x0000005c, 0x00050050, 0x00000017, 0x0100086a,
|
||||
0x0400289c, 0x0011e000, 0x00000000, 0x00004444, 0x0200005f, 0x00020072, 0x0400009b, 0x00000004,
|
||||
0x00000004, 0x00000010, 0x090000a4, 0x0011e0f2, 0x00000000, 0x00020a46, 0x00004002, 0x0deadca7,
|
||||
0x0deadca7, 0x0deadca7, 0x0deadca7, 0x0100003e,
|
||||
};
|
||||
static const D3D12_SHADER_BYTECODE cs_poison = SHADER_BYTECODE(cs_poison_dxbc);
|
||||
|
||||
static const D3D12_TEX3D_UAV slices[] =
|
||||
{
|
||||
/* Just to clear everything */
|
||||
{ 0, 0, -1u }, /* -1 means all remaining slices. */
|
||||
{ 1, 0, -1u },
|
||||
/* ... */
|
||||
|
||||
{ 0, 0, 2 },
|
||||
{ 0, 5, 3 },
|
||||
{ 0, 9, 1 },
|
||||
{ 0, 12, 4 },
|
||||
{ 0, 10, 5 },
|
||||
{ 1, 0, 2 },
|
||||
{ 1, 4, 3 },
|
||||
{ 0, 15, -1u },
|
||||
/* WSize = 0 is not allowed. Trips DEVICE_LOST. */
|
||||
};
|
||||
|
||||
if (!init_compute_test_context(&context))
|
||||
return;
|
||||
|
||||
memset(&rs_desc, 0, sizeof(rs_desc));
|
||||
memset(root_params, 0, sizeof(root_params));
|
||||
memset(&range, 0, sizeof(range));
|
||||
|
||||
rs_desc.NumParameters = ARRAY_SIZE(root_params);
|
||||
rs_desc.pParameters = root_params;
|
||||
|
||||
root_params[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
|
||||
root_params[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
|
||||
root_params[0].DescriptorTable.NumDescriptorRanges = 1;
|
||||
root_params[0].DescriptorTable.pDescriptorRanges = ⦥
|
||||
range.NumDescriptors = 1;
|
||||
range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV;
|
||||
|
||||
root_params[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
|
||||
root_params[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
|
||||
root_params[1].Constants.Num32BitValues = 1;
|
||||
|
||||
create_root_signature(context.device, &rs_desc, &context.root_signature);
|
||||
pso_actual = create_compute_pipeline_state(context.device, context.root_signature, cs_actual);
|
||||
pso_poison = create_compute_pipeline_state(context.device, context.root_signature, cs_poison);
|
||||
|
||||
resource = create_default_texture3d(context.device, 4, 4, 16, 2, DXGI_FORMAT_R32_UINT,
|
||||
D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
|
||||
|
||||
memset(&uav, 0, sizeof(uav));
|
||||
uav.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE3D;
|
||||
uav.Format = DXGI_FORMAT_R32_UINT;
|
||||
|
||||
heap = create_gpu_descriptor_heap(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, ARRAY_SIZE(slices));
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(slices); i++)
|
||||
{
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE h = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap);
|
||||
h.ptr += i * ID3D12Device_GetDescriptorHandleIncrementSize(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
|
||||
uav.Texture3D = slices[i];
|
||||
ID3D12Device_CreateUnorderedAccessView(context.device, resource, NULL, &uav, h);
|
||||
}
|
||||
|
||||
ID3D12GraphicsCommandList_SetDescriptorHeaps(context.list, 1, &heap);
|
||||
ID3D12GraphicsCommandList_SetComputeRootSignature(context.list, context.root_signature);
|
||||
|
||||
h = ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heap);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(slices); i++)
|
||||
{
|
||||
ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(context.list, 0, h);
|
||||
ID3D12GraphicsCommandList_SetComputeRoot32BitConstant(context.list, 1, i + 1, 0);
|
||||
/* First, attempt to flood the descriptor with writes. Validates robustness. */
|
||||
ID3D12GraphicsCommandList_SetPipelineState(context.list, pso_poison);
|
||||
ID3D12GraphicsCommandList_Dispatch(context.list, 1, 1, 1);
|
||||
uav_barrier(context.list, resource);
|
||||
/* Now, only write in bounds. Makes sure FirstWSlice offset works. */
|
||||
ID3D12GraphicsCommandList_SetPipelineState(context.list, pso_actual);
|
||||
ID3D12GraphicsCommandList_Dispatch(context.list, 1, 1, 1);
|
||||
uav_barrier(context.list, resource);
|
||||
|
||||
h.ptr += ID3D12Device_GetDescriptorHandleIncrementSize(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
|
||||
}
|
||||
|
||||
transition_resource_state(context.list, resource, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
|
||||
|
||||
get_texture_readback_with_command_list(resource, 0, &rb[0], context.queue, context.list);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(slices); i++)
|
||||
{
|
||||
unsigned int num_slices;
|
||||
|
||||
if (slices[i].MipSlice != 0)
|
||||
continue;
|
||||
|
||||
num_slices = min(16 - slices[i].FirstWSlice, slices[i].WSize);
|
||||
|
||||
for (z = 0; z < num_slices; z++)
|
||||
{
|
||||
for (y = 0; y < 4; y++)
|
||||
{
|
||||
for (x = 0; x < 4; x++)
|
||||
{
|
||||
uint32_t *ref = &reference[z + slices[i].FirstWSlice][y][x];
|
||||
*ref = i + 1;
|
||||
*ref |= 4 << 8;
|
||||
*ref |= 4 << 16;
|
||||
*ref |= num_slices << 24;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (z = 0; z < 16; z++)
|
||||
{
|
||||
for (y = 0; y < 4; y++)
|
||||
{
|
||||
for (x = 0; x < 4; x++)
|
||||
{
|
||||
uint32_t value;
|
||||
value = get_readback_uint(&rb[0], x, y, z);
|
||||
todo ok(value == reference[z][y][x], "Error for mip 0 at %u, %u, %u. Got %x, expected %x.\n", x, y, z, value, reference[z][y][x]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
reset_command_list(context.list, context.allocator);
|
||||
get_texture_readback_with_command_list(resource, 1, &rb[1], context.queue, context.list);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(slices); i++)
|
||||
{
|
||||
unsigned int num_slices;
|
||||
|
||||
if (slices[i].MipSlice != 1)
|
||||
continue;
|
||||
|
||||
num_slices = min(8 - slices[i].FirstWSlice, slices[i].WSize);
|
||||
|
||||
for (z = 0; z < num_slices; z++)
|
||||
{
|
||||
for (y = 0; y < 2; y++)
|
||||
{
|
||||
for (x = 0; x < 2; x++)
|
||||
{
|
||||
uint32_t *ref = &reference[z + slices[i].FirstWSlice][y][x];
|
||||
*ref = i + 1;
|
||||
*ref |= 2 << 8;
|
||||
*ref |= 2 << 16;
|
||||
*ref |= num_slices << 24;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (z = 0; z < 8; z++)
|
||||
{
|
||||
for (y = 0; y < 2; y++)
|
||||
{
|
||||
for (x = 0; x < 2; x++)
|
||||
{
|
||||
uint32_t value;
|
||||
value = get_readback_uint(&rb[1], x, y, z);
|
||||
todo ok(value == reference[z][y][x], "Error for mip 1 at %u, %u, %u. Got %x, expected %x.\n", x, y, z, value, reference[z][y][x]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(rb); i++)
|
||||
release_resource_readback(&rb[i]);
|
||||
ID3D12Resource_Release(resource);
|
||||
ID3D12PipelineState_Release(pso_actual);
|
||||
ID3D12PipelineState_Release(pso_poison);
|
||||
ID3D12DescriptorHeap_Release(heap);
|
||||
destroy_test_context(&context);
|
||||
}
|
||||
|
||||
void test_root_descriptor_offset_sign(void)
|
||||
{
|
||||
/* Exploratory test in nature. Will likely crash GPU if not on native drivers. Tweak ifdef to run it. */
|
||||
#if 1
|
||||
skip("Skipping exploratory test for root descriptor over/underflow test.\n");
|
||||
#else
|
||||
ID3D12RootSignature *root_signature;
|
||||
D3D12_ROOT_PARAMETER root_params[3];
|
||||
D3D12_ROOT_SIGNATURE_DESC rs_desc;
|
||||
ID3D12Resource *output_buffer;
|
||||
ID3D12Resource *input_buffer;
|
||||
struct resource_readback rb;
|
||||
struct test_context context;
|
||||
ID3D12PipelineState *pso;
|
||||
uint32_t values[4];
|
||||
unsigned int i;
|
||||
|
||||
static const BYTE cs_code_dxil[] =
|
||||
{
|
||||
#if 0
|
||||
RWStructuredBuffer<uint4> RW : register(u0);
|
||||
StructuredBuffer<uint> R0 : register(t0);
|
||||
ByteAddressBuffer R1 : register(t1);
|
||||
|
||||
[numthreads(1, 1, 1)]
|
||||
void main()
|
||||
{
|
||||
uint a = R0[-1]; // Negative index
|
||||
uint b = R0[1u << 30]; // offset 4 GB. Does it overflow back to 0?
|
||||
uint c = R1.Load(-4); // Negative offset
|
||||
uint d = R1.Load(0);
|
||||
RW[0] = uint4(a, b, c, d);
|
||||
}
|
||||
#endif
|
||||
0x44, 0x58, 0x42, 0x43, 0xac, 0xbf, 0xf4, 0x1f, 0x2f, 0x84, 0x34, 0x51, 0x10, 0xd2, 0xe1, 0x21, 0x95, 0x3b, 0xc5, 0x21, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x07, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
|
||||
0x38, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1c, 0x01, 0x00, 0x00, 0x53, 0x46, 0x49, 0x30, 0x08, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x53, 0x47, 0x31, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x4f, 0x53, 0x47, 0x31, 0x08, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x50, 0x53, 0x56, 0x30, 0x90, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x48, 0x41, 0x53, 0x48, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe5, 0x8f, 0xa6, 0x7e, 0x5d, 0xa7, 0xe6, 0xd6, 0x02, 0xac, 0xbd, 0xbf, 0x6f, 0x1b, 0xee, 0xc4, 0x44, 0x58, 0x49, 0x4c,
|
||||
0xe8, 0x05, 0x00, 0x00, 0x60, 0x00, 0x05, 0x00, 0x7a, 0x01, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4c, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xd0, 0x05, 0x00, 0x00, 0x42, 0x43, 0xc0, 0xde,
|
||||
0x21, 0x0c, 0x00, 0x00, 0x71, 0x01, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39,
|
||||
0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x52, 0x88,
|
||||
0x48, 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0xe4, 0x48, 0x0e, 0x90, 0x91, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x29, 0x46, 0x06,
|
||||
0x51, 0x18, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1b, 0x8c, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x40, 0x02, 0xaa, 0x0d, 0x84, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x20, 0x01, 0x00, 0x00, 0x00,
|
||||
0x49, 0x18, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x82, 0x60, 0x42, 0x20, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04,
|
||||
0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x60, 0x23, 0x00, 0x25, 0x00, 0x14, 0xe6, 0x08, 0x10, 0x1a, 0xf7,
|
||||
0x0c, 0x97, 0x3f, 0x61, 0x0f, 0x21, 0xf9, 0x21, 0xd0, 0x0c, 0x0b, 0x81, 0x02, 0x32, 0x47, 0x00, 0x06, 0x73, 0x04, 0x41, 0x31, 0x8a, 0x19, 0xc6, 0x1c, 0x42, 0x37, 0x0d, 0x97, 0x3f, 0x61, 0x0f,
|
||||
0x21, 0xf9, 0x2b, 0x21, 0xad, 0xc4, 0xe4, 0x23, 0xb7, 0x8d, 0x0a, 0x63, 0x8c, 0x31, 0xa5, 0x50, 0xa6, 0x18, 0x43, 0xab, 0x28, 0xc0, 0x14, 0x63, 0x8c, 0x31, 0x66, 0x50, 0x1b, 0x08, 0x98, 0x89,
|
||||
0x0c, 0xc6, 0x81, 0x1d, 0xc2, 0x61, 0x1e, 0xe6, 0xc1, 0x0d, 0x66, 0x81, 0x1e, 0xe4, 0xa1, 0x1e, 0xc6, 0x81, 0x1e, 0xea, 0x41, 0x1e, 0xca, 0x81, 0x1c, 0x44, 0xa1, 0x1e, 0xcc, 0xc1, 0x1c, 0xca,
|
||||
0x41, 0x1e, 0xf8, 0xa0, 0x1e, 0xdc, 0x61, 0x1e, 0xd2, 0xe1, 0x1c, 0xdc, 0xa1, 0x1c, 0xc8, 0x01, 0x0c, 0xd2, 0xc1, 0x1d, 0xe8, 0xc1, 0x0f, 0x50, 0x60, 0x08, 0x1e, 0x26, 0x4d, 0x11, 0x25, 0x4c,
|
||||
0xfe, 0x86, 0x4d, 0x84, 0x36, 0x0c, 0x11, 0x21, 0x49, 0x1b, 0x55, 0x14, 0x44, 0x84, 0x02, 0x43, 0x72, 0x18, 0x81, 0x30, 0x66, 0x92, 0x83, 0x71, 0x60, 0x87, 0x70, 0x98, 0x87, 0x79, 0x70, 0x03,
|
||||
0x59, 0xb8, 0x85, 0x59, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x71, 0xa0, 0x87, 0x7a, 0x90, 0x87, 0x72, 0x20, 0x07, 0x51, 0xa8, 0x07, 0x73, 0x30, 0x87, 0x72, 0x90, 0x07, 0x3e, 0xb0, 0x87, 0x72, 0x18,
|
||||
0x07, 0x7a, 0x78, 0x07, 0x79, 0xe0, 0x83, 0x7a, 0x70, 0x87, 0x79, 0x48, 0x87, 0x73, 0x70, 0x87, 0x72, 0x20, 0x07, 0x30, 0x48, 0x07, 0x77, 0xa0, 0x07, 0x36, 0x00, 0x03, 0x3a, 0xf0, 0x03, 0x30,
|
||||
0xf0, 0x03, 0x14, 0x50, 0xaa, 0x73, 0x04, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x13, 0x14, 0x72, 0xc0, 0x87, 0x74, 0x60, 0x87, 0x36, 0x68, 0x87, 0x79, 0x68, 0x03, 0x72, 0xc0, 0x87, 0x0d, 0xaf, 0x50,
|
||||
0x0e, 0x6d, 0xd0, 0x0e, 0x7a, 0x50, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x78,
|
||||
0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07,
|
||||
0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0,
|
||||
0x07, 0x76, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x43, 0x9e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x86, 0x3c, 0x08, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x79, 0x16, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xf2, 0x34,
|
||||
0x40, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x05, 0x02, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47,
|
||||
0xc6, 0x04, 0x43, 0x32, 0x25, 0x30, 0x02, 0x50, 0x0c, 0x85, 0x51, 0x08, 0x65, 0x51, 0x20, 0x74, 0x46, 0x00, 0xe8, 0x16, 0x08, 0xcd, 0x19, 0x00, 0xb2, 0x33, 0x00, 0x14, 0x67, 0x00, 0x00, 0x00,
|
||||
0x79, 0x18, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x90, 0x46, 0x02, 0x13, 0x44, 0x35, 0x18, 0x63, 0x0b, 0x73, 0x3b, 0x03, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x03, 0x99,
|
||||
0x71, 0xb9, 0x01, 0x41, 0xa1, 0x0b, 0x3b, 0x9b, 0x7b, 0x91, 0x2a, 0x62, 0x2a, 0x0a, 0x9a, 0x2a, 0xfa, 0x9a, 0xb9, 0x81, 0x79, 0x31, 0x4b, 0x73, 0x0b, 0x63, 0x4b, 0xd9, 0x10, 0x04, 0x13, 0x04,
|
||||
0x83, 0x98, 0x20, 0x18, 0xc5, 0x06, 0x61, 0x20, 0x26, 0x08, 0x86, 0xb1, 0x41, 0x18, 0x0c, 0x0a, 0x63, 0x73, 0x1b, 0x06, 0xc4, 0x20, 0x26, 0x08, 0xd1, 0x43, 0x60, 0x82, 0x60, 0x1c, 0x13, 0x04,
|
||||
0x03, 0xd9, 0x20, 0x0c, 0xcd, 0x86, 0x84, 0x50, 0x16, 0x82, 0x18, 0x18, 0xc2, 0x99, 0x20, 0x4c, 0xcd, 0x04, 0xc1, 0x48, 0x36, 0x24, 0x03, 0xb4, 0x10, 0xc3, 0x10, 0x11, 0xc0, 0x06, 0xe1, 0x91,
|
||||
0x26, 0x08, 0x96, 0x33, 0x41, 0x38, 0x96, 0x09, 0x82, 0xa1, 0x6c, 0x10, 0x06, 0x6b, 0xc3, 0x42, 0x50, 0x0b, 0x41, 0x0c, 0x4c, 0x55, 0x55, 0xd7, 0x86, 0x00, 0xdb, 0x40, 0x4c, 0x19, 0x00, 0x4c,
|
||||
0x10, 0x04, 0x80, 0x44, 0x5b, 0x58, 0x9a, 0xdb, 0x04, 0xe1, 0x62, 0x36, 0x0c, 0xc3, 0x30, 0x6c, 0x20, 0x88, 0xae, 0xf1, 0x36, 0x14, 0x1b, 0x07, 0x68, 0x5f, 0x15, 0x36, 0x36, 0xbb, 0x36, 0x97,
|
||||
0x34, 0xb2, 0x32, 0x37, 0xba, 0x29, 0x41, 0x50, 0x85, 0x0c, 0xcf, 0xc5, 0xae, 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x6d, 0x4a, 0x40, 0x34, 0x21, 0xc3, 0x73, 0xb1, 0x0b, 0x63, 0xb3, 0x2b, 0x93, 0x9b,
|
||||
0x12, 0x18, 0x75, 0xc8, 0xf0, 0x5c, 0xe6, 0xd0, 0xc2, 0xc8, 0xca, 0xe4, 0x9a, 0xde, 0xc8, 0xca, 0xd8, 0xa6, 0x04, 0x48, 0x19, 0x32, 0x3c, 0x17, 0xb9, 0xb2, 0xb9, 0xb7, 0x3a, 0xb9, 0xb1, 0xb2,
|
||||
0xb9, 0x29, 0x41, 0x56, 0x87, 0x0c, 0xcf, 0xa5, 0xcc, 0x8d, 0x4e, 0x2e, 0x0f, 0xea, 0x2d, 0xcd, 0x8d, 0x6e, 0x6e, 0x4a, 0xf0, 0x01, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00,
|
||||
0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10,
|
||||
0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03,
|
||||
0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e,
|
||||
0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b,
|
||||
0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90,
|
||||
0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e,
|
||||
0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca,
|
||||
0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82,
|
||||
0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x8c, 0xc8, 0x21, 0x07, 0x7c, 0x70, 0x03, 0x72, 0x10, 0x87, 0x73, 0x70, 0x03, 0x7b, 0x08, 0x07, 0x79, 0x60, 0x87, 0x70, 0xc8, 0x87, 0x77, 0xa8, 0x07, 0x7a,
|
||||
0x00, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x26, 0x40, 0x0d, 0x97, 0xef, 0x3c, 0x7e, 0x40, 0x15, 0x05, 0x11, 0x95, 0x0e, 0x30, 0xf8, 0xc8, 0x6d, 0xdb, 0x40, 0x35,
|
||||
0x5c, 0xbe, 0xf3, 0xf8, 0x01, 0x55, 0x14, 0x44, 0xc4, 0x4e, 0x4e, 0x44, 0xf8, 0xc8, 0x6d, 0x5b, 0x80, 0x34, 0x5c, 0xbe, 0xf3, 0xf8, 0x42, 0x44, 0x00, 0x13, 0x11, 0x02, 0xcd, 0xb0, 0x10, 0x06,
|
||||
0x40, 0x30, 0x00, 0xd2, 0x00, 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x34, 0x46, 0x00, 0x4a,
|
||||
0xa0, 0x3c, 0xc8, 0x14, 0x62, 0x40, 0xc9, 0xcd, 0x00, 0xd4, 0x40, 0x01, 0x02, 0x02, 0x02, 0x22, 0x54, 0x42, 0x29, 0x06, 0x00, 0x00, 0x00, 0x00, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x80, 0x64,
|
||||
0x46, 0x52, 0x55, 0xcf, 0x88, 0x41, 0x02, 0x80, 0x20, 0x18, 0x20, 0xda, 0xb1, 0x5c, 0x17, 0x34, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0xc8, 0x86, 0x30, 0xd7, 0x15, 0x8d, 0x18, 0x20, 0x00, 0x08,
|
||||
0x82, 0xc1, 0xb2, 0x29, 0xc1, 0x81, 0x8d, 0x26, 0x04, 0xc0, 0x88, 0x01, 0x02, 0x80, 0x20, 0x18, 0x2c, 0x1d, 0x33, 0x20, 0xda, 0x68, 0x42, 0x00, 0x8c, 0x18, 0x20, 0x00, 0x08, 0x82, 0xc1, 0xf2,
|
||||
0x39, 0x46, 0xc2, 0x8c, 0x26, 0x04, 0xc0, 0x88, 0x01, 0x02, 0x80, 0x20, 0x18, 0x2c, 0x61, 0x00, 0x21, 0x9e, 0x33, 0x9a, 0x10, 0x00, 0x23, 0x06, 0x0d, 0x00, 0x82, 0x60, 0xd0, 0x88, 0x01, 0xb3,
|
||||
0x80, 0x01, 0x18, 0x1c, 0xc5, 0x10, 0x4c, 0x08, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
static const D3D12_SHADER_BYTECODE cs_code = SHADER_BYTECODE(cs_code_dxil);
|
||||
|
||||
static const uint32_t test_data[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
|
||||
|
||||
memset(&rs_desc, 0, sizeof(rs_desc));
|
||||
rs_desc.NumParameters = ARRAY_SIZE(root_params);
|
||||
rs_desc.pParameters = root_params;
|
||||
memset(root_params, 0, sizeof(root_params));
|
||||
root_params[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
|
||||
root_params[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV;
|
||||
root_params[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
|
||||
root_params[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_SRV;
|
||||
root_params[2].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
|
||||
root_params[2].ParameterType = D3D12_ROOT_PARAMETER_TYPE_SRV;
|
||||
root_params[2].Descriptor.ShaderRegister = 1;
|
||||
|
||||
|
||||
if (!init_compute_test_context(&context))
|
||||
return;
|
||||
|
||||
if (!context_supports_dxil(&context))
|
||||
{
|
||||
destroy_test_context(&context);
|
||||
return;
|
||||
}
|
||||
|
||||
input_buffer = create_upload_buffer(context.device, sizeof(test_data), test_data);
|
||||
output_buffer = create_default_buffer(context.device, 16,
|
||||
D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS,
|
||||
D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
|
||||
create_root_signature(context.device, &rs_desc, &root_signature);
|
||||
pso = create_compute_pipeline_state(context.device, root_signature, cs_code);
|
||||
ID3D12GraphicsCommandList_SetPipelineState(context.list, pso);
|
||||
ID3D12GraphicsCommandList_SetComputeRootSignature(context.list, root_signature);
|
||||
ID3D12GraphicsCommandList_SetComputeRootUnorderedAccessView(context.list, 0,
|
||||
ID3D12Resource_GetGPUVirtualAddress(output_buffer));
|
||||
ID3D12GraphicsCommandList_SetComputeRootShaderResourceView(context.list, 1,
|
||||
ID3D12Resource_GetGPUVirtualAddress(input_buffer) + 16);
|
||||
ID3D12GraphicsCommandList_SetComputeRootShaderResourceView(context.list, 2,
|
||||
ID3D12Resource_GetGPUVirtualAddress(input_buffer) + 16);
|
||||
ID3D12GraphicsCommandList_Dispatch(context.list, 1, 1, 1);
|
||||
transition_resource_state(context.list, output_buffer, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
|
||||
get_buffer_readback_with_command_list(output_buffer, DXGI_FORMAT_R32_UINT, &rb, context.queue, context.list);
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
values[i] = get_readback_uint(&rb, i, 0, 0);
|
||||
|
||||
skip("Got structured access [-1] = #%x\n", values[0]);
|
||||
skip("Got structured access [1u << 30] = #%x\n", values[1]);
|
||||
skip("Got byte address [-4] = #%x\n", values[2]);
|
||||
skip("Got byte address [0] = #%x\n", values[3]);
|
||||
|
||||
/* Observed on AMD:
|
||||
test_root_descriptor_offset_sign:5262: Test skipped: Got structured access [-1] = #4b416743 <-- Garbage. Likely we accessed garbage memory way out at (4 * UINT_MAX) & UINT_MAX offset.
|
||||
test_root_descriptor_offset_sign:5263: Test skipped: Got structured access [1u << 30] = #4 <-- Suggests 32-bit uint offset.
|
||||
test_root_descriptor_offset_sign:5264: Test skipped: Got byte address [-4] = #0 <-- Suggests we hit robustness for driver generated descriptor.
|
||||
test_root_descriptor_offset_sign:5265: Test skipped: Got byte address [0] = #4
|
||||
*/
|
||||
|
||||
/* Observed on NV: Blue screen of death (?!?!). */
|
||||
|
||||
/* Observed on Intel: All 0. Likely faulted and terminated the dispatch before we could write results. */
|
||||
|
||||
ID3D12RootSignature_Release(root_signature);
|
||||
ID3D12PipelineState_Release(pso);
|
||||
ID3D12Resource_Release(input_buffer);
|
||||
ID3D12Resource_Release(output_buffer);
|
||||
release_resource_readback(&rb);
|
||||
destroy_test_context(&context);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void test_uav_counters_null_behavior(bool use_dxil)
|
||||
{
|
||||
D3D12_UNORDERED_ACCESS_VIEW_DESC uav_desc;
|
||||
D3D12_ROOT_SIGNATURE_DESC rs_desc;
|
||||
ID3D12DescriptorHeap *cpu_heap;
|
||||
D3D12_ROOT_PARAMETER rs_param;
|
||||
D3D12_DESCRIPTOR_RANGE range;
|
||||
struct test_context context;
|
||||
struct resource_readback rb;
|
||||
ID3D12DescriptorHeap *heap;
|
||||
ID3D12Resource *resource;
|
||||
unsigned int i;
|
||||
|
||||
#if 0
|
||||
RWStructuredBuffer<uint> RWBuf[4] : register(u0);
|
||||
|
||||
[numthreads(1, 1, 1)]
|
||||
void main(int wg : SV_GroupID)
|
||||
{
|
||||
RWBuf[wg >> 2][wg & 3] = RWBuf[wg >> 2].IncrementCounter() + 64;
|
||||
}
|
||||
#endif
|
||||
static const DWORD cs_code_dxbc[] =
|
||||
{
|
||||
0x43425844, 0xb5433247, 0x4cd30f6c, 0x58100e67, 0xc179ade1, 0x00000001, 0x00000134, 0x00000003,
|
||||
0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
|
||||
0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x000000e0, 0x00050051, 0x00000038, 0x0100086a,
|
||||
0x0700009e, 0x0031ee46, 0x00000000, 0x00000000, 0x00000003, 0x00000004, 0x00000000, 0x0200005f,
|
||||
0x00021012, 0x02000068, 0x00000002, 0x0400009b, 0x00000001, 0x00000001, 0x00000001, 0x0600002a,
|
||||
0x00100012, 0x00000000, 0x0002100a, 0x00004001, 0x00000002, 0x06000001, 0x00100022, 0x00000000,
|
||||
0x0002100a, 0x00004001, 0x00000003, 0x070000b2, 0x00100012, 0x00000001, 0x0421e000, 0x00000000,
|
||||
0x0010000a, 0x00000000, 0x0700001e, 0x00100042, 0x00000000, 0x0010000a, 0x00000001, 0x00004001,
|
||||
0x00000040, 0x0b0000a8, 0x0421e012, 0x00000000, 0x0010000a, 0x00000000, 0x0010001a, 0x00000000,
|
||||
0x00004001, 0x00000000, 0x0010002a, 0x00000000, 0x0100003e,
|
||||
};
|
||||
|
||||
static const BYTE cs_code_dxil[] =
|
||||
{
|
||||
0x44, 0x58, 0x42, 0x43, 0xc6, 0xfe, 0xe1, 0x77, 0xd8, 0x5c, 0x56, 0xc7, 0x6e, 0xf7, 0xe2, 0xf7, 0xb3, 0xb0, 0x40, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x34, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
|
||||
0x38, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0xd0, 0x00, 0x00, 0x00, 0xec, 0x00, 0x00, 0x00, 0x53, 0x46, 0x49, 0x30, 0x08, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x53, 0x47, 0x31, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x4f, 0x53, 0x47, 0x31, 0x08, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x50, 0x53, 0x56, 0x30, 0x60, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x41, 0x53, 0x48, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0xc1, 0xf5, 0xe2,
|
||||
0x29, 0x0a, 0x7c, 0x68, 0x4a, 0xfa, 0x15, 0xe9, 0x1a, 0x85, 0x63, 0x21, 0x44, 0x58, 0x49, 0x4c, 0x40, 0x05, 0x00, 0x00, 0x60, 0x00, 0x05, 0x00, 0x50, 0x01, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4c,
|
||||
0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x28, 0x05, 0x00, 0x00, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0x47, 0x01, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||
0x13, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02,
|
||||
0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x52, 0x88, 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0xe4, 0x48, 0x0e, 0x90,
|
||||
0x91, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x29, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x1b, 0x8c, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07,
|
||||
0x40, 0x02, 0xa8, 0x0d, 0x84, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x20, 0x6d, 0x30, 0x86, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x09, 0xa8, 0x00, 0x49, 0x18, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
|
||||
0x13, 0x82, 0x60, 0x42, 0x20, 0x4c, 0x08, 0x06, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84,
|
||||
0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x54, 0x23, 0x00, 0x25, 0x00, 0x14, 0xe6, 0x08, 0xc0, 0xa0, 0x0c, 0x63, 0x0c, 0x22, 0x73,
|
||||
0x04, 0x08, 0x99, 0x7b, 0x86, 0xcb, 0x9f, 0xb0, 0x87, 0x90, 0xfc, 0x10, 0x68, 0x86, 0x85, 0x40, 0xc1, 0x29, 0xc4, 0x18, 0xc8, 0x50, 0x9a, 0x23, 0x08, 0x8a, 0x81, 0x86, 0x19, 0x63, 0x11, 0x2b,
|
||||
0x0a, 0x18, 0x68, 0x8c, 0x31, 0xc6, 0x30, 0xe4, 0x06, 0x02, 0x66, 0x32, 0x83, 0x71, 0x60, 0x87, 0x70, 0x98, 0x87, 0x79, 0x70, 0x03, 0x59, 0xb8, 0x85, 0x59, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x71,
|
||||
0xa0, 0x87, 0x7a, 0x90, 0x87, 0x72, 0x20, 0x07, 0x51, 0xa8, 0x07, 0x73, 0x30, 0x87, 0x72, 0x90, 0x07, 0x3e, 0xa8, 0x07, 0x77, 0x98, 0x87, 0x74, 0x38, 0x07, 0x77, 0x28, 0x07, 0x72, 0x00, 0x83,
|
||||
0x74, 0x70, 0x07, 0x7a, 0xf0, 0x03, 0x14, 0x8c, 0x24, 0x88, 0x24, 0xe7, 0x08, 0x40, 0x01, 0x00, 0x13, 0x14, 0x72, 0xc0, 0x87, 0x74, 0x60, 0x87, 0x36, 0x68, 0x87, 0x79, 0x68, 0x03, 0x72, 0xc0,
|
||||
0x87, 0x0d, 0xaf, 0x50, 0x0e, 0x6d, 0xd0, 0x0e, 0x7a, 0x50, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x73, 0x20, 0x07,
|
||||
0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90,
|
||||
0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6,
|
||||
0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x43, 0x9e, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x3c, 0x04, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x79, 0x12, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x18, 0xf2, 0x30, 0x40, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xe4, 0x71, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x0b, 0x04, 0x00, 0x00,
|
||||
0x09, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x10, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x1a, 0x25, 0x30, 0x02, 0x50, 0x0c, 0x85, 0x50, 0x18, 0xb4, 0x46, 0x00, 0x6a,
|
||||
0x80, 0x68, 0x81, 0xd0, 0x9c, 0x01, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x90, 0x46, 0x02, 0x13, 0x44, 0x35, 0x18, 0x63, 0x0b, 0x73, 0x3b, 0x03, 0xb1,
|
||||
0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x03, 0x99, 0x71, 0xb9, 0x01, 0x41, 0xa1, 0x0b, 0x3b, 0x9b, 0x7b, 0x91, 0x2a, 0x62, 0x2a, 0x0a, 0x9a, 0x2a, 0xfa, 0x9a, 0xb9, 0x81, 0x79, 0x31, 0x4b, 0x73,
|
||||
0x0b, 0x63, 0x4b, 0xd9, 0x10, 0x04, 0x13, 0x84, 0xa1, 0x98, 0x20, 0x0c, 0xc6, 0x06, 0x61, 0x20, 0x26, 0x08, 0xc3, 0xb1, 0x41, 0x18, 0x0c, 0x0a, 0x63, 0x73, 0x1b, 0x06, 0xc4, 0x20, 0x26, 0x08,
|
||||
0x53, 0x43, 0x60, 0x82, 0x30, 0x20, 0x13, 0x84, 0x21, 0x99, 0x20, 0x2c, 0xca, 0x04, 0x61, 0x59, 0x36, 0x08, 0x03, 0xb3, 0x61, 0x21, 0x94, 0x85, 0x20, 0x98, 0xc6, 0x79, 0x1c, 0x68, 0x43, 0x10,
|
||||
0x6d, 0x20, 0x00, 0x09, 0x00, 0x26, 0x08, 0x02, 0x40, 0xa2, 0x2d, 0x2c, 0xcd, 0x6d, 0x82, 0x40, 0x31, 0x1b, 0x86, 0x61, 0x18, 0x36, 0x10, 0x84, 0xc5, 0x5c, 0x1b, 0x0a, 0xaa, 0x02, 0x26, 0xac,
|
||||
0x0a, 0x1b, 0x9b, 0x5d, 0x9b, 0x4b, 0x1a, 0x59, 0x99, 0x1b, 0xdd, 0x94, 0x20, 0xa8, 0x42, 0x86, 0xe7, 0x62, 0x57, 0x26, 0x37, 0x97, 0xf6, 0xe6, 0x36, 0x25, 0x20, 0x9a, 0x90, 0xe1, 0xb9, 0xd8,
|
||||
0x85, 0xb1, 0xd9, 0x95, 0xc9, 0x4d, 0x09, 0x8c, 0x3a, 0x64, 0x78, 0x2e, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x53, 0x02, 0xa4, 0x0c, 0x19, 0x9e, 0x8b, 0x5c, 0xd9,
|
||||
0xdc, 0x5b, 0x9d, 0xdc, 0x58, 0xd9, 0xdc, 0x94, 0x40, 0xaa, 0x43, 0x86, 0xe7, 0x52, 0xe6, 0x46, 0x27, 0x97, 0x07, 0xf5, 0x96, 0xe6, 0x46, 0x37, 0x37, 0x25, 0xc0, 0x00, 0x79, 0x18, 0x00, 0x00,
|
||||
0x4c, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6,
|
||||
0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8,
|
||||
0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11,
|
||||
0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89,
|
||||
0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37,
|
||||
0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81,
|
||||
0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c,
|
||||
0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc,
|
||||
0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc4, 0x21, 0x07, 0x7c, 0x70, 0x03, 0x7a, 0x28, 0x87, 0x76, 0x80, 0x87, 0x19, 0xd1, 0x43, 0x0e, 0xf8, 0xe0, 0x06, 0xe4, 0x20,
|
||||
0x0e, 0xe7, 0xe0, 0x06, 0xf6, 0x10, 0x0e, 0xf2, 0xc0, 0x0e, 0xe1, 0x90, 0x0f, 0xef, 0x50, 0x0f, 0xf4, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x46, 0x50, 0x0d, 0x97,
|
||||
0xef, 0x3c, 0x7e, 0x40, 0x15, 0x05, 0x11, 0xb1, 0x93, 0x13, 0x11, 0x3e, 0x72, 0xdb, 0x26, 0x90, 0x0d, 0x97, 0xef, 0x3c, 0x7e, 0x40, 0x15, 0x05, 0x11, 0xb9, 0xcf, 0x00, 0x4c, 0x04, 0xe7, 0x50,
|
||||
0xcd, 0x44, 0x44, 0x36, 0x20, 0x0d, 0x97, 0xef, 0x3c, 0xbe, 0x10, 0x11, 0xc0, 0x44, 0x84, 0x40, 0x33, 0x2c, 0x84, 0x05, 0x44, 0xc3, 0xe5, 0x3b, 0x8f, 0x6f, 0x44, 0x0e, 0xf5, 0x88, 0x83, 0x8f,
|
||||
0xdc, 0xb6, 0x01, 0x10, 0x0c, 0x80, 0x34, 0x00, 0x61, 0x20, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x34, 0x66, 0x00, 0x8a,
|
||||
0x37, 0xa0, 0x08, 0x4a, 0xae, 0x18, 0x03, 0x0a, 0x30, 0xa0, 0x0c, 0x4a, 0x31, 0x80, 0x4c, 0x09, 0x00, 0x00, 0x00, 0x00, 0x23, 0x06, 0x06, 0x00, 0x82, 0x60, 0x40, 0x58, 0x48, 0x54, 0x01, 0x92,
|
||||
0x15, 0x4c, 0x30, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0xcc, 0x95, 0x10, 0x54, 0x00, 0x8d, 0x18, 0x1c, 0x00, 0x08, 0x82, 0x41, 0x92, 0x25, 0x41, 0x51, 0x41, 0x02, 0x65, 0x24, 0x3a, 0x62, 0xd0,
|
||||
0x00, 0x20, 0x08, 0x06, 0x8e, 0x96, 0x10, 0x01, 0x26, 0x40, 0x10, 0x84, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
static const D3D12_SHADER_BYTECODE cs_dxbc = SHADER_BYTECODE(cs_code_dxbc);
|
||||
static const D3D12_SHADER_BYTECODE cs_dxil = SHADER_BYTECODE(cs_code_dxil);
|
||||
|
||||
if (!init_compute_test_context(&context))
|
||||
return;
|
||||
|
||||
if (use_dxil && !context_supports_dxil(&context))
|
||||
{
|
||||
skip("Context does not support DXIL.\n");
|
||||
destroy_test_context(&context);
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&rs_desc, 0, sizeof(rs_desc));
|
||||
memset(&rs_param, 0, sizeof(rs_param));
|
||||
memset(&range, 0, sizeof(range));
|
||||
rs_desc.NumParameters = 1;
|
||||
rs_desc.pParameters = &rs_param;
|
||||
rs_param.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
|
||||
rs_param.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
|
||||
rs_param.DescriptorTable.NumDescriptorRanges = 1;
|
||||
rs_param.DescriptorTable.pDescriptorRanges = ⦥
|
||||
range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV;
|
||||
range.NumDescriptors = 8;
|
||||
create_root_signature(context.device, &rs_desc, &context.root_signature);
|
||||
context.pipeline_state = create_compute_pipeline_state(context.device, context.root_signature, use_dxil ? cs_dxil : cs_dxbc);
|
||||
|
||||
cpu_heap = create_cpu_descriptor_heap(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 8);
|
||||
heap = create_gpu_descriptor_heap(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 8);
|
||||
resource = create_default_buffer(context.device, D3D12_UAV_COUNTER_PLACEMENT_ALIGNMENT * 9,
|
||||
D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
|
||||
|
||||
memset(&uav_desc, 0, sizeof(uav_desc));
|
||||
uav_desc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE cpu_h, gpu_h;
|
||||
cpu_h = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(cpu_heap);
|
||||
gpu_h = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap);
|
||||
cpu_h.ptr += ID3D12Device_GetDescriptorHandleIncrementSize(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV) * i;
|
||||
gpu_h.ptr += ID3D12Device_GetDescriptorHandleIncrementSize(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV) * i;
|
||||
|
||||
uav_desc.Buffer.NumElements = 4;
|
||||
uav_desc.Buffer.FirstElement = 4 * i;
|
||||
uav_desc.Buffer.StructureByteStride = 4;
|
||||
uav_desc.Buffer.CounterOffsetInBytes = D3D12_UAV_COUNTER_PLACEMENT_ALIGNMENT * (i + 1);
|
||||
|
||||
/* AMD drivers don't seem to clear the UAV counter if we pass in NULL, so
|
||||
* test a path which does not do that. */
|
||||
if (i < 4)
|
||||
{
|
||||
ID3D12Device_CreateUnorderedAccessView(context.device, resource, resource, &uav_desc, cpu_h);
|
||||
ID3D12Device_CreateUnorderedAccessView(context.device, resource, resource, &uav_desc, gpu_h);
|
||||
}
|
||||
|
||||
uav_desc.Buffer.CounterOffsetInBytes = 0;
|
||||
|
||||
/* Test writing NULL UAV counter after a non-NULL UAV counter. Makes sure that we are indeed supposed
|
||||
* to clear out UAV counters to NULL every time. */
|
||||
if ((i & 3) == 3)
|
||||
{
|
||||
ID3D12Device_CreateUnorderedAccessView(context.device, NULL, NULL, &uav_desc, cpu_h);
|
||||
ID3D12Device_CreateUnorderedAccessView(context.device, NULL, NULL, &uav_desc, gpu_h);
|
||||
}
|
||||
else if ((i & 3) >= 1)
|
||||
{
|
||||
ID3D12Device_CreateUnorderedAccessView(context.device, resource, NULL, &uav_desc, cpu_h);
|
||||
ID3D12Device_CreateUnorderedAccessView(context.device, resource, NULL, &uav_desc, gpu_h);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Test copy behavior. Make sure we correctly copy NULL counters as well. */
|
||||
ID3D12Device_CreateUnorderedAccessView(context.device, resource, NULL, &uav_desc, cpu_h);
|
||||
ID3D12Device_CopyDescriptorsSimple(context.device, 1,
|
||||
gpu_h, cpu_h, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
|
||||
}
|
||||
}
|
||||
|
||||
ID3D12GraphicsCommandList_SetDescriptorHeaps(context.list, 1, &heap);
|
||||
ID3D12GraphicsCommandList_SetComputeRootSignature(context.list, context.root_signature);
|
||||
ID3D12GraphicsCommandList_SetPipelineState(context.list, context.pipeline_state);
|
||||
ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(context.list, 0,
|
||||
ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heap));
|
||||
ID3D12GraphicsCommandList_Dispatch(context.list, 8 * 4, 1, 1);
|
||||
transition_resource_state(context.list, resource, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
|
||||
get_buffer_readback_with_command_list(resource, DXGI_FORMAT_R32_UINT, &rb, context.queue, context.list);
|
||||
|
||||
for (i = 0; i < 8 * 4; i++)
|
||||
{
|
||||
/* Possible behavior is very varied here:
|
||||
* NV: If UAV counter is NULL, NV makes the main descriptor robust.
|
||||
* AMD: Writing NULL uav counter does not update the counter descriptor, the atomic update will still go through.
|
||||
* Intel: Behaves as you would expect. Atomic op returns 0, writes to main descriptor behaves as you'd expect. */
|
||||
uint32_t value = get_readback_uint(&rb, i, 0, 0);
|
||||
ok(value == 0 || (value >= 64 && value < (64 + 4)), "Unexpected value %u = %u\n", i, value);
|
||||
}
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
uint32_t value = get_readback_uint(&rb, (i + 1) * (D3D12_UAV_COUNTER_PLACEMENT_ALIGNMENT / 4), 0, 0);
|
||||
if (i < 4)
|
||||
{
|
||||
/* AMD behavior: Passing NULL does not necessarily clear out UAV counter.
|
||||
* It is undefined to access UAV counter like this.
|
||||
* https://docs.microsoft.com/en-us/windows/win32/direct3d12/uav-counters
|
||||
* "If a shader attempts to access the counter of a UAV that does not have an associated counter,
|
||||
* then the debug layer will issue a warning,
|
||||
* and a GPU page fault will occur causing the apps’s device to be removed." */
|
||||
ok(value == 0 || value == 4, "Unexpected counter %u = %u.\n", i, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Technically undefined, but all drivers behave robustly here, we should too. */
|
||||
ok(value == 0, "Unexpected counter %u = %u.\n", i, value);
|
||||
}
|
||||
}
|
||||
|
||||
release_resource_readback(&rb);
|
||||
ID3D12DescriptorHeap_Release(heap);
|
||||
ID3D12DescriptorHeap_Release(cpu_heap);
|
||||
ID3D12Resource_Release(resource);
|
||||
destroy_test_context(&context);
|
||||
}
|
||||
|
||||
void test_uav_counter_null_behavior_dxbc(void)
|
||||
{
|
||||
test_uav_counters_null_behavior(false);
|
||||
}
|
||||
|
||||
void test_uav_counter_null_behavior_dxil(void)
|
||||
{
|
||||
test_uav_counters_null_behavior(true);
|
||||
}
|
||||
|
|
|
@ -1074,10 +1074,10 @@ void test_reset_command_allocator(void)
|
|||
command_allocator, NULL, &IID_ID3D12GraphicsCommandList, (void **)&command_list2);
|
||||
ok(hr == S_OK, "Failed to create command list, hr %#x.\n", hr);
|
||||
|
||||
ID3D12CommandAllocator_Release(command_allocator);
|
||||
ID3D12CommandAllocator_Release(command_allocator2);
|
||||
ID3D12GraphicsCommandList_Release(command_list);
|
||||
ID3D12GraphicsCommandList_Release(command_list2);
|
||||
ID3D12CommandAllocator_Release(command_allocator);
|
||||
ID3D12CommandAllocator_Release(command_allocator2);
|
||||
}
|
||||
|
||||
refcount = ID3D12Device_Release(device);
|
||||
|
|
|
@ -1633,10 +1633,35 @@ static void test_dual_source_blending(bool use_dxil)
|
|||
0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0x49, 0x19, 0x48, 0x60, 0xf0, 0x3d, 0xc2, 0x88, 0x41, 0x02, 0x80, 0x20, 0x18, 0x24, 0x65, 0x20, 0x81, 0xc1, 0xd7, 0x04, 0x18, 0x0e, 0x04, 0x00, 0x05, 0x00,
|
||||
0x00, 0x00, 0xc5, 0x01, 0x91, 0x8e, 0xec, 0xb7, 0x38, 0xcc, 0x9e, 0x7f, 0xc7, 0xe2, 0xba, 0xd9, 0x5c, 0x96, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
static const DWORD ps_code_3rt_dxbc[] =
|
||||
{
|
||||
#if 0
|
||||
float4 c0;
|
||||
float4 c1;
|
||||
|
||||
void main(out float4 o0 : SV_Target0, out float4 o1 : SV_Target1, out float4 o2 : SV_Target2)
|
||||
{
|
||||
o0 = c0;
|
||||
o1 = c1;
|
||||
o2 = 1.0.xxxx;
|
||||
}
|
||||
#endif
|
||||
0x43425844, 0xe1e2c26b, 0x10d9607c, 0x4a0f0786, 0xc368f603, 0x00000001, 0x0000013c, 0x00000003,
|
||||
0x0000002c, 0x0000003c, 0x000000a0, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
|
||||
0x0000005c, 0x00000003, 0x00000008, 0x00000050, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
|
||||
0x0000000f, 0x00000050, 0x00000001, 0x00000000, 0x00000003, 0x00000001, 0x0000000f, 0x00000050,
|
||||
0x00000002, 0x00000000, 0x00000003, 0x00000002, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074,
|
||||
0x58454853, 0x00000094, 0x00000050, 0x00000025, 0x0100086a, 0x04000059, 0x00208e46, 0x00000000,
|
||||
0x00000002, 0x03000065, 0x001020f2, 0x00000000, 0x03000065, 0x001020f2, 0x00000001, 0x03000065,
|
||||
0x001020f2, 0x00000002, 0x06000036, 0x001020f2, 0x00000000, 0x00208e46, 0x00000000, 0x00000000,
|
||||
0x06000036, 0x001020f2, 0x00000001, 0x00208e46, 0x00000000, 0x00000001, 0x08000036, 0x001020f2,
|
||||
0x00000002, 0x00004002, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x0100003e,
|
||||
};
|
||||
const D3D12_SHADER_BYTECODE ps = {
|
||||
use_dxil ? (const void*)ps_code_dxil : (const void*)ps_code_dxbc,
|
||||
use_dxil ? sizeof(ps_code_dxil) : sizeof(ps_code_dxbc)
|
||||
};
|
||||
static const D3D12_SHADER_BYTECODE ps_3rt = SHADER_BYTECODE(ps_code_3rt_dxbc);
|
||||
static const struct
|
||||
{
|
||||
struct
|
||||
|
@ -1681,6 +1706,7 @@ static void test_dual_source_blending(bool use_dxil)
|
|||
init_pipeline_state_desc(&pso_desc, context.root_signature,
|
||||
context.render_target_desc.Format, NULL, &ps, NULL);
|
||||
}
|
||||
|
||||
pso_desc.BlendState.RenderTarget[0].BlendEnable = true;
|
||||
pso_desc.BlendState.RenderTarget[0].SrcBlend = D3D12_BLEND_SRC_COLOR;
|
||||
pso_desc.BlendState.RenderTarget[0].DestBlend = D3D12_BLEND_SRC1_COLOR;
|
||||
|
@ -1688,6 +1714,54 @@ static void test_dual_source_blending(bool use_dxil)
|
|||
pso_desc.BlendState.RenderTarget[0].SrcBlendAlpha = D3D12_BLEND_SRC_ALPHA;
|
||||
pso_desc.BlendState.RenderTarget[0].DestBlendAlpha = D3D12_BLEND_SRC1_ALPHA;
|
||||
pso_desc.BlendState.RenderTarget[0].BlendOpAlpha = D3D12_BLEND_OP_ADD;
|
||||
|
||||
pso_desc.NumRenderTargets = 2;
|
||||
pso_desc.RTVFormats[1] = pso_desc.RTVFormats[0];
|
||||
hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
|
||||
&IID_ID3D12PipelineState, (void **)&context.pipeline_state);
|
||||
ok(hr == E_INVALIDARG, "Unexpected result, hr %#x.\n", hr);
|
||||
|
||||
/* Write mask of 0 is not enough. */
|
||||
pso_desc.BlendState.IndependentBlendEnable = TRUE;
|
||||
pso_desc.BlendState.RenderTarget[1].RenderTargetWriteMask = 0;
|
||||
hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
|
||||
&IID_ID3D12PipelineState, (void**)&context.pipeline_state);
|
||||
ok(hr == E_INVALIDARG, "Unexpected result, hr %#x.\n", hr);
|
||||
|
||||
/* This appears to be allowed however. */
|
||||
pso_desc.RTVFormats[1] = DXGI_FORMAT_UNKNOWN;
|
||||
pso_desc.BlendState.IndependentBlendEnable = FALSE;
|
||||
hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
|
||||
&IID_ID3D12PipelineState, (void**)&context.pipeline_state);
|
||||
ok(hr == S_OK, "Failed to create pipeline, hr %#x.\n", hr);
|
||||
ID3D12PipelineState_Release(context.pipeline_state);
|
||||
|
||||
/* >2 RTs is also allowed as long as we keep using NULL format. */
|
||||
pso_desc.NumRenderTargets = 3;
|
||||
hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
|
||||
&IID_ID3D12PipelineState, (void**)&context.pipeline_state);
|
||||
ok(hr == S_OK, "Failed to create pipeline, hr %#x.\n", hr);
|
||||
ID3D12PipelineState_Release(context.pipeline_state);
|
||||
|
||||
/* This is still allowed. We need to only consider RTs with IOSIG entry apparently ... */
|
||||
pso_desc.RTVFormats[2] = pso_desc.RTVFormats[0];
|
||||
hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
|
||||
&IID_ID3D12PipelineState, (void**)&context.pipeline_state);
|
||||
ok(hr == S_OK, "Failed to create pipeline, hr %#x.\n", hr);
|
||||
ID3D12PipelineState_Release(context.pipeline_state);
|
||||
|
||||
if (!use_dxil)
|
||||
{
|
||||
/* If we try to write to o2 however, this must fail. */
|
||||
pso_desc.PS = ps_3rt;
|
||||
hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
|
||||
&IID_ID3D12PipelineState, (void**)&context.pipeline_state);
|
||||
ok(hr == E_INVALIDARG, "Unexpected result, hr %#x.\n", hr);
|
||||
pso_desc.PS = ps;
|
||||
}
|
||||
|
||||
pso_desc.NumRenderTargets = 1;
|
||||
pso_desc.RTVFormats[2] = DXGI_FORMAT_UNKNOWN;
|
||||
hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
|
||||
&IID_ID3D12PipelineState, (void **)&context.pipeline_state);
|
||||
ok(hr == S_OK, "Failed to create pipeline, hr %#x.\n", hr);
|
||||
|
@ -1727,7 +1801,7 @@ static void test_dual_source_blending(bool use_dxil)
|
|||
pso_desc.BlendState.RenderTarget[1] = pso_desc.BlendState.RenderTarget[0];
|
||||
hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
|
||||
&IID_ID3D12PipelineState, (void **)&context.pipeline_state);
|
||||
todo ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
|
||||
ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
|
||||
if (SUCCEEDED(hr))
|
||||
ID3D12PipelineState_Release(context.pipeline_state);
|
||||
context.pipeline_state = NULL;
|
||||
|
@ -1736,7 +1810,7 @@ static void test_dual_source_blending(bool use_dxil)
|
|||
pso_desc.BlendState.RenderTarget[1].DestBlend = D3D12_BLEND_SRC_COLOR;
|
||||
hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
|
||||
&IID_ID3D12PipelineState, (void **)&context.pipeline_state);
|
||||
todo ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
|
||||
ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
|
||||
if (SUCCEEDED(hr))
|
||||
ID3D12PipelineState_Release(context.pipeline_state);
|
||||
context.pipeline_state = NULL;
|
||||
|
@ -1753,7 +1827,7 @@ static void test_dual_source_blending(bool use_dxil)
|
|||
pso_desc.BlendState.RenderTarget[0].BlendOpAlpha = D3D12_BLEND_OP_ADD;
|
||||
hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
|
||||
&IID_ID3D12PipelineState, (void **)&context.pipeline_state);
|
||||
todo ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
|
||||
ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
|
||||
if (SUCCEEDED(hr))
|
||||
ID3D12PipelineState_Release(context.pipeline_state);
|
||||
context.pipeline_state = NULL;
|
||||
|
@ -2227,3 +2301,119 @@ void test_mismatching_pso_stages(void)
|
|||
destroy_test_context(&context);
|
||||
}
|
||||
|
||||
void test_pipeline_no_ps_nonzero_rts(void)
|
||||
{
|
||||
const FLOAT white[] = { 100.0f, 100.0f, 100.0f, 100.0f };
|
||||
D3D12_GRAPHICS_PIPELINE_STATE_DESC pso;
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE rtv_handle;
|
||||
D3D12_ROOT_SIGNATURE_DESC rs_desc;
|
||||
struct depth_stencil_resource ds;
|
||||
D3D12_INPUT_LAYOUT_DESC layout;
|
||||
D3D12_INPUT_ELEMENT_DESC elem;
|
||||
struct test_context_desc desc;
|
||||
D3D12_VERTEX_BUFFER_VIEW vbv;
|
||||
struct test_context context;
|
||||
ID3D12DescriptorHeap *rtv;
|
||||
ID3D12Resource *vbo;
|
||||
ID3D12Resource *rt;
|
||||
D3D12_VIEWPORT vp;
|
||||
D3D12_RECT sci;
|
||||
|
||||
static const FLOAT vbo_data[] =
|
||||
{
|
||||
-1.0f, -1.0f, 0.5f, 1.0f,
|
||||
+3.0f, -1.0f, 0.5f, 1.0f,
|
||||
-1.0f, +3.0f, 0.5f, 1.0f,
|
||||
};
|
||||
|
||||
static const DWORD vs_code[] =
|
||||
{
|
||||
#if 0
|
||||
float4 main(float4 a : A) : SV_Position
|
||||
{
|
||||
return a;
|
||||
}
|
||||
#endif
|
||||
0x43425844, 0xecd820c8, 0x89ee4b40, 0xb73efa73, 0x4ed91573, 0x00000001, 0x000000d4, 0x00000003,
|
||||
0x0000002c, 0x00000058, 0x0000008c, 0x4e475349, 0x00000024, 0x00000001, 0x00000008, 0x00000020,
|
||||
0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0xabab0041, 0x4e47534f, 0x0000002c,
|
||||
0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f,
|
||||
0x505f5653, 0x7469736f, 0x006e6f69, 0x58454853, 0x00000040, 0x00010050, 0x00000010, 0x0100086a,
|
||||
0x0300005f, 0x001010f2, 0x00000000, 0x04000067, 0x001020f2, 0x00000000, 0x00000001, 0x05000036,
|
||||
0x001020f2, 0x00000000, 0x00101e46, 0x00000000, 0x0100003e,
|
||||
};
|
||||
static const D3D12_SHADER_BYTECODE vs = SHADER_BYTECODE(vs_code);
|
||||
|
||||
layout.NumElements = 1;
|
||||
layout.pInputElementDescs = &elem;
|
||||
memset(&elem, 0, sizeof(elem));
|
||||
elem.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
|
||||
elem.InputSlotClass = D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA;
|
||||
elem.SemanticName = "A";
|
||||
|
||||
memset(&desc, 0, sizeof(desc));
|
||||
desc.no_pipeline = true;
|
||||
desc.no_root_signature = true;
|
||||
desc.no_render_target = true;
|
||||
|
||||
if (!init_test_context(&context, &desc))
|
||||
return;
|
||||
|
||||
init_depth_stencil(&ds, context.device, 1, 1, 1, 1, DXGI_FORMAT_D32_FLOAT, DXGI_FORMAT_D32_FLOAT, NULL);
|
||||
rt = create_default_texture2d(context.device, 1, 1, 1, 1, DXGI_FORMAT_R32_FLOAT,
|
||||
D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET,
|
||||
D3D12_RESOURCE_STATE_RENDER_TARGET);
|
||||
|
||||
rtv = create_cpu_descriptor_heap(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_RTV, 1);
|
||||
|
||||
memset(&rs_desc, 0, sizeof(rs_desc));
|
||||
rs_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT;
|
||||
create_root_signature(context.device, &rs_desc, &context.root_signature);
|
||||
|
||||
init_pipeline_state_desc(&pso, context.root_signature, DXGI_FORMAT_R8G8B8A8_UNORM, &vs, NULL, &layout);
|
||||
pso.DSVFormat = DXGI_FORMAT_D32_FLOAT;
|
||||
pso.DepthStencilState.DepthEnable = TRUE;
|
||||
pso.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL;
|
||||
pso.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_LESS;
|
||||
pso.RasterizerState.CullMode = D3D12_CULL_MODE_NONE;
|
||||
pso.PS.BytecodeLength = 0;
|
||||
pso.PS.pShaderBytecode = NULL;
|
||||
|
||||
rtv_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(rtv);
|
||||
|
||||
ID3D12Device_CreateGraphicsPipelineState(context.device, &pso, &IID_ID3D12PipelineState, (void**)&context.pipeline_state);
|
||||
ID3D12Device_CreateRenderTargetView(context.device, rt, NULL, rtv_handle);
|
||||
ID3D12GraphicsCommandList_ClearRenderTargetView(context.list, rtv_handle, white, 0, NULL);
|
||||
ID3D12GraphicsCommandList_ClearDepthStencilView(context.list, ds.dsv_handle, D3D12_CLEAR_FLAG_DEPTH, 1.0f, 0, 0, NULL);
|
||||
|
||||
ID3D12GraphicsCommandList_SetGraphicsRootSignature(context.list, context.root_signature);
|
||||
ID3D12GraphicsCommandList_SetPipelineState(context.list, context.pipeline_state);
|
||||
set_viewport(&vp, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f);
|
||||
ID3D12GraphicsCommandList_RSSetViewports(context.list, 1, &vp);
|
||||
set_rect(&sci, 0, 0, 1, 1);
|
||||
ID3D12GraphicsCommandList_RSSetScissorRects(context.list, 1, &sci);
|
||||
ID3D12GraphicsCommandList_OMSetRenderTargets(context.list, 1, &rtv_handle, TRUE, &ds.dsv_handle);
|
||||
ID3D12GraphicsCommandList_IASetPrimitiveTopology(context.list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
|
||||
vbo = create_upload_buffer(context.device, sizeof(vbo_data), vbo_data);
|
||||
vbv.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(vbo);
|
||||
vbv.SizeInBytes = sizeof(vbo_data);
|
||||
vbv.StrideInBytes = 16;
|
||||
ID3D12GraphicsCommandList_IASetVertexBuffers(context.list, 0, 1, &vbv);
|
||||
ID3D12GraphicsCommandList_DrawInstanced(context.list, 3, 1, 0, 0);
|
||||
|
||||
transition_resource_state(context.list, rt, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
|
||||
transition_resource_state(context.list, ds.texture, D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_COPY_SOURCE);
|
||||
|
||||
/* Verify depth buffer was written to. */
|
||||
check_sub_resource_float(ds.texture, 0, context.queue, context.list, 0.5f, 0);
|
||||
reset_command_list(context.list, context.allocator);
|
||||
/* Verify that the invalid R32_FLOAT RTV was just ignored. */
|
||||
check_sub_resource_float(rt, 0, context.queue, context.list, 100.0f, 0);
|
||||
|
||||
ID3D12Resource_Release(rt);
|
||||
ID3D12Resource_Release(vbo);
|
||||
ID3D12DescriptorHeap_Release(rtv);
|
||||
destroy_depth_stencil(&ds);
|
||||
destroy_test_context(&context);
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -24,8 +24,8 @@
|
|||
|
||||
void test_unbound_rtv_rendering(void)
|
||||
{
|
||||
static const struct vec4 white = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
static const struct vec4 red = { 1.0f, 0.0f, 0.0f, 1.0f };
|
||||
static const float white[] = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
|
||||
ID3D12GraphicsCommandList *command_list;
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE rt_handle;
|
||||
|
@ -91,8 +91,8 @@ void test_unbound_rtv_rendering(void)
|
|||
&IID_ID3D12PipelineState, (void **)&context.pipeline_state);
|
||||
ok(hr == S_OK, "Failed to create state, hr %#x.\n", hr);
|
||||
|
||||
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, &white.x, 0, NULL);
|
||||
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, rt_handle, &white.x, 0, NULL);
|
||||
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
|
||||
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, rt_handle, white, 0, NULL);
|
||||
ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
|
||||
ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
|
||||
ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
|
@ -120,7 +120,8 @@ void test_unbound_rtv_rendering(void)
|
|||
|
||||
void test_unknown_rtv_format(void)
|
||||
{
|
||||
static const struct vec4 white = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||
static const struct vec4 vec4_white = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||
static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||
struct vec4 expected_vec4 = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
|
||||
ID3D12GraphicsCommandList *command_list;
|
||||
|
@ -185,7 +186,7 @@ void test_unknown_rtv_format(void)
|
|||
create_render_target(&context, &desc, &render_targets[1], &rtvs[2]);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(rtvs); ++i)
|
||||
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, rtvs[i], &white.x, 0, NULL);
|
||||
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, rtvs[i], white, 0, NULL);
|
||||
|
||||
/* NULL RTV */
|
||||
memset(&rtv_desc, 0, sizeof(rtv_desc));
|
||||
|
@ -212,7 +213,7 @@ void test_unknown_rtv_format(void)
|
|||
transition_resource_state(command_list, render_targets[1],
|
||||
D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
|
||||
|
||||
check_sub_resource_vec4(context.render_target, 0, queue, command_list, &white, 0);
|
||||
check_sub_resource_vec4(context.render_target, 0, queue, command_list, &vec4_white, 0);
|
||||
reset_command_list(command_list, context.allocator);
|
||||
expected_vec4.x = 2.0f;
|
||||
check_sub_resource_vec4(render_targets[0], 0, queue, command_list, &expected_vec4, 0);
|
||||
|
|
|
@ -2638,7 +2638,8 @@ void test_stress_suballocation_thread(void *userdata)
|
|||
{
|
||||
/* Randomly allocate heaps and place a buffer on top of it. */
|
||||
alloc_heap = rand_r(&seed) % 2 == 0;
|
||||
alloc_size = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT * (1 + rand_r(&seed) % 20);
|
||||
/* Ensures we sometimes hit dedicated allocation paths. (2 MiB limit). */
|
||||
alloc_size = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT * (1 + rand_r(&seed) % 40);
|
||||
keep_alive = rand_r(&seed) % 2 == 0;
|
||||
|
||||
if (buffers[i] && keep_alive)
|
||||
|
|
|
@ -1467,3 +1467,36 @@ void test_missing_bindings_root_signature(void)
|
|||
destroy_test_context(&context);
|
||||
}
|
||||
|
||||
void test_root_signature_empty_blob(void)
|
||||
{
|
||||
ID3D12RootSignature *root_signature;
|
||||
struct test_context context;
|
||||
HRESULT hr;
|
||||
|
||||
static const DWORD cs_code[] =
|
||||
{
|
||||
#if 0
|
||||
RWStructuredBuffer<uint> RWBuf;
|
||||
|
||||
[numthreads(1, 1, 1)]
|
||||
void main(int wg : SV_GroupID)
|
||||
{
|
||||
RWBuf[wg] = wg;
|
||||
}
|
||||
#endif
|
||||
0x43425844, 0x81a88c98, 0x1ab24abd, 0xfdb8fb1f, 0x7e9cb035, 0x00000001, 0x000000a8, 0x00000003,
|
||||
0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
|
||||
0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x00000054, 0x00050050, 0x00000015, 0x0100086a,
|
||||
0x0400009e, 0x0011e000, 0x00000000, 0x00000004, 0x0200005f, 0x00021012, 0x0400009b, 0x00000001,
|
||||
0x00000001, 0x00000001, 0x070000a8, 0x0011e012, 0x00000000, 0x0002100a, 0x00004001, 0x00000000,
|
||||
0x0002100a, 0x0100003e,
|
||||
};
|
||||
|
||||
if (!init_compute_test_context(&context))
|
||||
return;
|
||||
|
||||
hr = ID3D12Device_CreateRootSignature(context.device, 0, cs_code, sizeof(cs_code), &IID_ID3D12RootSignature, (void **)&root_signature);
|
||||
/* Has to be E_FAIL, not E_INVALIDARG, oddly enough. */
|
||||
ok(hr == E_FAIL, "Unexpected hr #%x.\n", hr);
|
||||
destroy_test_context(&context);
|
||||
}
|
||||
|
|
|
@ -5134,7 +5134,7 @@ void test_gather(void)
|
|||
{0.3f, 1.3f, 1.2f, 0.2f}, {1.3f, 2.3f, 2.2f, 1.2f}, {2.3f, 3.3f, 3.2f, 2.2f}, {3.3f, 3.3f, 3.2f, 3.2f},
|
||||
{0.3f, 1.3f, 1.3f, 0.3f}, {1.3f, 2.3f, 2.3f, 1.3f}, {2.3f, 3.3f, 3.3f, 2.3f}, {3.3f, 3.3f, 3.3f, 3.3f},
|
||||
};
|
||||
static const struct vec4 white = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||
static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||
static const D3D12_SUBRESOURCE_DATA resource_data = {&texture_data, sizeof(texture_data) / 4};
|
||||
|
||||
memset(&desc, 0, sizeof(desc));
|
||||
|
@ -5171,7 +5171,7 @@ void test_gather(void)
|
|||
context.pipeline_state = create_pipeline_state(context.device,
|
||||
context.root_signature, desc.rt_format, NULL, &ps_gather4, NULL);
|
||||
|
||||
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, &white.x, 0, NULL);
|
||||
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
|
||||
|
||||
ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
|
||||
ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
|
||||
|
@ -5209,7 +5209,7 @@ void test_gather(void)
|
|||
context.pipeline_state = create_pipeline_state(context.device,
|
||||
context.root_signature, desc.rt_format, NULL, &ps_gather4_offset, NULL);
|
||||
|
||||
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, &white.x, 0, NULL);
|
||||
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
|
||||
|
||||
ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
|
||||
ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
|
||||
|
@ -5247,7 +5247,7 @@ void test_gather(void)
|
|||
context.pipeline_state = create_pipeline_state(context.device,
|
||||
context.root_signature, desc.rt_format, NULL, &ps_gather4_green, NULL);
|
||||
|
||||
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, &white.x, 0, NULL);
|
||||
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
|
||||
|
||||
ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
|
||||
ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
|
||||
|
@ -5285,7 +5285,7 @@ void test_gather(void)
|
|||
context.pipeline_state = create_pipeline_state(context.device,
|
||||
context.root_signature, desc.rt_format, NULL, &ps_gather4_po, NULL);
|
||||
|
||||
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, &white.x, 0, NULL);
|
||||
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
|
||||
|
||||
ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
|
||||
ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
|
||||
|
@ -5321,7 +5321,7 @@ void test_gather(void)
|
|||
constants.offset_x = 0;
|
||||
constants.offset_y = 0;
|
||||
|
||||
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, &white.x, 0, NULL);
|
||||
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
|
||||
|
||||
ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
|
||||
ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
|
||||
|
@ -5455,7 +5455,7 @@ void test_gather_c(void)
|
|||
{0.0f, 0.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 1.0f, 0.0f}, {1.0f, 1.0f, 1.0f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f},
|
||||
{0.0f, 0.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 1.0f, 0.0f}, {1.0f, 1.0f, 1.0f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f},
|
||||
};
|
||||
static const struct vec4 white = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||
static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||
static const D3D12_SUBRESOURCE_DATA resource_data = {&texture_data, sizeof(texture_data) / 4};
|
||||
static const D3D12_STATIC_SAMPLER_DESC sampler_desc =
|
||||
{
|
||||
|
@ -5511,7 +5511,7 @@ void test_gather_c(void)
|
|||
context.pipeline_state = create_pipeline_state(context.device,
|
||||
context.root_signature, desc.rt_format, NULL, &ps_gather4_c, NULL);
|
||||
|
||||
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, &white.x, 0, NULL);
|
||||
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
|
||||
|
||||
ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
|
||||
ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
|
||||
|
@ -5549,7 +5549,7 @@ void test_gather_c(void)
|
|||
context.pipeline_state = create_pipeline_state(context.device,
|
||||
context.root_signature, desc.rt_format, NULL, &ps_gather4_po_c, NULL);
|
||||
|
||||
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, &white.x, 0, NULL);
|
||||
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
|
||||
|
||||
ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
|
||||
ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
|
||||
|
@ -5585,7 +5585,7 @@ void test_gather_c(void)
|
|||
constants.offset_x = 0;
|
||||
constants.offset_y = 0;
|
||||
|
||||
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, &white.x, 0, NULL);
|
||||
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
|
||||
|
||||
ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
|
||||
ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
|
||||
|
@ -6281,7 +6281,7 @@ void test_multisample_array_texture(void)
|
|||
};
|
||||
static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
|
||||
static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||
static const struct vec4 colors[] =
|
||||
static const float colors[][4] =
|
||||
{
|
||||
{1.0f, 0.0f, 0.0f, 1.0f},
|
||||
{0.0f, 1.0f, 0.0f, 1.0f},
|
||||
|
@ -6386,8 +6386,7 @@ void test_multisample_array_texture(void)
|
|||
rtv_desc.Texture2DMSArray.FirstArraySlice = i;
|
||||
rtv_desc.Texture2DMSArray.ArraySize = 1;
|
||||
ID3D12Device_CreateRenderTargetView(device, texture, &rtv_desc, cpu_handle);
|
||||
|
||||
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, cpu_handle, &colors[i].x, 0, NULL);
|
||||
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, cpu_handle, colors[i], 0, NULL);
|
||||
}
|
||||
|
||||
transition_resource_state(command_list, texture,
|
||||
|
|
|
@ -2131,8 +2131,8 @@ void test_sv_barycentric(void)
|
|||
#define BARY_RES 128
|
||||
|
||||
static const D3D12_VIEWPORT vp = { 0, 0, BARY_RES, BARY_RES, 0, 1 };
|
||||
static const float white[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
static const D3D12_RECT sci = { 0, 0, BARY_RES, BARY_RES };
|
||||
static const float white[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
static const uint8_t provoking_lut[] = {
|
||||
192, 212, 224, 244,
|
||||
128, 144, 160, 176,
|
||||
|
@ -4215,6 +4215,290 @@ void test_shader_sm64_packed(void)
|
|||
destroy_test_context(&context);
|
||||
}
|
||||
|
||||
void test_shader_waveop_maximal_convergence(void)
|
||||
{
|
||||
D3D12_ROOT_PARAMETER root_parameters[2];
|
||||
ID3D12PipelineState *pso_nonconverged;
|
||||
ID3D12PipelineState *pso_converged;
|
||||
D3D12_ROOT_SIGNATURE_DESC rs_desc;
|
||||
struct test_context context;
|
||||
struct resource_readback rb;
|
||||
ID3D12Resource *outputs;
|
||||
ID3D12Resource *inputs;
|
||||
unsigned int i;
|
||||
|
||||
static const uint32_t inputs_data[] =
|
||||
{
|
||||
2, 3, 1, 3,
|
||||
2, 0, 0, 1,
|
||||
0, 1, 3, 2,
|
||||
2, 1, 2, 2,
|
||||
};
|
||||
|
||||
static const uint32_t reference_converged[] =
|
||||
{
|
||||
25, 25, 25, 25,
|
||||
25, 25, 25, 25,
|
||||
25, 25, 25, 25,
|
||||
25, 25, 25, 25,
|
||||
};
|
||||
|
||||
static const uint32_t reference_nonconverged[] =
|
||||
{
|
||||
12, 9, 4, 9,
|
||||
12, 0, 0, 4,
|
||||
0, 4, 9, 12,
|
||||
12, 4, 12, 12,
|
||||
};
|
||||
|
||||
#if 0
|
||||
StructuredBuffer<uint> RO : register(t0);
|
||||
RWStructuredBuffer<uint> RW : register(u0);
|
||||
|
||||
[numthreads(16, 1, 1)]
|
||||
void main(uint thr : SV_DispatchThreadID)
|
||||
{
|
||||
uint v = RO[thr];
|
||||
uint result;
|
||||
while (true)
|
||||
{
|
||||
uint first = WaveReadLaneFirst(v);
|
||||
if (v == first)
|
||||
{
|
||||
result = WaveActiveSum(v);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
RW[thr] = result;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Compiled with Version: dxcompiler.dll: 1.5 - 1.4.1907.0; dxil.dll: 1.4(10.0.18362.1) */
|
||||
static const BYTE reconvergence_dxil[] =
|
||||
{
|
||||
0x44, 0x58, 0x42, 0x43, 0x27, 0x94, 0xf5, 0xbd, 0x53, 0x66, 0x70, 0xdb, 0xe2, 0x95, 0x5c, 0x8c, 0xdc, 0x10, 0x0b, 0xdf, 0x01, 0x00, 0x00, 0x00, 0xe4, 0x06, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
|
||||
0x34, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0x53, 0x46, 0x49, 0x30, 0x08, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x49, 0x53, 0x47, 0x31, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x4f, 0x53, 0x47, 0x31, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x08, 0x00, 0x00, 0x00, 0x50, 0x53, 0x56, 0x30, 0x5c, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4c, 0x14, 0x06, 0x00, 0x00, 0x60, 0x00, 0x05, 0x00, 0x85, 0x01, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4c, 0x00, 0x01, 0x00, 0x00,
|
||||
0x10, 0x00, 0x00, 0x00, 0xfc, 0x05, 0x00, 0x00, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0x7c, 0x01, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
|
||||
0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42,
|
||||
0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x52, 0x88, 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0xe4, 0x48, 0x0e, 0x90, 0x91, 0x22, 0xc4, 0x50,
|
||||
0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x29, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x1b, 0x8c, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x40, 0x02, 0xa8, 0x0d,
|
||||
0x84, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x20, 0x6d, 0x30, 0x86, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x09, 0xa8, 0x00, 0x49, 0x18, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x82, 0x60, 0x42,
|
||||
0x20, 0x4c, 0x08, 0x06, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3,
|
||||
0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x68, 0x23, 0x00, 0x25, 0x00, 0x14, 0xe6, 0x08, 0xc0, 0xa0, 0x0c, 0x63, 0x0c, 0x22, 0x73, 0x04, 0x48, 0x29, 0xc6,
|
||||
0x18, 0xc6, 0xd0, 0x21, 0x73, 0xcf, 0x70, 0xf9, 0x13, 0xf6, 0x10, 0x92, 0x1f, 0x02, 0xcd, 0xb0, 0x10, 0x28, 0x48, 0x73, 0x04, 0x41, 0x31, 0xd4, 0x30, 0x63, 0x2c, 0x62, 0x45, 0x01, 0x43, 0x8d,
|
||||
0x31, 0xc6, 0x18, 0x86, 0xdc, 0x4d, 0xc3, 0xe5, 0x4f, 0xd8, 0x43, 0x48, 0xfe, 0x4a, 0x48, 0x2b, 0x31, 0xf9, 0xc8, 0x6d, 0xa3, 0x62, 0x8c, 0x31, 0x46, 0x29, 0xe0, 0x50, 0x63, 0x50, 0x1c, 0x08,
|
||||
0x98, 0x89, 0x0c, 0xc6, 0x81, 0x1d, 0xc2, 0x61, 0x1e, 0xe6, 0xc1, 0x0d, 0x66, 0x81, 0x1e, 0xe4, 0xa1, 0x1e, 0xc6, 0x81, 0x1e, 0xea, 0x41, 0x1e, 0xca, 0x81, 0x1c, 0x44, 0xa1, 0x1e, 0xcc, 0xc1,
|
||||
0x1c, 0xca, 0x41, 0x1e, 0xf8, 0xa0, 0x1e, 0xdc, 0x61, 0x1e, 0xd2, 0xe1, 0x1c, 0xdc, 0xa1, 0x1c, 0xc8, 0x01, 0x0c, 0xd2, 0xc1, 0x1d, 0xe8, 0xc1, 0x0f, 0x50, 0x30, 0x88, 0xce, 0x64, 0x06, 0xe3,
|
||||
0xc0, 0x0e, 0xe1, 0x30, 0x0f, 0xf3, 0xe0, 0x06, 0xb2, 0x70, 0x0b, 0xb3, 0x40, 0x0f, 0xf2, 0x50, 0x0f, 0xe3, 0x40, 0x0f, 0xf5, 0x20, 0x0f, 0xe5, 0x40, 0x0e, 0xa2, 0x50, 0x0f, 0xe6, 0x60, 0x0e,
|
||||
0xe5, 0x20, 0x0f, 0x7c, 0x50, 0x0f, 0xee, 0x30, 0x0f, 0xe9, 0x70, 0x0e, 0xee, 0x50, 0x0e, 0xe4, 0x00, 0x06, 0xe9, 0xe0, 0x0e, 0xf4, 0xe0, 0x07, 0x28, 0x18, 0x64, 0xe7, 0x08, 0x40, 0x61, 0x0a,
|
||||
0x00, 0x00, 0x00, 0x00, 0x13, 0x14, 0x72, 0xc0, 0x87, 0x74, 0x60, 0x87, 0x36, 0x68, 0x87, 0x79, 0x68, 0x03, 0x72, 0xc0, 0x87, 0x0d, 0xaf, 0x50, 0x0e, 0x6d, 0xd0, 0x0e, 0x7a, 0x50, 0x0e, 0x6d,
|
||||
0x00, 0x0f, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e,
|
||||
0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x10,
|
||||
0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78,
|
||||
0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x43, 0x9e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x3c, 0x04, 0x10, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x79, 0x0e, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xf2, 0x10, 0x40, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x30, 0xe4, 0x61, 0x80, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xc8, 0xe3, 0x00, 0x01, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x90, 0x27, 0x02,
|
||||
0x02, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x2c, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x1a,
|
||||
0x25, 0x30, 0x02, 0x50, 0x08, 0xc5, 0x50, 0x18, 0x05, 0x42, 0x6b, 0x04, 0x80, 0x70, 0x81, 0x02, 0x02, 0xd1, 0x9d, 0x01, 0xa0, 0x3a, 0x03, 0x00, 0x79, 0x18, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
|
||||
0x1a, 0x03, 0x4c, 0x90, 0x46, 0x02, 0x13, 0xc4, 0x88, 0x0c, 0x6f, 0xec, 0xed, 0x4d, 0x0c, 0x44, 0x06, 0x26, 0x26, 0xc7, 0x05, 0xa6, 0xc6, 0x05, 0x06, 0x66, 0x43, 0x10, 0x4c, 0x10, 0x86, 0x63,
|
||||
0x82, 0x30, 0x20, 0x1b, 0x84, 0x81, 0x98, 0x20, 0x0c, 0xc9, 0x06, 0x61, 0x30, 0x28, 0x8c, 0xcd, 0x4d, 0x10, 0x06, 0x65, 0xc3, 0x80, 0x24, 0xc4, 0x04, 0xa1, 0x82, 0x08, 0x4c, 0x10, 0x86, 0x65,
|
||||
0x43, 0x42, 0x2c, 0x0c, 0x41, 0x0c, 0x0d, 0x71, 0x6c, 0x08, 0x9c, 0x09, 0xc2, 0xf5, 0x4c, 0x10, 0x96, 0x66, 0xc3, 0x42, 0x40, 0x0c, 0x41, 0x0c, 0x4d, 0x14, 0x45, 0xc7, 0x86, 0x40, 0xda, 0x40,
|
||||
0x3c, 0x13, 0x00, 0x4c, 0x10, 0x04, 0x60, 0x03, 0xb0, 0x61, 0x20, 0x2c, 0x6b, 0x43, 0x70, 0x6d, 0x18, 0x86, 0x0a, 0x23, 0xd1, 0x16, 0x96, 0xe6, 0x36, 0x41, 0xc0, 0x9c, 0x09, 0xc2, 0xc0, 0x6c,
|
||||
0x18, 0xb8, 0x61, 0xd8, 0x40, 0x10, 0x9b, 0xd1, 0x6d, 0x28, 0x2a, 0x0d, 0xa0, 0xbc, 0x2a, 0x6c, 0x6c, 0x76, 0x6d, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x53, 0x82, 0xa0, 0x0a, 0x19, 0x9e, 0x8b,
|
||||
0x5d, 0x99, 0xdc, 0x5c, 0xda, 0x9b, 0xdb, 0x94, 0x80, 0x68, 0x42, 0x86, 0xe7, 0x62, 0x17, 0xc6, 0x66, 0x57, 0x26, 0x37, 0x25, 0x30, 0xea, 0x90, 0xe1, 0xb9, 0xcc, 0xa1, 0x85, 0x91, 0x95, 0xc9,
|
||||
0x35, 0xbd, 0x91, 0x95, 0xb1, 0x4d, 0x09, 0x92, 0x32, 0x64, 0x78, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x53, 0x82, 0xa9, 0x12, 0x19, 0x9e, 0x0b, 0x5d, 0x1e, 0x5c, 0x59,
|
||||
0x90, 0x9b, 0xdb, 0x1b, 0x5d, 0x18, 0x5d, 0xda, 0x9b, 0xdb, 0xdc, 0x94, 0x00, 0xab, 0x43, 0x86, 0xe7, 0x52, 0xe6, 0x46, 0x27, 0x97, 0x07, 0xf5, 0x96, 0xe6, 0x46, 0x37, 0x37, 0x25, 0xf0, 0x00,
|
||||
0x79, 0x18, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73,
|
||||
0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b,
|
||||
0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20,
|
||||
0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61,
|
||||
0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87,
|
||||
0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98,
|
||||
0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61,
|
||||
0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b,
|
||||
0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x8c, 0xcc, 0x21, 0x07, 0x7c, 0x70, 0x03, 0x74, 0x60, 0x07, 0x37, 0x90, 0x87, 0x72, 0x98, 0x87, 0x77, 0xa8,
|
||||
0x07, 0x79, 0x18, 0x87, 0x72, 0x70, 0x83, 0x70, 0xa0, 0x07, 0x7a, 0x90, 0x87, 0x74, 0x10, 0x87, 0x7a, 0xa0, 0x87, 0x72, 0x00, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00,
|
||||
0x66, 0x40, 0x0d, 0x97, 0xef, 0x3c, 0x7e, 0x40, 0x15, 0x05, 0x11, 0x95, 0x0e, 0x30, 0xf8, 0xc8, 0x6d, 0x5b, 0x41, 0x35, 0x5c, 0xbe, 0xf3, 0xf8, 0x01, 0x55, 0x14, 0x44, 0xc4, 0x4e, 0x4e, 0x44,
|
||||
0xf8, 0xc8, 0x6d, 0x1b, 0x81, 0x34, 0x5c, 0xbe, 0xf3, 0xf8, 0x42, 0x44, 0x00, 0x13, 0x11, 0x02, 0xcd, 0xb0, 0x10, 0x16, 0x20, 0x0d, 0x97, 0xef, 0x3c, 0xfe, 0x74, 0x44, 0x04, 0x30, 0x88, 0x83,
|
||||
0x8f, 0xdc, 0xb6, 0x09, 0x58, 0xc3, 0xe5, 0x3b, 0x8f, 0x6f, 0x01, 0x15, 0xa1, 0x09, 0x13, 0x52, 0x11, 0xe8, 0xe3, 0x23, 0xb7, 0x6d, 0x03, 0xdb, 0x70, 0xf9, 0xce, 0xe3, 0x5b, 0x40, 0x45, 0xac,
|
||||
0x04, 0x30, 0x94, 0x40, 0x43, 0x7c, 0x48, 0x24, 0x4d, 0x3e, 0x72, 0xdb, 0x06, 0x40, 0x30, 0x00, 0xd2, 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x13, 0x04, 0x43, 0x2c,
|
||||
0x10, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x34, 0x66, 0x00, 0x4a, 0xae, 0x74, 0x03, 0x0a, 0x31, 0xa0, 0xd8, 0x03, 0xca, 0x3d, 0xa0, 0x14, 0x03, 0xc8, 0x94, 0xc0, 0x08, 0x00, 0x00, 0x00,
|
||||
0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0xc0, 0x58, 0x88, 0x20, 0x49, 0xcd, 0x88, 0x41, 0x02, 0x80, 0x20, 0x18, 0x30, 0x57, 0x22, 0x4c, 0x93, 0x33, 0x62, 0x60, 0x00, 0x20, 0x08, 0x06, 0xc4, 0x96,
|
||||
0x50, 0x23, 0x06, 0x08, 0x00, 0x82, 0x60, 0x10, 0x5d, 0x89, 0x10, 0x54, 0xa3, 0x09, 0x01, 0x30, 0x4b, 0x10, 0x8c, 0x18, 0x18, 0x00, 0x08, 0x82, 0x01, 0xc1, 0x29, 0xc1, 0x70, 0x83, 0x10, 0x80,
|
||||
0xc1, 0x2c, 0x83, 0x10, 0x04, 0x23, 0x06, 0x08, 0x00, 0x82, 0x60, 0x70, 0x7c, 0xcb, 0x80, 0x24, 0x23, 0x06, 0x0d, 0x00, 0x82, 0x60, 0xe0, 0x74, 0x0b, 0x62, 0x68, 0x41, 0x14, 0x45, 0x0a, 0x02,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
static const D3D12_SHADER_BYTECODE reconvergence_code = SHADER_BYTECODE(reconvergence_dxil);
|
||||
|
||||
/* Compiled with Version: dxcompiler.dll: 1.6 - 1.6.2112.12 (770ac0cc1); dxil.dll: 1.6(101.6.2112.2)
|
||||
* This version of DXC seems to workaround the control flow issue and explicitly hoists the wave-op out of the branch
|
||||
* to avoid convergence, most curious! */
|
||||
#if 0
|
||||
@dx.break.cond = internal constant [1 x i32] zeroinitializer
|
||||
define void @main() {
|
||||
%1 = load i32, i32* getelementptr inbounds ([1 x i32], [1 x i32]* @dx.break.cond, i32 0, i32 0)
|
||||
%2 = icmp eq i32 %1, 0
|
||||
%3 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 1, i32 0, i32 0, i1 false) ; CreateHandle(resourceClass,rangeId,index,nonUniformIndex)
|
||||
%4 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 0, i32 0, i32 0, i1 false) ; CreateHandle(resourceClass,rangeId,index,nonUniformIndex)
|
||||
%5 = call i32 @dx.op.threadId.i32(i32 93, i32 0) ; ThreadId(component)
|
||||
%6 = call %dx.types.ResRet.i32 @dx.op.bufferLoad.i32(i32 68, %dx.types.Handle %4, i32 %5, i32 0) ; BufferLoad(srv,index,wot)
|
||||
%7 = extractvalue %dx.types.ResRet.i32 %6, 0
|
||||
br label %8
|
||||
|
||||
; <label>:8 ; preds = %13, %0
|
||||
%9 = call i32 @dx.op.waveReadLaneFirst.i32(i32 118, i32 %7) ; WaveReadLaneFirst(value)
|
||||
%10 = icmp eq i32 %7, %9
|
||||
br i1 %10, label %11, label %13
|
||||
|
||||
; <label>:11 ; preds = %8
|
||||
%12 = call i32 @dx.op.waveActiveOp.i32(i32 119, i32 %7, i8 0, i8 1) ; WaveActiveOp(value,op,sop)
|
||||
; Wow ... Load a constant 0 from a Private array and branch on that.
|
||||
br i1 %2, label %14, label %13
|
||||
|
||||
; <label>:13 ; preds = %11, %8
|
||||
br label %8
|
||||
|
||||
; <label>:14 ; preds = %11
|
||||
call void @dx.op.bufferStore.i32(i32 69, %dx.types.Handle %3, i32 %5, i32 0, i32 %12, i32 undef, i32 undef, i32 undef, i8 1) ; BufferStore(uav,coord0,coord1,value0,value1,value2,value3,mask)
|
||||
ret void
|
||||
}
|
||||
#endif
|
||||
static const BYTE nonconvergence_dxil[] =
|
||||
{
|
||||
0x44, 0x58, 0x42, 0x43, 0x6a, 0xe3, 0x1a, 0x21, 0xec, 0x33, 0x8f, 0x47, 0xcb, 0xd9, 0x75, 0x47, 0x59, 0x62, 0x3f, 0x1f, 0x01, 0x00, 0x00, 0x00, 0x6c, 0x07, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
|
||||
0x38, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0xe8, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x53, 0x46, 0x49, 0x30, 0x08, 0x00, 0x00, 0x00,
|
||||
0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x53, 0x47, 0x31, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x4f, 0x53, 0x47, 0x31, 0x08, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x50, 0x53, 0x56, 0x30, 0x78, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x41, 0x53, 0x48, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x96, 0xd4, 0x61, 0x94, 0x9f, 0xd5, 0x2a, 0x70, 0x1d, 0xed, 0x1f, 0xc3,
|
||||
0x53, 0x48, 0x48, 0x9e, 0x44, 0x58, 0x49, 0x4c, 0x60, 0x06, 0x00, 0x00, 0x60, 0x00, 0x05, 0x00, 0x98, 0x01, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4c, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
|
||||
0x48, 0x06, 0x00, 0x00, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0x8f, 0x01, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91,
|
||||
0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14,
|
||||
0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x52, 0x88, 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0xe4, 0x48, 0x0e, 0x90, 0x91, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c,
|
||||
0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x29, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x1b, 0x8c, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x40, 0x02, 0xa8, 0x0d, 0x84, 0xf0, 0xff, 0xff,
|
||||
0xff, 0xff, 0x03, 0x20, 0x6d, 0x30, 0x86, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x09, 0xa8, 0x00, 0x49, 0x18, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x82, 0x60, 0x42, 0x20, 0x4c, 0x08, 0x06,
|
||||
0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14,
|
||||
0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x74, 0x73, 0x04, 0x60, 0x90, 0x01, 0x80, 0xc2, 0x08, 0x40, 0x09, 0x06, 0x91, 0x32, 0x00, 0x00, 0xc8, 0xcc, 0x11, 0x20, 0xa5, 0x00, 0x00,
|
||||
0x20, 0x44, 0x89, 0xd0, 0x3d, 0xc3, 0xe5, 0x4f, 0xd8, 0x43, 0x48, 0x7e, 0x08, 0x34, 0xc3, 0x42, 0xa0, 0x60, 0xcd, 0x11, 0x04, 0xc5, 0x60, 0x00, 0x01, 0xd0, 0xc8, 0x15, 0x65, 0x00, 0x06, 0x00,
|
||||
0x00, 0x00, 0x20, 0x82, 0x37, 0x0d, 0x97, 0x3f, 0x61, 0x0f, 0x21, 0xf9, 0x2b, 0x21, 0xad, 0xc4, 0xe4, 0x23, 0xb7, 0x8d, 0x0a, 0x00, 0x00, 0x00, 0xa5, 0x90, 0x80, 0x01, 0x40, 0x73, 0x20, 0x60,
|
||||
0x26, 0x32, 0x18, 0x07, 0x76, 0x08, 0x87, 0x79, 0x98, 0x07, 0x37, 0x98, 0x05, 0x7a, 0x90, 0x87, 0x7a, 0x18, 0x07, 0x7a, 0xa8, 0x07, 0x79, 0x28, 0x07, 0x72, 0x10, 0x85, 0x7a, 0x30, 0x07, 0x73,
|
||||
0x28, 0x07, 0x79, 0xe0, 0x83, 0x7a, 0x70, 0x87, 0x79, 0x48, 0x87, 0x73, 0x70, 0x87, 0x72, 0x20, 0x07, 0x30, 0x48, 0x07, 0x77, 0xa0, 0x07, 0x3f, 0x40, 0x01, 0x20, 0x3b, 0x93, 0x19, 0x8c, 0x03,
|
||||
0x3b, 0x84, 0xc3, 0x3c, 0xcc, 0x83, 0x1b, 0xc8, 0xc2, 0x2d, 0xcc, 0x02, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xd4, 0x83, 0x3c, 0x94, 0x03, 0x39, 0x88, 0x42, 0x3d, 0x98, 0x83, 0x39, 0x94,
|
||||
0x83, 0x3c, 0xf0, 0x41, 0x3d, 0xb8, 0xc3, 0x3c, 0xa4, 0xc3, 0x39, 0xb8, 0x43, 0x39, 0x90, 0x03, 0x18, 0xa4, 0x83, 0x3b, 0xd0, 0x83, 0x1f, 0xa0, 0x00, 0x10, 0x9e, 0x23, 0x00, 0x05, 0x02, 0x53,
|
||||
0x00, 0x00, 0x00, 0x00, 0x13, 0x14, 0x72, 0xc0, 0x87, 0x74, 0x60, 0x87, 0x36, 0x68, 0x87, 0x79, 0x68, 0x03, 0x72, 0xc0, 0x87, 0x0d, 0xaf, 0x50, 0x0e, 0x6d, 0xd0, 0x0e, 0x7a, 0x50, 0x0e, 0x6d,
|
||||
0x00, 0x0f, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e,
|
||||
0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x10,
|
||||
0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78,
|
||||
0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x3a, 0x0f, 0x24, 0x90, 0x21, 0x23, 0x25, 0x40, 0x00, 0x1e, 0xa6, 0x31, 0xe4, 0x21, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xc8, 0x63, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x90, 0x27, 0x01, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x21, 0x8f, 0x01, 0x04, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x1e, 0x07, 0x08, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x3c, 0x10, 0x10, 0x00,
|
||||
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x79, 0x26, 0x20, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x02, 0x01, 0x0b, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x14,
|
||||
0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x02, 0x25, 0x30, 0x02, 0x50, 0x0c, 0x85, 0x51, 0x08, 0x05, 0x42, 0xba, 0x40, 0x01, 0x81, 0xa8, 0x8d, 0x00, 0xd0, 0x9d, 0x01,
|
||||
0xa0, 0x3c, 0x03, 0x40, 0x61, 0x04, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x90, 0x46, 0x02, 0x13, 0x44, 0x35, 0x18, 0x63, 0x0b, 0x73, 0x3b, 0x03, 0xb1,
|
||||
0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x03, 0x99, 0x71, 0xb9, 0x01, 0x41, 0xa1, 0x0b, 0x3b, 0x9b, 0x7b, 0x91, 0x2a, 0x62, 0x2a, 0x0a, 0x9a, 0x2a, 0xfa, 0x9a, 0xb9, 0x81, 0x79, 0x31, 0x4b, 0x73,
|
||||
0x0b, 0x63, 0x4b, 0xd9, 0x10, 0x04, 0x13, 0x04, 0x00, 0x99, 0x20, 0x00, 0xc9, 0x06, 0x61, 0x20, 0x26, 0x08, 0x80, 0xb2, 0x41, 0x18, 0x0c, 0x0a, 0x63, 0x73, 0x1b, 0x06, 0xc4, 0x20, 0x26, 0x08,
|
||||
0x17, 0x44, 0x60, 0x82, 0x00, 0x2c, 0x13, 0x04, 0x80, 0xd9, 0x20, 0x0c, 0xcd, 0x86, 0x84, 0x50, 0x16, 0x82, 0x18, 0x18, 0xc2, 0xd9, 0x10, 0x3c, 0x13, 0x84, 0x2c, 0x9a, 0x20, 0x34, 0xcf, 0x86,
|
||||
0x85, 0x88, 0x16, 0x82, 0x18, 0x18, 0x49, 0x92, 0x9c, 0x0d, 0xc1, 0xb4, 0x81, 0x80, 0x28, 0x00, 0x98, 0x20, 0x14, 0x01, 0x89, 0xb6, 0xb0, 0x34, 0xb7, 0x09, 0x82, 0xe6, 0x4c, 0x10, 0x80, 0x66,
|
||||
0xc3, 0x90, 0x0d, 0xc3, 0x06, 0x82, 0xc0, 0x1a, 0x6d, 0x43, 0x61, 0x5d, 0x40, 0xb5, 0x55, 0x61, 0x63, 0xb3, 0x6b, 0x73, 0x49, 0x23, 0x2b, 0x73, 0xa3, 0x9b, 0x12, 0x04, 0x55, 0xc8, 0xf0, 0x5c,
|
||||
0xec, 0xca, 0xe4, 0xe6, 0xd2, 0xde, 0xdc, 0xa6, 0x04, 0x44, 0x13, 0x32, 0x3c, 0x17, 0xbb, 0x30, 0x36, 0xbb, 0x32, 0xb9, 0x29, 0x81, 0x51, 0x87, 0x0c, 0xcf, 0x65, 0x0e, 0x2d, 0x8c, 0xac, 0x4c,
|
||||
0xae, 0xe9, 0x8d, 0xac, 0x8c, 0x6d, 0x4a, 0x80, 0x94, 0x21, 0xc3, 0x73, 0x91, 0x2b, 0x9b, 0x7b, 0xab, 0x93, 0x1b, 0x2b, 0x9b, 0x9b, 0x12, 0x50, 0x75, 0xc8, 0xf0, 0x5c, 0xca, 0xdc, 0xe8, 0xe4,
|
||||
0xf2, 0xa0, 0xde, 0xd2, 0xdc, 0xe8, 0xe6, 0xa6, 0x04, 0x1b, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88,
|
||||
0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce,
|
||||
0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48,
|
||||
0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e,
|
||||
0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b,
|
||||
0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78,
|
||||
0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1,
|
||||
0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39,
|
||||
0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc4, 0x21, 0x07, 0x7c, 0x70,
|
||||
0x03, 0x7a, 0x28, 0x87, 0x76, 0x80, 0x87, 0x19, 0xcc, 0x43, 0x0e, 0xf8, 0xe0, 0x06, 0xe2, 0x20, 0x0f, 0xe5, 0x10, 0x0e, 0xeb, 0xe0, 0x06, 0xe2, 0x20, 0x0f, 0x33, 0x22, 0x88, 0x1c, 0xf0, 0xc1,
|
||||
0x0d, 0xc8, 0x41, 0x1c, 0xce, 0xc1, 0x0d, 0xec, 0x21, 0x1c, 0xe4, 0x81, 0x1d, 0xc2, 0x21, 0x1f, 0xde, 0xa1, 0x1e, 0xe8, 0x01, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
|
||||
0x06, 0xd0, 0x0c, 0x97, 0x1f, 0x44, 0x04, 0xa0, 0xf8, 0x82, 0xd3, 0x0c, 0x76, 0x40, 0x0d, 0x97, 0xef, 0x3c, 0x7e, 0x40, 0x15, 0x05, 0x11, 0x95, 0x0e, 0x30, 0xf8, 0xc8, 0x6d, 0x9b, 0x41, 0x35,
|
||||
0x5c, 0xbe, 0xf3, 0xf8, 0x01, 0x55, 0x14, 0x44, 0xc4, 0x4e, 0x4e, 0x44, 0xf8, 0xc8, 0x6d, 0x5b, 0x81, 0x34, 0x5c, 0xbe, 0xf3, 0xf8, 0x42, 0x44, 0x00, 0x13, 0x11, 0x02, 0xcd, 0xb0, 0x10, 0x26,
|
||||
0x20, 0x0d, 0x97, 0xef, 0x3c, 0xfe, 0x74, 0x44, 0x04, 0x30, 0x88, 0x83, 0x8f, 0xdc, 0xb6, 0x0d, 0x58, 0xc3, 0xe5, 0x3b, 0x8f, 0x6f, 0x01, 0x15, 0xa1, 0x09, 0x13, 0x52, 0x11, 0xe8, 0xe3, 0x23,
|
||||
0xb7, 0x6d, 0x04, 0xdb, 0x70, 0xf9, 0xce, 0xe3, 0x5b, 0x40, 0x45, 0xac, 0x04, 0x30, 0x94, 0x40, 0x43, 0x7c, 0x48, 0x24, 0x4d, 0x3e, 0x72, 0xdb, 0x16, 0x40, 0x30, 0x00, 0xd2, 0x00, 0x00, 0x00,
|
||||
0x61, 0x20, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x13, 0x04, 0x45, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x66, 0x00, 0x4a, 0xae, 0x74, 0x03, 0x0a, 0x31, 0xa0, 0xd8, 0x03,
|
||||
0xca, 0x3d, 0xa0, 0x14, 0x03, 0x08, 0x95, 0xc0, 0x08, 0x00, 0xed, 0xa1, 0x8e, 0x40, 0x00, 0x80, 0x04, 0x48, 0x00, 0x00, 0x14, 0x00, 0x30, 0xdc, 0x10, 0x54, 0x60, 0x30, 0x62, 0x90, 0x00, 0x20,
|
||||
0x08, 0x06, 0x8e, 0xb6, 0x14, 0x96, 0x05, 0x8d, 0x18, 0x24, 0x00, 0x08, 0x82, 0x81, 0xb3, 0x31, 0xc5, 0x75, 0x45, 0x23, 0x06, 0x06, 0x00, 0x82, 0x60, 0x60, 0x7c, 0x0c, 0x36, 0x62, 0x80, 0x00,
|
||||
0x20, 0x08, 0x06, 0xd3, 0xc6, 0x08, 0x41, 0x36, 0x9a, 0x10, 0x00, 0xb3, 0x04, 0xc1, 0x88, 0x81, 0x01, 0x80, 0x20, 0x18, 0x18, 0x60, 0xd0, 0x04, 0xc3, 0x0d, 0x42, 0x00, 0x06, 0xb3, 0x0c, 0xc2,
|
||||
0x10, 0x8c, 0x18, 0x20, 0x00, 0x08, 0x82, 0x41, 0x32, 0x06, 0xce, 0xb0, 0x30, 0xb3, 0x0c, 0xc4, 0x90, 0xcc, 0x12, 0x04, 0x23, 0x06, 0x0d, 0x00, 0x82, 0x60, 0x00, 0x85, 0x81, 0x83, 0x18, 0x5e,
|
||||
0x40, 0x51, 0x54, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
static const D3D12_SHADER_BYTECODE nonconvergence_code = SHADER_BYTECODE(nonconvergence_dxil);
|
||||
|
||||
memset(root_parameters, 0, sizeof(root_parameters));
|
||||
memset(&rs_desc, 0, sizeof(rs_desc));
|
||||
root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_SRV;
|
||||
root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
|
||||
root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV;
|
||||
root_parameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
|
||||
rs_desc.pParameters = root_parameters;
|
||||
rs_desc.NumParameters = ARRAY_SIZE(root_parameters);
|
||||
|
||||
if (!init_compute_test_context(&context))
|
||||
return;
|
||||
|
||||
if (!context_supports_dxil(&context))
|
||||
{
|
||||
skip("Context does not support DXIL.\n");
|
||||
destroy_test_context(&context);
|
||||
return;
|
||||
}
|
||||
|
||||
create_root_signature(context.device, &rs_desc, &context.root_signature);
|
||||
pso_converged = create_compute_pipeline_state(context.device, context.root_signature, reconvergence_code);
|
||||
pso_nonconverged = create_compute_pipeline_state(context.device, context.root_signature, nonconvergence_code);
|
||||
|
||||
inputs = create_upload_buffer(context.device, sizeof(inputs_data), inputs_data);
|
||||
outputs = create_default_buffer(context.device, sizeof(inputs_data) * 2,
|
||||
D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
|
||||
|
||||
ID3D12GraphicsCommandList_SetComputeRootSignature(context.list, context.root_signature);
|
||||
ID3D12GraphicsCommandList_SetPipelineState(context.list, pso_converged);
|
||||
ID3D12GraphicsCommandList_SetComputeRootShaderResourceView(context.list, 0,
|
||||
ID3D12Resource_GetGPUVirtualAddress(inputs));
|
||||
ID3D12GraphicsCommandList_SetComputeRootUnorderedAccessView(context.list, 1,
|
||||
ID3D12Resource_GetGPUVirtualAddress(outputs));
|
||||
ID3D12GraphicsCommandList_Dispatch(context.list, 1, 1, 1);
|
||||
ID3D12GraphicsCommandList_SetComputeRootUnorderedAccessView(context.list, 1,
|
||||
ID3D12Resource_GetGPUVirtualAddress(outputs) + sizeof(reference_converged));
|
||||
ID3D12GraphicsCommandList_SetPipelineState(context.list, pso_nonconverged);
|
||||
ID3D12GraphicsCommandList_Dispatch(context.list, 1, 1, 1);
|
||||
|
||||
transition_resource_state(context.list, outputs,
|
||||
D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
|
||||
|
||||
get_buffer_readback_with_command_list(outputs, DXGI_FORMAT_R32_UINT, &rb, context.queue, context.list);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(reference_converged); i++)
|
||||
{
|
||||
uint32_t v = get_readback_uint(&rb, i, 0, 0);
|
||||
ok(v == reference_converged[i], "Element %u, %u != %u.\n", i, v, reference_converged[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(reference_nonconverged); i++)
|
||||
{
|
||||
uint32_t v = get_readback_uint(&rb, i + 16, 0, 0);
|
||||
ok(v == reference_nonconverged[i], "Element %u, %u != %u.\n", i, v, reference_nonconverged[i]);
|
||||
}
|
||||
|
||||
release_resource_readback(&rb);
|
||||
|
||||
ID3D12Resource_Release(inputs);
|
||||
ID3D12Resource_Release(outputs);
|
||||
ID3D12PipelineState_Release(pso_converged);
|
||||
ID3D12PipelineState_Release(pso_nonconverged);
|
||||
destroy_test_context(&context);
|
||||
}
|
||||
|
||||
void test_shader_sm65_wave_intrinsics(void)
|
||||
{
|
||||
D3D12_FEATURE_DATA_SHADER_MODEL shader_model;
|
||||
|
@ -4550,7 +4834,7 @@ void test_shader_sm66_is_helper_lane(void)
|
|||
{
|
||||
/* Oh, hi there. */
|
||||
static const float alpha_keys[4] = { 0.75f, 2.25f, 3.25f, 3.75f };
|
||||
static const struct vec4 white = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
static const float white[] = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
D3D12_FEATURE_DATA_SHADER_MODEL shader_model;
|
||||
D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
|
||||
D3D12_UNORDERED_ACCESS_VIEW_DESC uav_desc;
|
||||
|
@ -4757,7 +5041,7 @@ void test_shader_sm66_is_helper_lane(void)
|
|||
ID3D12Device_CreateUnorderedAccessView(context.device, atomic_buffer, NULL, &uav_desc, cpu_handle);
|
||||
|
||||
ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &heap);
|
||||
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, &white.x, 0, NULL);
|
||||
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
|
||||
ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
|
||||
ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
|
||||
ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
|
||||
|
@ -4804,7 +5088,7 @@ void test_shader_sm66_is_helper_lane(void)
|
|||
expected.w = 8881.0f;
|
||||
}
|
||||
else
|
||||
expected = white;
|
||||
memcpy(&expected, white, sizeof(white));
|
||||
|
||||
ok(compare_vec4(value, &expected, 0), "Mismatch pixel %u, %u, (%f %f %f %f) != (%f %f %f %f).\n",
|
||||
x, y, expected.x, expected.y, expected.z, expected.w,
|
||||
|
@ -4820,3 +5104,588 @@ void test_shader_sm66_is_helper_lane(void)
|
|||
destroy_test_context(&context);
|
||||
}
|
||||
|
||||
void test_advanced_cbv_layout(void)
|
||||
{
|
||||
/* This is extremely cursed in DXC ... D: */
|
||||
D3D12_FEATURE_DATA_D3D12_OPTIONS4 features4;
|
||||
D3D12_FEATURE_DATA_D3D12_OPTIONS1 features1;
|
||||
D3D12_CONSTANT_BUFFER_VIEW_DESC cbv_desc;
|
||||
D3D12_ROOT_PARAMETER root_parameters[3];
|
||||
D3D12_ROOT_SIGNATURE_DESC rs_desc;
|
||||
D3D12_DESCRIPTOR_RANGE range[1];
|
||||
struct test_context context;
|
||||
struct resource_readback rb;
|
||||
ID3D12DescriptorHeap *heap;
|
||||
ID3D12Resource *cbv_buffer;
|
||||
ID3D12Resource *uav_buffer;
|
||||
uint32_t input_buffer[64];
|
||||
ID3D12PipelineState *pso;
|
||||
bool support_16bit;
|
||||
bool support_64bit;
|
||||
unsigned int i, j;
|
||||
|
||||
#if 0
|
||||
cbuffer Cbuf : register(b0)
|
||||
{
|
||||
uint64_t4 values_root[8];
|
||||
};
|
||||
|
||||
cbuffer Cbuf : register(b0, space1)
|
||||
{
|
||||
uint64_t4 values_table[8];
|
||||
};
|
||||
|
||||
RWStructuredBuffer<uint> RWBuf : register(u0);
|
||||
|
||||
uint pack4(uint4 v)
|
||||
{
|
||||
return v.x | (v.y << 8) | (v.z << 16) | (v.w << 24);
|
||||
}
|
||||
|
||||
[numthreads(8, 1, 1)]
|
||||
void main(uint thr : SV_DispatchThreadID)
|
||||
{
|
||||
uint64_t4 v = values_root[thr] + values_table[thr];
|
||||
uint4 lo = uint4(v);
|
||||
uint4 hi = uint4(v >> 32);
|
||||
RWBuf[2 * thr + 0] = pack4(lo);
|
||||
RWBuf[2 * thr + 1] = pack4(hi);
|
||||
}
|
||||
#endif
|
||||
static const BYTE cs_legacy_uint64_code[] =
|
||||
{
|
||||
0x44, 0x58, 0x42, 0x43, 0x96, 0xca, 0xa3, 0x18, 0x56, 0xf8, 0xd5, 0xa3, 0xd8, 0xc2, 0x6f, 0x4e, 0x51, 0x02, 0xf3, 0x54, 0x01, 0x00, 0x00, 0x00, 0x88, 0x07, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
|
||||
0x38, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1c, 0x01, 0x00, 0x00, 0x53, 0x46, 0x49, 0x30, 0x08, 0x00, 0x00, 0x00,
|
||||
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x53, 0x47, 0x31, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x4f, 0x53, 0x47, 0x31, 0x08, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x50, 0x53, 0x56, 0x30, 0x90, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x48, 0x41, 0x53, 0x48, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x75, 0xa5, 0x06, 0x98, 0x3e, 0x10, 0x1e, 0x1e, 0xd3, 0x41, 0xf1, 0xd3, 0xdf, 0xbb, 0x4f, 0x44, 0x58, 0x49, 0x4c,
|
||||
0x64, 0x06, 0x00, 0x00, 0x60, 0x00, 0x05, 0x00, 0x99, 0x01, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4c, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x4c, 0x06, 0x00, 0x00, 0x42, 0x43, 0xc0, 0xde,
|
||||
0x21, 0x0c, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39,
|
||||
0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x52, 0x88,
|
||||
0x48, 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0xe4, 0x48, 0x0e, 0x90, 0x91, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x29, 0x46, 0x06,
|
||||
0x51, 0x18, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x1b, 0x8c, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x40, 0x02, 0xa8, 0x0d, 0x86, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x20, 0x01, 0xd5, 0x06, 0x62,
|
||||
0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x90, 0x00, 0x49, 0x18, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x82, 0x60, 0x42, 0x20, 0x4c, 0x08, 0x06, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00,
|
||||
0x31, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c,
|
||||
0x10, 0x6c, 0x23, 0x00, 0x25, 0x00, 0x14, 0xe6, 0x08, 0xc0, 0xa0, 0x0c, 0x63, 0x0c, 0x22, 0x73, 0x04, 0xa0, 0x70, 0xd4, 0x70, 0xf9, 0x13, 0xf6, 0x10, 0x92, 0xcf, 0x6d, 0x54, 0xb1, 0x12, 0x93,
|
||||
0x8f, 0xe8, 0x38, 0x12, 0x8c, 0x99, 0x23, 0x40, 0x08, 0xdd, 0x33, 0x5c, 0xfe, 0x84, 0x3d, 0x84, 0xe4, 0x87, 0x40, 0x33, 0x2c, 0x04, 0x0a, 0x52, 0x21, 0xce, 0x50, 0x83, 0xd6, 0x1c, 0x41, 0x50,
|
||||
0x0c, 0x35, 0xd0, 0x18, 0x8d, 0x5c, 0x51, 0xc0, 0x50, 0x63, 0x8c, 0x31, 0x06, 0x22, 0x38, 0x10, 0x30, 0x93, 0x19, 0x8c, 0x03, 0x3b, 0x84, 0xc3, 0x3c, 0xcc, 0x83, 0x1b, 0xc8, 0xc2, 0x2d, 0xcc,
|
||||
0x02, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xd4, 0x83, 0x3c, 0x94, 0x03, 0x39, 0x88, 0x42, 0x3d, 0x98, 0x83, 0x39, 0x94, 0x83, 0x3c, 0xf0, 0x41, 0x3d, 0xb8, 0xc3, 0x3c, 0xa4, 0xc3, 0x39,
|
||||
0xb8, 0x43, 0x39, 0x90, 0x03, 0x18, 0xa4, 0x83, 0x3b, 0xd0, 0x83, 0x1f, 0xa0, 0x60, 0xd0, 0x1c, 0x46, 0x20, 0x8c, 0x44, 0xa8, 0x47, 0x70, 0x01, 0x55, 0xa0, 0xc0, 0xd2, 0x3d, 0x83, 0x0b, 0xa8,
|
||||
0xc2, 0xa7, 0x51, 0x60, 0x29, 0x03, 0x00, 0x00, 0x13, 0x14, 0x72, 0xc0, 0x87, 0x74, 0x60, 0x87, 0x36, 0x68, 0x87, 0x79, 0x68, 0x03, 0x72, 0xc0, 0x87, 0x0d, 0xaf, 0x50, 0x0e, 0x6d, 0xd0, 0x0e,
|
||||
0x7a, 0x50, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x73, 0x20,
|
||||
0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74,
|
||||
0xd0, 0x06, 0xe6, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07,
|
||||
0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x43, 0x9e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86,
|
||||
0x3c, 0x04, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x79, 0x16, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xf2, 0x38, 0x40, 0x00, 0x08, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xe4, 0x81, 0x80, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x0b, 0x04, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x14,
|
||||
0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x1a, 0x25, 0x30, 0x02, 0x50, 0x0c, 0x85, 0x51, 0x08, 0x05, 0x48, 0x50, 0x10, 0x64, 0x0a, 0x14, 0x10, 0x30, 0x80, 0xda, 0x08,
|
||||
0x00, 0xd1, 0x19, 0x00, 0xc2, 0x33, 0x00, 0xa4, 0x67, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x90, 0x46, 0x02, 0x13, 0x44, 0x35, 0x18, 0x63, 0x0b,
|
||||
0x73, 0x3b, 0x03, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x03, 0x99, 0x71, 0xb9, 0x01, 0x41, 0xa1, 0x0b, 0x3b, 0x9b, 0x7b, 0x91, 0x2a, 0x62, 0x2a, 0x0a, 0x9a, 0x2a, 0xfa, 0x9a, 0xb9, 0x81,
|
||||
0x79, 0x31, 0x4b, 0x73, 0x0b, 0x63, 0x4b, 0xd9, 0x10, 0x04, 0x13, 0x84, 0xa1, 0x98, 0x20, 0x0c, 0xc6, 0x06, 0x61, 0x20, 0x26, 0x08, 0xc3, 0xb1, 0x41, 0x18, 0x0c, 0x0a, 0x63, 0x73, 0x1b, 0x06,
|
||||
0xc4, 0x20, 0x26, 0x08, 0x94, 0x43, 0x60, 0x82, 0x30, 0x20, 0x13, 0x84, 0xa6, 0x99, 0x20, 0x0c, 0xc9, 0x06, 0x61, 0x70, 0x36, 0x2c, 0x84, 0xb2, 0x10, 0xc4, 0xc0, 0x34, 0x4d, 0xf3, 0x6c, 0x08,
|
||||
0xa0, 0x09, 0x02, 0xf6, 0x4c, 0x10, 0x06, 0x65, 0x03, 0x42, 0x48, 0x0b, 0x41, 0x0c, 0x13, 0x30, 0x41, 0xd0, 0xa0, 0x0d, 0xc8, 0x50, 0x2d, 0x03, 0x31, 0x4c, 0xc0, 0x06, 0x81, 0xb2, 0x36, 0x10,
|
||||
0x40, 0x74, 0x01, 0x13, 0x04, 0x01, 0x20, 0xd1, 0x16, 0x96, 0xe6, 0x36, 0x41, 0x30, 0x98, 0x09, 0xc2, 0xb0, 0x6c, 0x18, 0xb8, 0x61, 0xd8, 0x40, 0x10, 0x9b, 0xd3, 0x6d, 0x28, 0x32, 0x0d, 0xc0,
|
||||
0xbc, 0x2a, 0x6c, 0x6c, 0x76, 0x6d, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x53, 0x82, 0xa0, 0x0a, 0x19, 0x9e, 0x8b, 0x5d, 0x99, 0xdc, 0x5c, 0xda, 0x9b, 0xdb, 0x94, 0x80, 0x68, 0x42, 0x86, 0xe7,
|
||||
0x62, 0x17, 0xc6, 0x66, 0x57, 0x26, 0x37, 0x25, 0x30, 0xea, 0x90, 0xe1, 0xb9, 0xcc, 0xa1, 0x85, 0x91, 0x95, 0xc9, 0x35, 0xbd, 0x91, 0x95, 0xb1, 0x4d, 0x09, 0x90, 0x32, 0x64, 0x78, 0x2e, 0x72,
|
||||
0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x53, 0x82, 0xab, 0x0e, 0x19, 0x9e, 0x4b, 0x99, 0x1b, 0x9d, 0x5c, 0x1e, 0xd4, 0x5b, 0x9a, 0x1b, 0xdd, 0xdc, 0x94, 0xc0, 0x03, 0x00, 0x00, 0x00,
|
||||
0x79, 0x18, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73,
|
||||
0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b,
|
||||
0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20,
|
||||
0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61,
|
||||
0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87,
|
||||
0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98,
|
||||
0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61,
|
||||
0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b,
|
||||
0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc4, 0x21, 0x07, 0x7c, 0x70, 0x03, 0x7a, 0x28, 0x87, 0x76, 0x80, 0x87, 0x19, 0xd1, 0x43, 0x0e, 0xf8,
|
||||
0xe0, 0x06, 0xe4, 0x20, 0x0e, 0xe7, 0xe0, 0x06, 0xf6, 0x10, 0x0e, 0xf2, 0xc0, 0x0e, 0xe1, 0x90, 0x0f, 0xef, 0x50, 0x0f, 0xf4, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
|
||||
0x46, 0x50, 0x0d, 0x97, 0xef, 0x3c, 0x7e, 0x40, 0x15, 0x05, 0x11, 0xb1, 0x93, 0x13, 0x11, 0x3e, 0x72, 0xdb, 0x26, 0xb0, 0x0d, 0x97, 0xef, 0x3c, 0xbe, 0x10, 0x50, 0x45, 0x41, 0x44, 0xa5, 0x03,
|
||||
0x0c, 0x25, 0x61, 0x00, 0x02, 0xe6, 0x23, 0x3a, 0x6e, 0x03, 0xd2, 0x70, 0xf9, 0xce, 0xe3, 0x0b, 0x11, 0x01, 0x4c, 0x44, 0x08, 0x34, 0xc3, 0x42, 0x58, 0x80, 0x34, 0x5c, 0xbe, 0xf3, 0xf8, 0xd3,
|
||||
0x11, 0x11, 0xc0, 0x20, 0x0e, 0x3e, 0x72, 0xdb, 0x06, 0x40, 0x30, 0x00, 0xd2, 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00,
|
||||
0x0a, 0x00, 0x00, 0x00, 0x34, 0x66, 0x00, 0xca, 0xae, 0xe4, 0x4a, 0x31, 0xa0, 0x74, 0x03, 0x0a, 0xa4, 0x60, 0x2a, 0x90, 0xa0, 0x02, 0x01, 0x11, 0x2a, 0x10, 0x10, 0x10, 0x82, 0x4c, 0x01, 0x15,
|
||||
0x4c, 0x81, 0x14, 0x04, 0xa1, 0x12, 0x28, 0x02, 0x00, 0x00, 0x00, 0x00, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0xe0, 0x78, 0x8e, 0xb0, 0x6d, 0xd4, 0x88, 0x41, 0x02, 0x80, 0x20, 0x18, 0x38, 0xdf,
|
||||
0x23, 0x74, 0x5c, 0x35, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0x0e, 0x18, 0x40, 0x43, 0xd7, 0x59, 0x23, 0x06, 0x06, 0x00, 0x82, 0x60, 0x40, 0x8c, 0xc1, 0xe3, 0x55, 0x00, 0x06, 0x37, 0x62, 0x70,
|
||||
0x00, 0x20, 0x08, 0x06, 0x0b, 0x19, 0x50, 0x43, 0x30, 0x9a, 0x10, 0x00, 0xa3, 0x09, 0x42, 0x50, 0x04, 0x19, 0xec, 0x88, 0xc1, 0x01, 0x80, 0x20, 0x18, 0x2c, 0x68, 0x80, 0x1d, 0xc1, 0x68, 0x42,
|
||||
0x00, 0x8c, 0x26, 0x08, 0xc1, 0x88, 0xc1, 0x01, 0x80, 0x20, 0x18, 0x2c, 0x6b, 0xb0, 0x2d, 0xc8, 0x68, 0x42, 0x00, 0x8c, 0x26, 0x08, 0xc1, 0x88, 0xc1, 0x01, 0x80, 0x20, 0x18, 0x2c, 0x6e, 0xe0,
|
||||
0x39, 0xc7, 0x68, 0x42, 0x00, 0x8c, 0x26, 0x08, 0x41, 0x15, 0x0c, 0x54, 0xc1, 0x40, 0x11, 0x0a, 0x14, 0xa1, 0xc0, 0x11, 0x03, 0x8e, 0x18, 0x70, 0xc4, 0x80, 0x23, 0x06, 0x14, 0x02, 0x06, 0x78,
|
||||
0xc1, 0x80, 0x2a, 0xe4, 0xe0, 0x2a, 0x38, 0xb6, 0x8c, 0x34, 0xb8, 0x12, 0x82, 0xad, 0x43, 0x0d, 0xae, 0x84, 0x60, 0x47, 0x0c, 0x1a, 0x00, 0x04, 0xc1, 0x00, 0xfa, 0x83, 0x37, 0x10, 0x03, 0xaf,
|
||||
0x0f, 0x02, 0x39, 0x90, 0x03, 0x39, 0x20, 0x83, 0x7a, 0xce, 0x00, 0x2f, 0x18, 0x50, 0x41, 0x1b, 0x68, 0x05, 0xca, 0x96, 0xa4, 0x06, 0x78, 0xc1, 0x80, 0x0a, 0xe0, 0x40, 0x8b, 0x08, 0xb6, 0xaa,
|
||||
0x36, 0xc0, 0x0b, 0x06, 0x54, 0x30, 0x07, 0x5a, 0x44, 0xb0, 0x23, 0x06, 0x0d, 0x00, 0x82, 0x60, 0x00, 0xad, 0xc2, 0x1e, 0xb8, 0x81, 0x19, 0xa4, 0x42, 0xe0, 0x07, 0x7e, 0xe0, 0x07, 0x70, 0x80,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
/* -no-legacy-cbuf-layout variant. Tests CBufferLoad vs LoadLegacy() */
|
||||
static const BYTE cs_modern_uint64_code[] =
|
||||
{
|
||||
0x44, 0x58, 0x42, 0x43, 0x18, 0x99, 0xb1, 0x23, 0x80, 0xf3, 0x05, 0xf7, 0xc0, 0x1e, 0xd6, 0x21, 0x5c, 0xf3, 0xd0, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x94, 0x07, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
|
||||
0x38, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1c, 0x01, 0x00, 0x00, 0x53, 0x46, 0x49, 0x30, 0x08, 0x00, 0x00, 0x00,
|
||||
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x53, 0x47, 0x31, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x4f, 0x53, 0x47, 0x31, 0x08, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x50, 0x53, 0x56, 0x30, 0x90, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x48, 0x41, 0x53, 0x48, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9e, 0x97, 0x67, 0xe4, 0xf8, 0x45, 0xd6, 0x79, 0xed, 0x09, 0xc1, 0x5b, 0x49, 0x81, 0xb9, 0xa3, 0x44, 0x58, 0x49, 0x4c,
|
||||
0x70, 0x06, 0x00, 0x00, 0x60, 0x00, 0x05, 0x00, 0x9c, 0x01, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4c, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x58, 0x06, 0x00, 0x00, 0x42, 0x43, 0xc0, 0xde,
|
||||
0x21, 0x0c, 0x00, 0x00, 0x93, 0x01, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39,
|
||||
0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x52, 0x88,
|
||||
0x48, 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0xe4, 0x48, 0x0e, 0x90, 0x91, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x29, 0x46, 0x06,
|
||||
0x51, 0x18, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x1b, 0x8c, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x40, 0x02, 0xa8, 0x0d, 0x86, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x20, 0x01, 0xd5, 0x06, 0x62,
|
||||
0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x90, 0x00, 0x49, 0x18, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x82, 0x60, 0x42, 0x20, 0x4c, 0x08, 0x06, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00,
|
||||
0x2c, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c,
|
||||
0x10, 0x68, 0x23, 0x00, 0x25, 0x00, 0x14, 0xe6, 0x08, 0xc0, 0xa0, 0x0c, 0x63, 0x0c, 0x22, 0x73, 0x04, 0xa0, 0x30, 0x47, 0x80, 0xd0, 0xb9, 0x67, 0xb8, 0xfc, 0x09, 0x7b, 0x08, 0xc9, 0x0f, 0x81,
|
||||
0x66, 0x58, 0x08, 0x14, 0xa0, 0x52, 0x98, 0x91, 0xc6, 0x20, 0x35, 0x47, 0x10, 0x14, 0x23, 0x8d, 0x33, 0x06, 0xa3, 0x56, 0x14, 0x30, 0xd2, 0x18, 0x63, 0x8c, 0x71, 0xe8, 0x0d, 0x04, 0xcc, 0x64,
|
||||
0x06, 0xe3, 0xc0, 0x0e, 0xe1, 0x30, 0x0f, 0xf3, 0xe0, 0x06, 0xb2, 0x70, 0x0b, 0xb3, 0x40, 0x0f, 0xf2, 0x50, 0x0f, 0xe3, 0x40, 0x0f, 0xf5, 0x20, 0x0f, 0xe5, 0x40, 0x0e, 0xa2, 0x50, 0x0f, 0xe6,
|
||||
0x60, 0x0e, 0xe5, 0x20, 0x0f, 0x7c, 0x50, 0x0f, 0xee, 0x30, 0x0f, 0xe9, 0x70, 0x0e, 0xee, 0x50, 0x0e, 0xe4, 0x00, 0x06, 0xe9, 0xe0, 0x0e, 0xf4, 0xe0, 0x07, 0x28, 0x18, 0x24, 0x87, 0x11, 0x08,
|
||||
0x23, 0x11, 0xe8, 0x11, 0x5c, 0x40, 0x15, 0x28, 0xa8, 0x64, 0xcf, 0xe0, 0x02, 0xaa, 0xf0, 0x69, 0x14, 0x54, 0xc2, 0x00, 0x13, 0x14, 0x72, 0xc0, 0x87, 0x74, 0x60, 0x87, 0x36, 0x68, 0x87, 0x79,
|
||||
0x68, 0x03, 0x72, 0xc0, 0x87, 0x0d, 0xaf, 0x50, 0x0e, 0x6d, 0xd0, 0x0e, 0x7a, 0x50, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0,
|
||||
0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73,
|
||||
0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07,
|
||||
0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x43, 0x9e,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x3c, 0x04, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x79, 0x14, 0x20, 0x00, 0x04, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xf2, 0x34, 0x40, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xe4, 0x79, 0x80, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
|
||||
0x0b, 0x04, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x1a, 0x25, 0x30, 0x02, 0x50, 0x0c, 0x85, 0x51, 0x08,
|
||||
0x05, 0x48, 0x50, 0x10, 0x64, 0x0a, 0x14, 0x10, 0x30, 0x80, 0xd8, 0x08, 0x00, 0xcd, 0x19, 0x00, 0xba, 0x33, 0x00, 0x94, 0x67, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00,
|
||||
0x1a, 0x03, 0x4c, 0x90, 0x46, 0x02, 0x13, 0x44, 0x35, 0x18, 0x63, 0x0b, 0x73, 0x3b, 0x03, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x03, 0x99, 0x71, 0xb9, 0x01, 0x41, 0xa1, 0x0b, 0x3b, 0x9b,
|
||||
0x7b, 0x91, 0x2a, 0x62, 0x2a, 0x0a, 0x9a, 0x2a, 0xfa, 0x9a, 0xb9, 0x81, 0x79, 0x31, 0x4b, 0x73, 0x0b, 0x63, 0x4b, 0xd9, 0x10, 0x04, 0x13, 0x84, 0xa1, 0x98, 0x20, 0x0c, 0xc6, 0x06, 0x61, 0x20,
|
||||
0x26, 0x08, 0xc3, 0xb1, 0x41, 0x18, 0x0c, 0x0a, 0x63, 0x73, 0x1b, 0x06, 0xc4, 0x20, 0x26, 0x08, 0x93, 0x43, 0x60, 0x82, 0x30, 0x20, 0x13, 0x04, 0xa6, 0x99, 0x20, 0x0c, 0xc9, 0x06, 0x61, 0x70,
|
||||
0x36, 0x2c, 0x84, 0xb2, 0x10, 0xc4, 0xc0, 0x34, 0x4d, 0xf3, 0x6c, 0x08, 0xa0, 0x09, 0xc2, 0xf5, 0x4c, 0x10, 0x06, 0x65, 0x03, 0x42, 0x48, 0x0b, 0x41, 0x0c, 0x13, 0x30, 0x41, 0xc8, 0xa0, 0x0d,
|
||||
0xc8, 0x50, 0x2d, 0x03, 0x31, 0x4c, 0xc0, 0x06, 0x81, 0xb2, 0x36, 0x10, 0x40, 0x74, 0x01, 0x13, 0x04, 0x01, 0x20, 0xd1, 0x16, 0x96, 0xe6, 0x36, 0x41, 0x30, 0x98, 0x09, 0xc2, 0xb0, 0x6c, 0x18,
|
||||
0xb8, 0x61, 0xd8, 0x40, 0x10, 0x9b, 0xd3, 0x6d, 0x28, 0x32, 0x0d, 0xc0, 0xbc, 0x2a, 0x6c, 0x6c, 0x76, 0x6d, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x53, 0x82, 0xa0, 0x0a, 0x19, 0x9e, 0x8b, 0x5d,
|
||||
0x99, 0xdc, 0x5c, 0xda, 0x9b, 0xdb, 0x94, 0x80, 0x68, 0x42, 0x86, 0xe7, 0x62, 0x17, 0xc6, 0x66, 0x57, 0x26, 0x37, 0x25, 0x30, 0xea, 0x90, 0xe1, 0xb9, 0xcc, 0xa1, 0x85, 0x91, 0x95, 0xc9, 0x35,
|
||||
0xbd, 0x91, 0x95, 0xb1, 0x4d, 0x09, 0x90, 0x32, 0x64, 0x78, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x53, 0x82, 0xab, 0x0e, 0x19, 0x9e, 0x4b, 0x99, 0x1b, 0x9d, 0x5c, 0x1e,
|
||||
0xd4, 0x5b, 0x9a, 0x1b, 0xdd, 0xdc, 0x94, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88,
|
||||
0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce,
|
||||
0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48,
|
||||
0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e,
|
||||
0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b,
|
||||
0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78,
|
||||
0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1,
|
||||
0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39,
|
||||
0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc4, 0x21, 0x07, 0x7c, 0x70,
|
||||
0x03, 0x7a, 0x28, 0x87, 0x76, 0x80, 0x87, 0x19, 0xd1, 0x43, 0x0e, 0xf8, 0xe0, 0x06, 0xe4, 0x20, 0x0e, 0xe7, 0xe0, 0x06, 0xf6, 0x10, 0x0e, 0xf2, 0xc0, 0x0e, 0xe1, 0x90, 0x0f, 0xef, 0x50, 0x0f,
|
||||
0xf4, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x46, 0x50, 0x0d, 0x97, 0xef, 0x3c, 0x7e, 0x40, 0x15, 0x05, 0x11, 0xb1, 0x93, 0x13, 0x11, 0x3e, 0x72, 0xdb, 0x26, 0x50,
|
||||
0x0d, 0x97, 0xef, 0x3c, 0xbe, 0x10, 0x50, 0x45, 0x41, 0x44, 0xa5, 0x03, 0x0c, 0x3e, 0xa2, 0xe3, 0x36, 0x20, 0x0d, 0x97, 0xef, 0x3c, 0xbe, 0x10, 0x11, 0xc0, 0x44, 0x84, 0x40, 0x33, 0x2c, 0x84,
|
||||
0x05, 0x48, 0xc3, 0xe5, 0x3b, 0x8f, 0x3f, 0x1d, 0x11, 0x01, 0x0c, 0xe2, 0xe0, 0x23, 0xb7, 0x6d, 0x00, 0x04, 0x03, 0x20, 0x0d, 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00,
|
||||
0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x34, 0x8a, 0x6e, 0x06, 0xa0, 0xe4, 0x0a, 0xa6, 0x14, 0x03, 0x4a, 0x37, 0xa0, 0x14, 0x0a, 0xa4, 0x02, 0x09, 0x2a, 0x10,
|
||||
0x10, 0xa1, 0x02, 0x01, 0x01, 0x21, 0xc8, 0x14, 0x50, 0xc1, 0x14, 0x48, 0x41, 0xd0, 0x29, 0x81, 0x22, 0x00, 0x00, 0x00, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0xd0, 0x7c, 0x8f, 0xc0, 0x71, 0xd5,
|
||||
0x88, 0x41, 0x02, 0x80, 0x20, 0x18, 0x34, 0x60, 0x00, 0x09, 0x5e, 0x67, 0x8d, 0x18, 0x24, 0x00, 0x08, 0x82, 0x41, 0x13, 0x06, 0xd1, 0xe0, 0x79, 0xd7, 0x88, 0x81, 0x01, 0x80, 0x20, 0x18, 0x10,
|
||||
0x64, 0xf0, 0x7c, 0x15, 0x3c, 0x37, 0x62, 0x80, 0x00, 0x20, 0x08, 0x06, 0x4a, 0x19, 0x58, 0x43, 0xc0, 0x95, 0xd0, 0xed, 0x88, 0x01, 0x02, 0x80, 0x20, 0x18, 0x28, 0x67, 0x80, 0x15, 0x81, 0x67,
|
||||
0xc2, 0x07, 0x82, 0x11, 0x03, 0x04, 0x00, 0x41, 0x30, 0x50, 0xd2, 0x40, 0x3b, 0x02, 0x30, 0x28, 0x03, 0xdb, 0x11, 0x03, 0x04, 0x00, 0x41, 0x30, 0x50, 0xd6, 0x80, 0x4b, 0x02, 0x31, 0x18, 0x31,
|
||||
0x40, 0x00, 0x10, 0x04, 0x03, 0x85, 0x0d, 0xba, 0x05, 0x19, 0x83, 0x11, 0x03, 0x04, 0x00, 0x41, 0x30, 0x50, 0xda, 0xc0, 0x63, 0x0e, 0x32, 0x18, 0x31, 0x40, 0x00, 0x10, 0x04, 0x03, 0xc5, 0x0d,
|
||||
0xbe, 0xc6, 0x28, 0x83, 0x11, 0x03, 0x04, 0x00, 0x41, 0x30, 0x50, 0xde, 0x00, 0x0c, 0x9c, 0xc2, 0x0c, 0x8a, 0x58, 0xa0, 0x08, 0x05, 0x8a, 0x48, 0xa0, 0x08, 0x04, 0x8e, 0x18, 0x70, 0xc4, 0x80,
|
||||
0x23, 0x06, 0x1c, 0x31, 0xa0, 0x10, 0x0f, 0x2f, 0x18, 0x50, 0x45, 0x1c, 0x5c, 0x05, 0xc7, 0x96, 0x61, 0x06, 0x57, 0x42, 0xb0, 0x75, 0xb0, 0xc1, 0x95, 0x10, 0x6c, 0x75, 0x7d, 0x70, 0x23, 0x06,
|
||||
0x0d, 0x00, 0x82, 0x60, 0xf0, 0xfc, 0x81, 0x1b, 0x84, 0x41, 0xd0, 0x07, 0x42, 0x1c, 0xc4, 0x41, 0x1c, 0x8c, 0x41, 0x41, 0x66, 0x80, 0x17, 0x0c, 0xa8, 0x80, 0x0d, 0xb4, 0x82, 0x65, 0x6b, 0x4a,
|
||||
0x03, 0xbc, 0x60, 0x40, 0x05, 0x6f, 0xa0, 0x45, 0x04, 0x5b, 0x16, 0x1b, 0xe0, 0x05, 0x03, 0x2a, 0x90, 0x03, 0x2d, 0x22, 0xd8, 0x6a, 0x54, 0x61, 0x47, 0x0c, 0x1a, 0x00, 0x04, 0xc1, 0xe0, 0x61,
|
||||
0x85, 0x3d, 0x70, 0x83, 0x40, 0x15, 0x04, 0x3f, 0xf0, 0x03, 0x3f, 0x80, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
#if 0
|
||||
struct Vec8 { uint16_t4 lo; uint16_t4 hi; };
|
||||
|
||||
cbuffer Cbuf : register(b0)
|
||||
{
|
||||
Vec8 values_root[8];
|
||||
};
|
||||
|
||||
cbuffer Cbuf : register(b0, space1)
|
||||
{
|
||||
Vec8 values_table[8];
|
||||
};
|
||||
|
||||
RWStructuredBuffer<uint> RWBuf : register(u0);
|
||||
|
||||
uint pack4(uint4 v)
|
||||
{
|
||||
return v.x | (v.y << 8) | (v.z << 16) | (v.w << 24);
|
||||
}
|
||||
|
||||
[numthreads(8, 1, 1)]
|
||||
void main(uint thr : SV_DispatchThreadID)
|
||||
{
|
||||
Vec8 v_root = values_root[thr];
|
||||
Vec8 v_table = values_table[thr];
|
||||
uint4 lo = uint4(v_root.lo) + uint4(v_root.hi);
|
||||
uint4 hi = uint4(v_table.lo) + uint4(v_table.hi);
|
||||
RWBuf[2 * thr + 0] = pack4(lo);
|
||||
RWBuf[2 * thr + 1] = pack4(hi);
|
||||
}
|
||||
#endif
|
||||
/* -Tcs_6_2 test.hlsl -Qstrip_reflect -Qstrip_debug -enable-16bit-types */
|
||||
static const BYTE cs_legacy_uint16_code[] =
|
||||
{
|
||||
0x44, 0x58, 0x42, 0x43, 0x4f, 0xae, 0x04, 0x82, 0xc1, 0xba, 0x0a, 0x10, 0xd2, 0xf7, 0x7f, 0xff, 0x9f, 0x91, 0x46, 0xcc, 0x01, 0x00, 0x00, 0x00, 0xac, 0x07, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
|
||||
0x38, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1c, 0x01, 0x00, 0x00, 0x53, 0x46, 0x49, 0x30, 0x08, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x53, 0x47, 0x31, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x4f, 0x53, 0x47, 0x31, 0x08, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x50, 0x53, 0x56, 0x30, 0x90, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x48, 0x41, 0x53, 0x48, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x6d, 0xd7, 0xfd, 0xb1, 0xd3, 0x39, 0xdf, 0x73, 0xd3, 0x6e, 0x62, 0xe5, 0xca, 0x4d, 0x8a, 0x44, 0x58, 0x49, 0x4c,
|
||||
0x88, 0x06, 0x00, 0x00, 0x62, 0x00, 0x05, 0x00, 0xa2, 0x01, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4c, 0x02, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x06, 0x00, 0x00, 0x42, 0x43, 0xc0, 0xde,
|
||||
0x21, 0x0c, 0x00, 0x00, 0x99, 0x01, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39,
|
||||
0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x52, 0x88,
|
||||
0x48, 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0xe4, 0x48, 0x0e, 0x90, 0x91, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x29, 0x46, 0x06,
|
||||
0x51, 0x18, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x1b, 0x8c, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x40, 0x02, 0xa8, 0x0d, 0x84, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x20, 0x6d, 0x30, 0x86, 0xff,
|
||||
0xff, 0xff, 0xff, 0x1f, 0x00, 0x09, 0xa8, 0x00, 0x49, 0x18, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x82, 0x60, 0x42, 0x20, 0x4c, 0x08, 0x06, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00,
|
||||
0x36, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c,
|
||||
0x10, 0x74, 0x23, 0x00, 0x25, 0x00, 0x14, 0xe6, 0x08, 0xc0, 0xa0, 0x0c, 0x63, 0x0c, 0x22, 0x73, 0x04, 0x08, 0x99, 0x7b, 0x86, 0xcb, 0x9f, 0xb0, 0x87, 0x90, 0xfc, 0x10, 0x68, 0x86, 0x85, 0x40,
|
||||
0xc1, 0x29, 0x0b, 0x18, 0x68, 0x8c, 0x31, 0xc6, 0x30, 0x83, 0xd2, 0x1c, 0x01, 0x74, 0xd6, 0x70, 0xf9, 0x13, 0xf6, 0x10, 0x92, 0xcf, 0x6d, 0x54, 0xb1, 0x12, 0x93, 0x8f, 0xd4, 0xba, 0xcf, 0x23,
|
||||
0x64, 0xad, 0xb5, 0xd6, 0x5a, 0xab, 0x10, 0x6c, 0xa0, 0x41, 0x6d, 0x8e, 0x20, 0x28, 0x06, 0x1a, 0x66, 0x8c, 0x47, 0x70, 0x20, 0x60, 0x26, 0x33, 0x18, 0x07, 0x76, 0x08, 0x87, 0x79, 0x98, 0x07,
|
||||
0x37, 0x90, 0x85, 0x5b, 0x98, 0x05, 0x7a, 0x90, 0x87, 0x7a, 0x18, 0x07, 0x7a, 0xa8, 0x07, 0x79, 0x28, 0x07, 0x72, 0x10, 0x85, 0x7a, 0x30, 0x07, 0x73, 0x28, 0x07, 0x79, 0xe0, 0x83, 0x7a, 0x70,
|
||||
0x87, 0x79, 0x48, 0x87, 0x73, 0x70, 0x87, 0x72, 0x20, 0x07, 0x30, 0x48, 0x07, 0x77, 0xa0, 0x07, 0x3f, 0x40, 0xc1, 0xa0, 0x39, 0x8c, 0x40, 0x2c, 0xb7, 0x48, 0x53, 0x44, 0x09, 0x93, 0xff, 0x12,
|
||||
0x02, 0x8f, 0x84, 0x5a, 0x13, 0xc1, 0x1e, 0xc1, 0x05, 0x54, 0x81, 0x82, 0x4b, 0xf8, 0x0c, 0x2e, 0xa0, 0x0a, 0x9f, 0x46, 0xc1, 0x25, 0x3d, 0x47, 0x00, 0x0a, 0x00, 0x00, 0x13, 0x14, 0x72, 0xc0,
|
||||
0x87, 0x74, 0x60, 0x87, 0x36, 0x68, 0x87, 0x79, 0x68, 0x03, 0x72, 0xc0, 0x87, 0x0d, 0xae, 0x50, 0x0e, 0x6d, 0xd0, 0x0e, 0x7a, 0x50, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07,
|
||||
0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x78, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, 0x90,
|
||||
0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xe6,
|
||||
0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xee, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07,
|
||||
0x7a, 0x60, 0x07, 0x74, 0x30, 0xe4, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xc8, 0x43, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x90,
|
||||
0x27, 0x01, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x21, 0x4f, 0x03, 0x04, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x1e, 0x08, 0x08, 0x80, 0x01, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb2, 0x40, 0x0d, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x1a, 0x25, 0x50, 0x04, 0xc5,
|
||||
0x30, 0x02, 0x50, 0x18, 0x85, 0x50, 0x80, 0x02, 0x05, 0x41, 0x6f, 0x04, 0x80, 0x78, 0x81, 0x03, 0x02, 0x22, 0x50, 0x9e, 0x01, 0xa0, 0x3d, 0x03, 0x40, 0x74, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x79, 0x18, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x90, 0x46, 0x02, 0x13, 0x44, 0x35, 0x18, 0x63, 0x0b, 0x73, 0x3b, 0x03, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x03, 0x99,
|
||||
0x71, 0xb9, 0x01, 0x41, 0xa1, 0x0b, 0x3b, 0x9b, 0x7b, 0x91, 0x2a, 0x62, 0x2a, 0x0a, 0x9a, 0x2a, 0xfa, 0x9a, 0xb9, 0x81, 0x79, 0x31, 0x4b, 0x73, 0x0b, 0x63, 0x4b, 0xd9, 0x10, 0x04, 0x13, 0x84,
|
||||
0xa1, 0x98, 0x20, 0x0c, 0xc6, 0x06, 0x61, 0x20, 0x26, 0x08, 0xc3, 0xb1, 0x41, 0x18, 0x0c, 0x0a, 0x63, 0x73, 0x1b, 0x06, 0xc4, 0x20, 0x26, 0x08, 0x03, 0x32, 0x41, 0xa0, 0x22, 0x02, 0x13, 0x84,
|
||||
0x21, 0x99, 0x20, 0x3c, 0xcd, 0x04, 0x61, 0x50, 0x36, 0x08, 0xc3, 0xb3, 0x61, 0x51, 0x16, 0x46, 0x51, 0x86, 0xc6, 0x71, 0x1c, 0x68, 0x43, 0x10, 0x4d, 0x10, 0xb2, 0x67, 0x82, 0x30, 0x2c, 0x1b,
|
||||
0x10, 0x65, 0x62, 0x14, 0x65, 0xa0, 0x80, 0x09, 0xc2, 0x06, 0x6d, 0x40, 0x06, 0x8b, 0x19, 0x94, 0x81, 0x02, 0x36, 0x08, 0xd5, 0xb5, 0x81, 0x00, 0x24, 0x0c, 0x98, 0x20, 0x08, 0x00, 0x89, 0xb6,
|
||||
0xb0, 0x34, 0xb7, 0x09, 0x02, 0xe7, 0x4c, 0x10, 0x06, 0x66, 0xc3, 0xd0, 0x0d, 0xc3, 0x06, 0x42, 0xe1, 0x1e, 0x6f, 0x43, 0xa1, 0x6d, 0x40, 0xf6, 0x55, 0x61, 0x63, 0xb3, 0x6b, 0x73, 0x49, 0x23,
|
||||
0x2b, 0x73, 0xa3, 0x9b, 0x12, 0x04, 0x55, 0xc8, 0xf0, 0x5c, 0xec, 0xca, 0xe4, 0xe6, 0xd2, 0xde, 0xdc, 0xa6, 0x04, 0x44, 0x13, 0x32, 0x3c, 0x17, 0xbb, 0x30, 0x36, 0xbb, 0x32, 0xb9, 0x29, 0x81,
|
||||
0x51, 0x87, 0x0c, 0xcf, 0x65, 0x0e, 0x2d, 0x8c, 0xac, 0x4c, 0xae, 0xe9, 0x8d, 0xac, 0x8c, 0x6d, 0x4a, 0x80, 0x94, 0x21, 0xc3, 0x73, 0x91, 0x2b, 0x9b, 0x7b, 0xab, 0x93, 0x1b, 0x2b, 0x9b, 0x9b,
|
||||
0x12, 0x60, 0x75, 0xc8, 0xf0, 0x5c, 0xca, 0xdc, 0xe8, 0xe4, 0xf2, 0xa0, 0xde, 0xd2, 0xdc, 0xe8, 0xe6, 0xa6, 0x04, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00,
|
||||
0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10,
|
||||
0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03,
|
||||
0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e,
|
||||
0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b,
|
||||
0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90,
|
||||
0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e,
|
||||
0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca,
|
||||
0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82,
|
||||
0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc4, 0x21, 0x07, 0x7c, 0x70, 0x03, 0x7a, 0x28, 0x87, 0x76, 0x80, 0x87, 0x19, 0xd1, 0x43, 0x0e, 0xf8, 0xe0, 0x06, 0xe4, 0x20, 0x0e, 0xe7, 0xe0, 0x06,
|
||||
0xf6, 0x10, 0x0e, 0xf2, 0xc0, 0x0e, 0xe1, 0x90, 0x0f, 0xef, 0x50, 0x0f, 0xf4, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x36, 0xb0, 0x0d, 0x97, 0xef, 0x3c, 0xbe, 0x10,
|
||||
0x50, 0x45, 0x41, 0x44, 0xa5, 0x03, 0x0c, 0x25, 0x61, 0x00, 0x02, 0xe6, 0x23, 0xb5, 0x6e, 0x04, 0xd2, 0x70, 0xf9, 0xce, 0xe3, 0x0b, 0x11, 0x01, 0x4c, 0x44, 0x08, 0x34, 0xc3, 0x42, 0x98, 0x00,
|
||||
0x36, 0x5c, 0xbe, 0xf3, 0xf8, 0x11, 0x60, 0x6d, 0x54, 0x51, 0x10, 0x11, 0x3b, 0x39, 0x11, 0xe1, 0x23, 0xb7, 0x6d, 0x01, 0xd2, 0x70, 0xf9, 0xce, 0xe3, 0x4f, 0x47, 0x44, 0x00, 0x83, 0x38, 0xf8,
|
||||
0xc8, 0x6d, 0x1b, 0x00, 0xc1, 0x00, 0x48, 0x03, 0x61, 0x20, 0x00, 0x00, 0x4e, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x66, 0x00, 0x4a,
|
||||
0xae, 0xec, 0x0a, 0xa4, 0x60, 0x0a, 0x53, 0xa0, 0x74, 0x03, 0xc8, 0x94, 0x40, 0x11, 0x00, 0x00, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x00, 0x5d, 0x88, 0x30, 0x4d, 0xce, 0x88, 0x41, 0x02, 0x80,
|
||||
0x20, 0x18, 0x40, 0x58, 0x22, 0x5c, 0xd4, 0x33, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0x50, 0xa6, 0x0c, 0x55, 0x05, 0x8d, 0x18, 0x18, 0x00, 0x08, 0x82, 0x01, 0xd1, 0x19, 0xd6, 0x88, 0xc1, 0x01,
|
||||
0x80, 0x20, 0x18, 0x34, 0xdc, 0x22, 0x04, 0xa3, 0x09, 0x01, 0x30, 0x9a, 0x20, 0x04, 0xa3, 0x09, 0x83, 0x30, 0x9a, 0x40, 0x0c, 0x47, 0x8c, 0x38, 0x62, 0xc4, 0x11, 0x23, 0x8e, 0x18, 0x31, 0x9a,
|
||||
0x90, 0x10, 0xa3, 0x09, 0x4a, 0x31, 0x9a, 0xb0, 0x18, 0xa3, 0x09, 0xcc, 0x71, 0xc4, 0x88, 0x23, 0x46, 0x1c, 0x31, 0xe2, 0x88, 0x11, 0x46, 0x30, 0x30, 0x30, 0x82, 0x81, 0x81, 0x11, 0x0c, 0x0c,
|
||||
0x8c, 0x60, 0x60, 0x30, 0x62, 0x70, 0x00, 0x20, 0x08, 0x06, 0x4d, 0x1c, 0x80, 0x01, 0x66, 0x8d, 0x26, 0x04, 0xc0, 0x68, 0x82, 0x10, 0x8c, 0x26, 0x0c, 0xc2, 0x68, 0x02, 0x31, 0x1c, 0x31, 0xe2,
|
||||
0x88, 0x11, 0x47, 0x8c, 0x38, 0x62, 0xc4, 0x68, 0x42, 0x42, 0x8c, 0x26, 0x28, 0xc5, 0x68, 0xc2, 0x62, 0x8c, 0x26, 0x30, 0xc7, 0x11, 0x23, 0x8e, 0x18, 0x71, 0xc4, 0x88, 0x23, 0x46, 0x18, 0xc1,
|
||||
0xc0, 0xc0, 0x08, 0x06, 0x06, 0x46, 0x30, 0x30, 0x30, 0x82, 0x81, 0x81, 0x61, 0x7d, 0x70, 0x83, 0x0a, 0xb4, 0xad, 0xcc, 0x0e, 0xae, 0x84, 0x60, 0x4b, 0xbb, 0x83, 0x2b, 0x21, 0xd8, 0x8a, 0x03,
|
||||
0x55, 0xb8, 0x11, 0x03, 0x07, 0x00, 0x41, 0x30, 0x48, 0x5c, 0x21, 0x0f, 0xea, 0x20, 0x40, 0x05, 0xc1, 0x0f, 0xfc, 0xc0, 0x0f, 0xee, 0xc0, 0x14, 0x4c, 0x21, 0x85, 0x1b, 0x54, 0xc0, 0x6c, 0x2d,
|
||||
0x7d, 0x70, 0x25, 0x04, 0x5b, 0x8c, 0x1f, 0x5c, 0x09, 0xc1, 0xd6, 0x11, 0x0b, 0x3b, 0x62, 0xe0, 0x00, 0x20, 0x08, 0x06, 0x49, 0x2d, 0x80, 0x02, 0x1f, 0x04, 0xaf, 0x20, 0x94, 0x42, 0x29, 0x94,
|
||||
0x82, 0x1f, 0xb4, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
static const BYTE cs_modern_uint16_code[] =
|
||||
{
|
||||
0x44, 0x58, 0x42, 0x43, 0x39, 0x52, 0xf1, 0x80, 0x79, 0x9b, 0x59, 0xc4, 0x15, 0xb8, 0x28, 0x20, 0x4a, 0x97, 0x3b, 0x4f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
|
||||
0x38, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1c, 0x01, 0x00, 0x00, 0x53, 0x46, 0x49, 0x30, 0x08, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x53, 0x47, 0x31, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x4f, 0x53, 0x47, 0x31, 0x08, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x50, 0x53, 0x56, 0x30, 0x90, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x48, 0x41, 0x53, 0x48, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x64, 0xa7, 0x4b, 0xfc, 0x17, 0xd7, 0x69, 0x59, 0x79, 0x99, 0x2b, 0x2f, 0x9d, 0x15, 0xb4, 0x44, 0x58, 0x49, 0x4c,
|
||||
0xdc, 0x06, 0x00, 0x00, 0x62, 0x00, 0x05, 0x00, 0xb7, 0x01, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4c, 0x02, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xc4, 0x06, 0x00, 0x00, 0x42, 0x43, 0xc0, 0xde,
|
||||
0x21, 0x0c, 0x00, 0x00, 0xae, 0x01, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39,
|
||||
0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x52, 0x88,
|
||||
0x48, 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0xe4, 0x48, 0x0e, 0x90, 0x91, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x29, 0x46, 0x06,
|
||||
0x51, 0x18, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x1b, 0x8c, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x40, 0x02, 0xa8, 0x0d, 0x84, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x20, 0x6d, 0x30, 0x86, 0xff,
|
||||
0xff, 0xff, 0xff, 0x1f, 0x00, 0x09, 0xa8, 0x00, 0x49, 0x18, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x82, 0x60, 0x42, 0x20, 0x4c, 0x08, 0x06, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00,
|
||||
0x30, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c,
|
||||
0x10, 0x70, 0x23, 0x00, 0x25, 0x00, 0x14, 0xe6, 0x08, 0xc0, 0xa0, 0x0c, 0x63, 0x0c, 0x22, 0x73, 0x04, 0x08, 0x99, 0x7b, 0x86, 0xcb, 0x9f, 0xb0, 0x87, 0x90, 0xfc, 0x10, 0x68, 0x86, 0x85, 0x40,
|
||||
0xc1, 0x29, 0x0b, 0x18, 0x68, 0x8c, 0x31, 0xc6, 0x30, 0x83, 0xd2, 0x1c, 0x01, 0x54, 0x8a, 0x35, 0xd0, 0x18, 0xc4, 0xe6, 0x08, 0x82, 0x62, 0xa0, 0x61, 0xc6, 0x70, 0xf4, 0x06, 0x02, 0x66, 0x32,
|
||||
0x83, 0x71, 0x60, 0x87, 0x70, 0x98, 0x87, 0x79, 0x70, 0x03, 0x59, 0xb8, 0x85, 0x59, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x71, 0xa0, 0x87, 0x7a, 0x90, 0x87, 0x72, 0x20, 0x07, 0x51, 0xa8, 0x07, 0x73,
|
||||
0x30, 0x87, 0x72, 0x90, 0x07, 0x3e, 0xa8, 0x07, 0x77, 0x98, 0x87, 0x74, 0x38, 0x07, 0x77, 0x28, 0x07, 0x72, 0x00, 0x83, 0x74, 0x70, 0x07, 0x7a, 0xf0, 0x03, 0x14, 0x0c, 0x92, 0xc3, 0x08, 0xc4,
|
||||
0x72, 0x8b, 0x34, 0x45, 0x94, 0x30, 0xf9, 0x2f, 0x21, 0xf0, 0x48, 0xa0, 0x34, 0x11, 0xea, 0x11, 0x5c, 0x40, 0x15, 0x28, 0xb0, 0x74, 0xcf, 0xe0, 0x02, 0xaa, 0xf0, 0x69, 0x14, 0x58, 0xca, 0x73,
|
||||
0x04, 0xa0, 0x00, 0x00, 0x13, 0x14, 0x72, 0xc0, 0x87, 0x74, 0x60, 0x87, 0x36, 0x68, 0x87, 0x79, 0x68, 0x03, 0x72, 0xc0, 0x87, 0x0d, 0xae, 0x50, 0x0e, 0x6d, 0xd0, 0x0e, 0x7a, 0x50, 0x0e, 0x6d,
|
||||
0x00, 0x0f, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x78, 0xd0, 0x06, 0xe9, 0x10, 0x07,
|
||||
0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, 0x90, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0e, 0x71, 0x60,
|
||||
0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xe6, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xee, 0x80, 0x07, 0x7a,
|
||||
0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x60, 0x07, 0x74, 0x30, 0xe4, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xc8, 0x43, 0x00, 0x01, 0x10, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x90, 0x27, 0x01, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x21, 0x0f, 0x03, 0x04, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x43, 0x9e, 0x07, 0x08, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb2, 0x40, 0x0d, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47,
|
||||
0xc6, 0x04, 0x43, 0x1a, 0x25, 0x50, 0x04, 0xc5, 0x30, 0x02, 0x50, 0x18, 0x85, 0x50, 0x80, 0x02, 0x05, 0x41, 0x6e, 0x04, 0x80, 0x76, 0x81, 0x03, 0x02, 0x22, 0x10, 0x9e, 0x01, 0x20, 0x3d, 0x03,
|
||||
0x40, 0x73, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x90, 0x46, 0x02, 0x13, 0x44, 0x35, 0x18, 0x63, 0x0b, 0x73, 0x3b, 0x03, 0xb1,
|
||||
0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x03, 0x99, 0x71, 0xb9, 0x01, 0x41, 0xa1, 0x0b, 0x3b, 0x9b, 0x7b, 0x91, 0x2a, 0x62, 0x2a, 0x0a, 0x9a, 0x2a, 0xfa, 0x9a, 0xb9, 0x81, 0x79, 0x31, 0x4b, 0x73,
|
||||
0x0b, 0x63, 0x4b, 0xd9, 0x10, 0x04, 0x13, 0x84, 0xa1, 0x98, 0x20, 0x0c, 0xc6, 0x06, 0x61, 0x20, 0x26, 0x08, 0xc3, 0xb1, 0x41, 0x18, 0x0c, 0x0a, 0x63, 0x73, 0x1b, 0x06, 0xc4, 0x20, 0x26, 0x08,
|
||||
0x03, 0x32, 0x41, 0x98, 0x22, 0x02, 0x13, 0x84, 0x21, 0x99, 0x20, 0x38, 0xcd, 0x04, 0x61, 0x50, 0x36, 0x08, 0xc3, 0xb3, 0x61, 0x51, 0x16, 0x46, 0x51, 0x86, 0xc6, 0x71, 0x1c, 0x68, 0x43, 0x10,
|
||||
0x4d, 0x10, 0xb0, 0x67, 0x82, 0x30, 0x2c, 0x1b, 0x10, 0x65, 0x62, 0x14, 0x65, 0xa0, 0x80, 0x09, 0x82, 0x06, 0x6d, 0x40, 0x06, 0x8b, 0x19, 0x94, 0x81, 0x02, 0x36, 0x08, 0xd5, 0xb5, 0x81, 0x00,
|
||||
0x24, 0x0c, 0x98, 0x20, 0x08, 0x00, 0x89, 0xb6, 0xb0, 0x34, 0xb7, 0x09, 0xc2, 0xe6, 0x4c, 0x10, 0x06, 0x66, 0xc3, 0xd0, 0x0d, 0xc3, 0x06, 0x42, 0xe1, 0x1e, 0x6f, 0x43, 0xa1, 0x6d, 0x40, 0xf6,
|
||||
0x55, 0x61, 0x63, 0xb3, 0x6b, 0x73, 0x49, 0x23, 0x2b, 0x73, 0xa3, 0x9b, 0x12, 0x04, 0x55, 0xc8, 0xf0, 0x5c, 0xec, 0xca, 0xe4, 0xe6, 0xd2, 0xde, 0xdc, 0xa6, 0x04, 0x44, 0x13, 0x32, 0x3c, 0x17,
|
||||
0xbb, 0x30, 0x36, 0xbb, 0x32, 0xb9, 0x29, 0x81, 0x51, 0x87, 0x0c, 0xcf, 0x65, 0x0e, 0x2d, 0x8c, 0xac, 0x4c, 0xae, 0xe9, 0x8d, 0xac, 0x8c, 0x6d, 0x4a, 0x80, 0x94, 0x21, 0xc3, 0x73, 0x91, 0x2b,
|
||||
0x9b, 0x7b, 0xab, 0x93, 0x1b, 0x2b, 0x9b, 0x9b, 0x12, 0x60, 0x75, 0xc8, 0xf0, 0x5c, 0xca, 0xdc, 0xe8, 0xe4, 0xf2, 0xa0, 0xde, 0xd2, 0xdc, 0xe8, 0xe6, 0xa6, 0x04, 0x1f, 0x00, 0x00, 0x00, 0x00,
|
||||
0x79, 0x18, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73,
|
||||
0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b,
|
||||
0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20,
|
||||
0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61,
|
||||
0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87,
|
||||
0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98,
|
||||
0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61,
|
||||
0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b,
|
||||
0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc4, 0x21, 0x07, 0x7c, 0x70, 0x03, 0x7a, 0x28, 0x87, 0x76, 0x80, 0x87, 0x19, 0xd1, 0x43, 0x0e, 0xf8,
|
||||
0xe0, 0x06, 0xe4, 0x20, 0x0e, 0xe7, 0xe0, 0x06, 0xf6, 0x10, 0x0e, 0xf2, 0xc0, 0x0e, 0xe1, 0x90, 0x0f, 0xef, 0x50, 0x0f, 0xf4, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
|
||||
0x36, 0x50, 0x0d, 0x97, 0xef, 0x3c, 0xbe, 0x10, 0x50, 0x45, 0x41, 0x44, 0xa5, 0x03, 0x0c, 0x3e, 0x52, 0xeb, 0x46, 0x20, 0x0d, 0x97, 0xef, 0x3c, 0xbe, 0x10, 0x11, 0xc0, 0x44, 0x84, 0x40, 0x33,
|
||||
0x2c, 0x84, 0x09, 0x60, 0xc3, 0xe5, 0x3b, 0x8f, 0x1f, 0x01, 0xd6, 0x46, 0x15, 0x05, 0x11, 0xb1, 0x93, 0x13, 0x11, 0x3e, 0x72, 0xdb, 0x16, 0x20, 0x0d, 0x97, 0xef, 0x3c, 0xfe, 0x74, 0x44, 0x04,
|
||||
0x30, 0x88, 0x83, 0x8f, 0xdc, 0xb6, 0x01, 0x10, 0x0c, 0x80, 0x34, 0x00, 0x61, 0x20, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
|
||||
0x34, 0x8a, 0x6e, 0x06, 0xa0, 0xe4, 0x0a, 0xa4, 0x60, 0x0a, 0x53, 0xa0, 0x74, 0x03, 0xc8, 0x94, 0x40, 0x11, 0x00, 0x00, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0xf0, 0x5c, 0x87, 0x30, 0x4d, 0xce,
|
||||
0x88, 0x41, 0x02, 0x80, 0x20, 0x18, 0x3c, 0x18, 0x22, 0x5c, 0xd4, 0x33, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0x4f, 0x96, 0x0c, 0x55, 0x05, 0x8d, 0x18, 0x18, 0x00, 0x08, 0x82, 0x01, 0xd1, 0x19,
|
||||
0x56, 0x05, 0xd5, 0x8d, 0x18, 0x20, 0x00, 0x08, 0x82, 0x01, 0xd3, 0x39, 0x43, 0x40, 0x95, 0x70, 0xed, 0x88, 0x01, 0x02, 0x80, 0x20, 0x18, 0x30, 0x1f, 0x54, 0x04, 0x96, 0x09, 0x19, 0x08, 0x46,
|
||||
0x0c, 0x10, 0x00, 0x04, 0xc1, 0x80, 0x09, 0x03, 0xe9, 0x08, 0xb0, 0x32, 0xb8, 0x1d, 0x31, 0x40, 0x00, 0x10, 0x04, 0x03, 0x66, 0x0c, 0xa8, 0x24, 0xd0, 0xee, 0x18, 0x71, 0xc6, 0x88, 0x2b, 0x46,
|
||||
0x1c, 0x31, 0xa2, 0x98, 0x6f, 0x47, 0x0c, 0x10, 0x00, 0x04, 0xc1, 0x80, 0x49, 0x03, 0xed, 0x09, 0xc0, 0xa0, 0x90, 0x31, 0x80, 0x11, 0x03, 0x04, 0x00, 0x41, 0x30, 0x60, 0xd6, 0x80, 0x8b, 0x02,
|
||||
0x31, 0x28, 0x65, 0x0c, 0x60, 0xc4, 0x00, 0x01, 0x40, 0x10, 0x0c, 0x98, 0x36, 0xf0, 0xa6, 0x80, 0x0c, 0xae, 0x18, 0x71, 0xc4, 0x88, 0x1b, 0x46, 0xd8, 0xd0, 0xc0, 0xc0, 0x96, 0x06, 0x06, 0x46,
|
||||
0x34, 0x30, 0x30, 0xa2, 0x81, 0xc1, 0x88, 0x01, 0x02, 0x80, 0x20, 0x18, 0x30, 0x75, 0x60, 0x06, 0x5c, 0xc6, 0x06, 0x23, 0x06, 0x08, 0x00, 0x82, 0x60, 0xc0, 0xd8, 0xc1, 0x19, 0x74, 0x58, 0x1b,
|
||||
0x8c, 0x18, 0x20, 0x00, 0x08, 0x82, 0x01, 0x73, 0x07, 0x68, 0xe0, 0x5d, 0x6e, 0x30, 0x62, 0x80, 0x00, 0x20, 0x08, 0x06, 0x0c, 0x1e, 0xa4, 0xc1, 0x67, 0xbd, 0xc1, 0x11, 0x23, 0x8e, 0x18, 0x71,
|
||||
0xc4, 0x88, 0x23, 0x46, 0x8c, 0x18, 0x20, 0x00, 0x08, 0x82, 0x01, 0xd3, 0x07, 0x6e, 0x40, 0x06, 0x15, 0x1d, 0x8c, 0x18, 0x20, 0x00, 0x08, 0x82, 0x01, 0xe3, 0x07, 0x6f, 0x50, 0x06, 0x54, 0x1d,
|
||||
0x8c, 0x18, 0x20, 0x00, 0x08, 0x82, 0x01, 0xf3, 0x07, 0x70, 0x60, 0x06, 0x93, 0x1d, 0xdc, 0x30, 0xe2, 0x86, 0x11, 0x37, 0x8c, 0xb0, 0x41, 0x81, 0x81, 0x21, 0x0a, 0x0c, 0x8c, 0x50, 0x60, 0x60,
|
||||
0x84, 0x02, 0x03, 0xab, 0xfc, 0xe0, 0x06, 0x15, 0x5c, 0x5b, 0xd6, 0x1d, 0x5c, 0x09, 0xc1, 0xd6, 0x85, 0x07, 0x57, 0x42, 0xb0, 0x25, 0x07, 0xab, 0x70, 0x23, 0x06, 0x0e, 0x00, 0x82, 0x60, 0x90,
|
||||
0xbc, 0x82, 0x1e, 0xd8, 0x41, 0x90, 0x0a, 0x82, 0x1f, 0xf8, 0x81, 0x1f, 0xe0, 0xc1, 0x29, 0x98, 0x52, 0x0a, 0x37, 0xa8, 0x80, 0xd9, 0x5a, 0xfc, 0xe0, 0x4a, 0x08, 0xb6, 0x98, 0x3f, 0xb8, 0x12,
|
||||
0x82, 0xad, 0x43, 0x16, 0x76, 0xc4, 0xc0, 0x01, 0x40, 0x10, 0x0c, 0x12, 0x5b, 0x08, 0x85, 0x3e, 0x08, 0x60, 0x41, 0x28, 0x85, 0x52, 0x28, 0x85, 0x3f, 0x70, 0x05, 0x04, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
#if 0
|
||||
cbuffer Cbuf : register(b0)
|
||||
{
|
||||
uint4 values_root[8];
|
||||
};
|
||||
|
||||
cbuffer Cbuf : register(b0, space1)
|
||||
{
|
||||
uint4 values_table[8];
|
||||
};
|
||||
|
||||
RWStructuredBuffer<uint> RWBuf : register(u0);
|
||||
|
||||
uint pack4(uint4 v)
|
||||
{
|
||||
return v.x | (v.y << 8) | (v.z << 16) | (v.w << 24);
|
||||
}
|
||||
|
||||
[numthreads(8, 1, 1)]
|
||||
void main(uint thr : SV_DispatchThreadID)
|
||||
{
|
||||
uint4 lo = values_root[thr];
|
||||
uint4 hi = values_table[thr];
|
||||
RWBuf[2 * thr + 0] = pack4(lo);
|
||||
RWBuf[2 * thr + 1] = pack4(hi);
|
||||
}
|
||||
#endif
|
||||
static const BYTE cs_modern_uint32_code[] =
|
||||
{
|
||||
0x44, 0x58, 0x42, 0x43, 0xb4, 0xcf, 0x15, 0xbf, 0x17, 0x57, 0xac, 0x4d, 0x2e, 0xda, 0x48, 0x7e, 0xf8, 0x0a, 0x89, 0x23, 0x01, 0x00, 0x00, 0x00, 0x40, 0x07, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
|
||||
0x38, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1c, 0x01, 0x00, 0x00, 0x53, 0x46, 0x49, 0x30, 0x08, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x53, 0x47, 0x31, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x4f, 0x53, 0x47, 0x31, 0x08, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x50, 0x53, 0x56, 0x30, 0x90, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x48, 0x41, 0x53, 0x48, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2b, 0x6b, 0x32, 0xc2, 0xa4, 0xa0, 0xc4, 0xd4, 0xdb, 0xee, 0xb1, 0x4d, 0xa5, 0x0d, 0x3b, 0x44, 0x58, 0x49, 0x4c,
|
||||
0x1c, 0x06, 0x00, 0x00, 0x60, 0x00, 0x05, 0x00, 0x87, 0x01, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4c, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x06, 0x00, 0x00, 0x42, 0x43, 0xc0, 0xde,
|
||||
0x21, 0x0c, 0x00, 0x00, 0x7e, 0x01, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39,
|
||||
0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x52, 0x88,
|
||||
0x48, 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0xe4, 0x48, 0x0e, 0x90, 0x91, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x29, 0x46, 0x06,
|
||||
0x51, 0x18, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x1b, 0x8c, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x40, 0x02, 0xa8, 0x0d, 0x86, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x20, 0x01, 0xd5, 0x06, 0x62,
|
||||
0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x90, 0x00, 0x49, 0x18, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x82, 0x60, 0x42, 0x20, 0x4c, 0x08, 0x06, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00,
|
||||
0x2c, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c,
|
||||
0x10, 0x68, 0x23, 0x00, 0x25, 0x00, 0x14, 0xe6, 0x08, 0xc0, 0xa0, 0x0c, 0x63, 0x0c, 0x22, 0x73, 0x04, 0x08, 0x99, 0x7b, 0x86, 0xcb, 0x9f, 0xb0, 0x87, 0x90, 0xfc, 0x10, 0x68, 0x86, 0x85, 0x40,
|
||||
0xc1, 0x29, 0xc5, 0x18, 0x68, 0x0c, 0x4a, 0x73, 0x04, 0x41, 0x31, 0xd0, 0x30, 0x63, 0x2c, 0x62, 0x45, 0x01, 0x03, 0x8d, 0x31, 0xc6, 0x18, 0x86, 0xdc, 0x40, 0xc0, 0x4c, 0x66, 0x30, 0x0e, 0xec,
|
||||
0x10, 0x0e, 0xf3, 0x30, 0x0f, 0x6e, 0x20, 0x0b, 0xb7, 0x30, 0x0b, 0xf4, 0x20, 0x0f, 0xf5, 0x30, 0x0e, 0xf4, 0x50, 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x20, 0x0a, 0xf5, 0x60, 0x0e, 0xe6, 0x50, 0x0e,
|
||||
0xf2, 0xc0, 0x07, 0xf5, 0xe0, 0x0e, 0xf3, 0x90, 0x0e, 0xe7, 0xe0, 0x0e, 0xe5, 0x40, 0x0e, 0x60, 0x90, 0x0e, 0xee, 0x40, 0x0f, 0x7e, 0x80, 0x82, 0x41, 0x71, 0x18, 0x81, 0x18, 0x12, 0x61, 0x1e,
|
||||
0xc1, 0x05, 0x54, 0x81, 0x02, 0x4a, 0xf5, 0x0c, 0x2e, 0xa0, 0x0a, 0x9f, 0x46, 0x01, 0xa5, 0x3b, 0x47, 0x00, 0x0a, 0x00, 0x13, 0x14, 0x72, 0xc0, 0x87, 0x74, 0x60, 0x87, 0x36, 0x68, 0x87, 0x79,
|
||||
0x68, 0x03, 0x72, 0xc0, 0x87, 0x0d, 0xaf, 0x50, 0x0e, 0x6d, 0xd0, 0x0e, 0x7a, 0x50, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0,
|
||||
0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73,
|
||||
0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07,
|
||||
0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x43, 0x9e,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x3c, 0x04, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x79, 0x12, 0x20, 0x00, 0x04, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xf2, 0x30, 0x40, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xe4, 0x71, 0x80, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
|
||||
0x0b, 0x04, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x1a, 0x25, 0x30, 0x02, 0x50, 0x0c, 0x85, 0x51, 0x08,
|
||||
0x05, 0x28, 0x50, 0x10, 0xb4, 0x46, 0x00, 0x28, 0x17, 0x08, 0xd9, 0x19, 0x00, 0xc2, 0x33, 0x00, 0x24, 0x67, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x90,
|
||||
0x46, 0x02, 0x13, 0x44, 0x35, 0x18, 0x63, 0x0b, 0x73, 0x3b, 0x03, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x03, 0x99, 0x71, 0xb9, 0x01, 0x41, 0xa1, 0x0b, 0x3b, 0x9b, 0x7b, 0x91, 0x2a, 0x62,
|
||||
0x2a, 0x0a, 0x9a, 0x2a, 0xfa, 0x9a, 0xb9, 0x81, 0x79, 0x31, 0x4b, 0x73, 0x0b, 0x63, 0x4b, 0xd9, 0x10, 0x04, 0x13, 0x84, 0xa1, 0x98, 0x20, 0x0c, 0xc6, 0x06, 0x61, 0x20, 0x26, 0x08, 0xc3, 0xb1,
|
||||
0x41, 0x18, 0x0c, 0x0a, 0x63, 0x73, 0x1b, 0x06, 0xc4, 0x20, 0x26, 0x08, 0x12, 0x44, 0x60, 0x82, 0x30, 0x20, 0x13, 0x84, 0x85, 0x99, 0x20, 0x0c, 0xc9, 0x06, 0x61, 0x70, 0x36, 0x2c, 0x84, 0xb2,
|
||||
0x10, 0xc4, 0xc0, 0x34, 0x4d, 0xf3, 0x6c, 0x08, 0xa0, 0x09, 0x82, 0xe5, 0x4c, 0x10, 0x06, 0x65, 0x03, 0x42, 0x48, 0x0b, 0x41, 0x0c, 0x13, 0x30, 0x41, 0xc0, 0x9e, 0x0d, 0xc8, 0x50, 0x2d, 0x03,
|
||||
0x31, 0x4c, 0xc0, 0x06, 0x81, 0xb2, 0x36, 0x10, 0x40, 0x74, 0x01, 0x13, 0x04, 0x01, 0x20, 0xd1, 0x16, 0x96, 0xe6, 0x36, 0x41, 0xc8, 0x9a, 0x09, 0xc2, 0xb0, 0x6c, 0x18, 0xb8, 0x61, 0xd8, 0x40,
|
||||
0x10, 0x9b, 0xd3, 0x6d, 0x28, 0x32, 0x0d, 0xc0, 0xbc, 0x2a, 0x6c, 0x6c, 0x76, 0x6d, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x53, 0x82, 0xa0, 0x0a, 0x19, 0x9e, 0x8b, 0x5d, 0x99, 0xdc, 0x5c, 0xda,
|
||||
0x9b, 0xdb, 0x94, 0x80, 0x68, 0x42, 0x86, 0xe7, 0x62, 0x17, 0xc6, 0x66, 0x57, 0x26, 0x37, 0x25, 0x30, 0xea, 0x90, 0xe1, 0xb9, 0xcc, 0xa1, 0x85, 0x91, 0x95, 0xc9, 0x35, 0xbd, 0x91, 0x95, 0xb1,
|
||||
0x4d, 0x09, 0x90, 0x32, 0x64, 0x78, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x53, 0x82, 0xab, 0x0e, 0x19, 0x9e, 0x4b, 0x99, 0x1b, 0x9d, 0x5c, 0x1e, 0xd4, 0x5b, 0x9a, 0x1b,
|
||||
0xdd, 0xdc, 0x94, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3,
|
||||
0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30,
|
||||
0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07,
|
||||
0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d,
|
||||
0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76,
|
||||
0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87,
|
||||
0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c,
|
||||
0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8,
|
||||
0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc4, 0x21, 0x07, 0x7c, 0x70, 0x03, 0x7a, 0x28, 0x87,
|
||||
0x76, 0x80, 0x87, 0x19, 0xd1, 0x43, 0x0e, 0xf8, 0xe0, 0x06, 0xe4, 0x20, 0x0e, 0xe7, 0xe0, 0x06, 0xf6, 0x10, 0x0e, 0xf2, 0xc0, 0x0e, 0xe1, 0x90, 0x0f, 0xef, 0x50, 0x0f, 0xf4, 0x00, 0x00, 0x00,
|
||||
0x71, 0x20, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x46, 0x50, 0x0d, 0x97, 0xef, 0x3c, 0x7e, 0x40, 0x15, 0x05, 0x11, 0xb1, 0x93, 0x13, 0x11, 0x3e, 0x72, 0xdb, 0x26, 0x50, 0x0d, 0x97, 0xef, 0x3c,
|
||||
0xbe, 0x10, 0x50, 0x45, 0x41, 0x44, 0xa5, 0x03, 0x0c, 0x3e, 0x72, 0xdb, 0x36, 0x20, 0x0d, 0x97, 0xef, 0x3c, 0xbe, 0x10, 0x11, 0xc0, 0x44, 0x84, 0x40, 0x33, 0x2c, 0x84, 0x05, 0x48, 0xc3, 0xe5,
|
||||
0x3b, 0x8f, 0x3f, 0x1d, 0x11, 0x01, 0x0c, 0xe2, 0xe0, 0x23, 0xb7, 0x6d, 0x00, 0x04, 0x03, 0x20, 0x0d, 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c,
|
||||
0x10, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x8a, 0x6e, 0x06, 0xa0, 0xe4, 0x0a, 0xa4, 0x60, 0x4a, 0x31, 0xa0, 0x74, 0x03, 0xc8, 0x94, 0x40, 0x11, 0x00, 0x00, 0x23, 0x06, 0x09, 0x00,
|
||||
0x82, 0x60, 0xc0, 0x5c, 0x87, 0x40, 0x51, 0xce, 0x88, 0x41, 0x02, 0x80, 0x20, 0x18, 0x30, 0x18, 0x22, 0x58, 0xd5, 0x33, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0x4c, 0x96, 0x0c, 0x96, 0x05, 0x8d,
|
||||
0x18, 0x18, 0x00, 0x08, 0x82, 0x01, 0xc1, 0x19, 0x57, 0x05, 0xd5, 0x8d, 0x18, 0x20, 0x00, 0x08, 0x82, 0x41, 0xd2, 0x39, 0x43, 0x40, 0x95, 0x70, 0xed, 0x88, 0x01, 0x02, 0x80, 0x20, 0x18, 0x24,
|
||||
0x1f, 0x54, 0x04, 0x96, 0x09, 0x19, 0x08, 0x46, 0x0c, 0x10, 0x00, 0x04, 0xc1, 0x20, 0x09, 0x03, 0xe9, 0x08, 0xb0, 0x32, 0xb8, 0x1d, 0x31, 0x40, 0x00, 0x10, 0x04, 0x83, 0x64, 0x0c, 0xa8, 0x24,
|
||||
0xd0, 0x46, 0x0c, 0x10, 0x00, 0x04, 0xc1, 0x20, 0x21, 0x83, 0x6a, 0x41, 0xb6, 0x11, 0x03, 0x04, 0x00, 0x41, 0x30, 0x48, 0xca, 0xc0, 0x62, 0x0e, 0x6e, 0xc4, 0x00, 0x01, 0x40, 0x10, 0x0c, 0x12,
|
||||
0x33, 0xb8, 0x1a, 0xa3, 0x1b, 0x31, 0x40, 0x00, 0x10, 0x04, 0x83, 0xe4, 0x0c, 0x30, 0xa7, 0xf0, 0x2a, 0xf9, 0xae, 0x02, 0x66, 0x2b, 0xc1, 0xae, 0x84, 0x60, 0x2b, 0xc9, 0xae, 0x84, 0x60, 0x6b,
|
||||
0x5a, 0x83, 0x1b, 0x31, 0x68, 0x00, 0x10, 0x04, 0x03, 0xa7, 0x0d, 0xb6, 0x2b, 0x58, 0x03, 0xe1, 0xfb, 0xbe, 0xac, 0x14, 0x33, 0xb8, 0x0a, 0x98, 0xad, 0xe5, 0xbb, 0x12, 0x82, 0x2d, 0x06, 0x0c,
|
||||
0xae, 0x84, 0x60, 0xeb, 0x90, 0x83, 0x1d, 0x31, 0x68, 0x00, 0x10, 0x04, 0x03, 0x87, 0x0e, 0xc4, 0xc0, 0x0b, 0xe4, 0x40, 0x30, 0x03, 0x33, 0x30, 0x03, 0x30, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
static const D3D12_SHADER_BYTECODE cs_legacy_uint64 = SHADER_BYTECODE(cs_legacy_uint64_code);
|
||||
static const D3D12_SHADER_BYTECODE cs_modern_uint64 = SHADER_BYTECODE(cs_modern_uint64_code);
|
||||
static const D3D12_SHADER_BYTECODE cs_legacy_uint16 = SHADER_BYTECODE(cs_legacy_uint16_code);
|
||||
/* DXC miscompiles the stride for elements for 16-bit. It thinks elements are 32-bit, but loads 16-bit ;_; */
|
||||
static const D3D12_SHADER_BYTECODE cs_modern_uint16 = SHADER_BYTECODE(cs_modern_uint16_code);
|
||||
static const D3D12_SHADER_BYTECODE cs_modern_uint32 = SHADER_BYTECODE(cs_modern_uint32_code);
|
||||
|
||||
struct test
|
||||
{
|
||||
const D3D12_SHADER_BYTECODE *cs;
|
||||
bool requires_16bit;
|
||||
bool requires_64bit;
|
||||
uint32_t reference[16];
|
||||
};
|
||||
|
||||
static const struct test tests[] =
|
||||
{
|
||||
{ &cs_legacy_uint64, false, true, {
|
||||
0xc080400, 0xe0a0602, 0x1c181410, 0x1e1a1612,
|
||||
0x2c282420, 0x2e2a2622, 0x3c383430, 0x3e3a3632,
|
||||
0x4c484440, 0x4e4a4642, 0x5c585450, 0x5e5a5652,
|
||||
0x6c686460, 0x6e6a6662, 0x7c787470, 0x7e7a7672 }},
|
||||
{ &cs_modern_uint64, false, true, {
|
||||
0xc080400, 0xe0a0602, 0x1c181410, 0x1e1a1612,
|
||||
0x2c282420, 0x2e2a2622, 0x3c383430, 0x3e3a3632,
|
||||
0x4c484440, 0x4e4a4642, 0x5c585450, 0x5e5a5652,
|
||||
0x6c686460, 0x6e6a6662, 0x7c787470, 0x7e7a7672 }},
|
||||
{ &cs_legacy_uint16, true, false, {
|
||||
0x40002, 0x40002, 0xc000a, 0xc000a,
|
||||
0x140012, 0x140012, 0x1c001a, 0x1c001a,
|
||||
0x240022, 0x240022, 0x2c002a, 0x2c002a,
|
||||
0x340032, 0x340032, 0x3c003a, 0x3c003a, }},
|
||||
{ &cs_modern_uint16, true, false, {
|
||||
0x08060402, 0x08060402, 0x100e0c0a, 0x100e0c0a,
|
||||
0x18161412, 0x18161412, 0x201e1c1a, 0x201e1c1a,
|
||||
0x28262422, 0x28262422, 0x302e2c2a, 0x302e2c2a,
|
||||
0x38363432, 0x38363432, 0x403e3c3a, 0x403e3c3a, }},
|
||||
{ &cs_modern_uint32, false, false, {
|
||||
0x03020100, 0x03020100, 0x07060504, 0x07060504,
|
||||
0x0b0a0908, 0x0b0a0908, 0x0f0e0d0c, 0x0f0e0d0c,
|
||||
0x13121110, 0x13121110, 0x17161514, 0x17161514,
|
||||
0x1b1a1918, 0x1b1a1918, 0x1f1e1d1c, 0x1f1e1d1c, }},
|
||||
};
|
||||
|
||||
if (!init_compute_test_context(&context))
|
||||
return;
|
||||
|
||||
if (!context_supports_dxil(&context))
|
||||
{
|
||||
destroy_test_context(&context);
|
||||
skip("DXIL not supported.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(input_buffer); i++)
|
||||
input_buffer[i] = i;
|
||||
|
||||
memset(&rs_desc, 0, sizeof(rs_desc));
|
||||
memset(root_parameters, 0, sizeof(root_parameters));
|
||||
memset(range, 0, sizeof(range));
|
||||
root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
|
||||
root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV;
|
||||
root_parameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
|
||||
root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV;
|
||||
root_parameters[2].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
|
||||
root_parameters[2].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
|
||||
root_parameters[2].DescriptorTable.NumDescriptorRanges = ARRAY_SIZE(range);
|
||||
root_parameters[2].DescriptorTable.pDescriptorRanges = range;
|
||||
range[0].NumDescriptors = 1;
|
||||
range[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_CBV;
|
||||
range[0].RegisterSpace = 1;
|
||||
rs_desc.NumParameters = ARRAY_SIZE(root_parameters);
|
||||
rs_desc.pParameters = root_parameters;
|
||||
|
||||
create_root_signature(context.device, &rs_desc, &context.root_signature);
|
||||
|
||||
support_16bit =
|
||||
SUCCEEDED(ID3D12Device_CheckFeatureSupport(context.device, D3D12_FEATURE_D3D12_OPTIONS4,
|
||||
&features4, sizeof(features4))) &&
|
||||
features4.Native16BitShaderOpsSupported;
|
||||
|
||||
support_64bit =
|
||||
SUCCEEDED(ID3D12Device_CheckFeatureSupport(context.device, D3D12_FEATURE_D3D12_OPTIONS1,
|
||||
&features1, sizeof(features1))) &&
|
||||
features1.Int64ShaderOps;
|
||||
|
||||
heap = create_gpu_descriptor_heap(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1);
|
||||
cbv_buffer = create_upload_buffer(context.device, sizeof(input_buffer), input_buffer);
|
||||
uav_buffer = create_default_buffer(context.device, 256, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS,
|
||||
D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
|
||||
|
||||
cbv_desc.SizeInBytes = sizeof(input_buffer);
|
||||
cbv_desc.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(cbv_buffer);
|
||||
ID3D12Device_CreateConstantBufferView(context.device, &cbv_desc,
|
||||
ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap));
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(tests); i++)
|
||||
{
|
||||
vkd3d_test_set_context("Test %u", i);
|
||||
|
||||
if (tests[i].requires_16bit && !support_16bit)
|
||||
{
|
||||
skip("Test requires 16-bit, but not supported.\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tests[i].requires_64bit && !support_64bit)
|
||||
{
|
||||
skip("Test requires 64-bit, but not supported.\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
pso = create_compute_pipeline_state(context.device, context.root_signature, *tests[i].cs);
|
||||
ok(!!pso, "Failed to create PSO.\n");
|
||||
if (!pso)
|
||||
continue;
|
||||
|
||||
ID3D12GraphicsCommandList_SetComputeRootSignature(context.list, context.root_signature);
|
||||
ID3D12GraphicsCommandList_SetDescriptorHeaps(context.list, 1, &heap);
|
||||
ID3D12GraphicsCommandList_SetPipelineState(context.list, pso);
|
||||
ID3D12GraphicsCommandList_SetComputeRootUnorderedAccessView(context.list, 0,
|
||||
ID3D12Resource_GetGPUVirtualAddress(uav_buffer));
|
||||
ID3D12GraphicsCommandList_SetComputeRootConstantBufferView(context.list, 1,
|
||||
ID3D12Resource_GetGPUVirtualAddress(cbv_buffer));
|
||||
ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(context.list, 2,
|
||||
ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heap));
|
||||
ID3D12GraphicsCommandList_Dispatch(context.list, 1, 1, 1);
|
||||
|
||||
transition_resource_state(context.list, uav_buffer, D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
|
||||
D3D12_RESOURCE_STATE_COPY_SOURCE);
|
||||
get_buffer_readback_with_command_list(uav_buffer, DXGI_FORMAT_R32_UINT, &rb, context.queue, context.list);
|
||||
reset_command_list(context.list, context.allocator);
|
||||
transition_resource_state(context.list, uav_buffer, D3D12_RESOURCE_STATE_COPY_SOURCE,
|
||||
D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
|
||||
ID3D12PipelineState_Release(pso);
|
||||
|
||||
for (j = 0; j < ARRAY_SIZE(tests[i].reference); j++)
|
||||
{
|
||||
uint32_t ref = tests[i].reference[j];
|
||||
uint32_t v = get_readback_uint(&rb, j, 0, 0);
|
||||
ok(v == ref, "Value %u: #%x != #%x\n", j, v, ref);
|
||||
}
|
||||
release_resource_readback(&rb);
|
||||
}
|
||||
vkd3d_test_set_context(NULL);
|
||||
|
||||
ID3D12Resource_Release(cbv_buffer);
|
||||
ID3D12Resource_Release(uav_buffer);
|
||||
ID3D12DescriptorHeap_Release(heap);
|
||||
destroy_test_context(&context);
|
||||
}
|
||||
|
|
|
@ -65,6 +65,16 @@ void test_get_resource_tiling(void)
|
|||
/* Test buffers */
|
||||
{ D3D12_RESOURCE_DIMENSION_BUFFER, DXGI_FORMAT_UNKNOWN, 1024, 1, 1, 1, 1, 1, 0, 65536, 1, 1, D3D12_TILED_RESOURCES_TIER_1 },
|
||||
{ D3D12_RESOURCE_DIMENSION_BUFFER, DXGI_FORMAT_UNKNOWN, 16*65536, 1, 1, 1, 16, 1, 0, 65536, 1, 1, D3D12_TILED_RESOURCES_TIER_1 },
|
||||
/* Test small resource behavior */
|
||||
{ D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8_UNORM, 1, 1, 1, 1, 1, 1, 0, 256, 256, 1, D3D12_TILED_RESOURCES_TIER_1 },
|
||||
{ D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8_UNORM, 2, 2, 1, 2, 1, 2, 0, 256, 256, 1, D3D12_TILED_RESOURCES_TIER_1 },
|
||||
{ D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8_UNORM, 4, 4, 1, 3, 1, 3, 0, 256, 256, 1, D3D12_TILED_RESOURCES_TIER_1 },
|
||||
{ D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8_UNORM, 8, 8, 1, 4, 1, 4, 0, 256, 256, 1, D3D12_TILED_RESOURCES_TIER_1 },
|
||||
{ D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8_UNORM, 16, 16, 1, 5, 1, 5, 0, 256, 256, 1, D3D12_TILED_RESOURCES_TIER_1 },
|
||||
{ D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8_UNORM, 32, 32, 1, 6, 1, 6, 0, 256, 256, 1, D3D12_TILED_RESOURCES_TIER_1 },
|
||||
{ D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8_UNORM, 64, 64, 1, 7, 1, 7, 0, 256, 256, 1, D3D12_TILED_RESOURCES_TIER_1 },
|
||||
{ D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8_UNORM, 128, 128, 1, 8, 1, 8, 0, 256, 256, 1, D3D12_TILED_RESOURCES_TIER_1 },
|
||||
{ D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8_UNORM, 256, 256, 1, 9, 2, 9, 1, 256, 256, 1, D3D12_TILED_RESOURCES_TIER_1 },
|
||||
/* Test various image formats */
|
||||
{ D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8_UNORM, 512, 512, 1, 1, 4, 1, 1, 256, 256, 1, D3D12_TILED_RESOURCES_TIER_1 },
|
||||
{ D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8G8_UNORM, 512, 512, 1, 1, 8, 1, 1, 256, 128, 1, D3D12_TILED_RESOURCES_TIER_1 },
|
||||
|
@ -86,7 +96,7 @@ void test_get_resource_tiling(void)
|
|||
{ D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8G8B8A8_UNORM, 128, 128, 1, 8, 1, 8, 1, 128, 128, 1, D3D12_TILED_RESOURCES_TIER_1 },
|
||||
{ D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8G8B8A8_UNORM, 512, 512, 1, 10, 21, 10, 3, 128, 128, 1, D3D12_TILED_RESOURCES_TIER_1 },
|
||||
{ D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8G8B8A8_UNORM, 512, 512, 4, 3, 84, 12, 3, 128, 128, 1, D3D12_TILED_RESOURCES_TIER_1 },
|
||||
{ D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8G8B8A8_UNORM, 64, 64, 1, 1, 0, 1, 0, 128, 128, 1, D3D12_TILED_RESOURCES_TIER_1 },
|
||||
{ D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8G8B8A8_UNORM, 64, 64, 1, 1, 1, 1, 0, 128, 128, 1, D3D12_TILED_RESOURCES_TIER_1 },
|
||||
/* Test 3D textures */
|
||||
{ D3D12_RESOURCE_DIMENSION_TEXTURE3D, DXGI_FORMAT_R8_UNORM, 64, 64, 64, 1, 4, 1, 1, 64, 32, 32, D3D12_TILED_RESOURCES_TIER_3 },
|
||||
{ D3D12_RESOURCE_DIMENSION_TEXTURE3D, DXGI_FORMAT_R8G8_UNORM, 64, 64, 64, 1, 8, 1, 1, 32, 32, 32, D3D12_TILED_RESOURCES_TIER_3 },
|
||||
|
@ -213,18 +223,10 @@ void test_get_resource_tiling(void)
|
|||
ok((packed_mip_info.NumTilesForPackedMips == 0) == (packed_mip_info.NumPackedMips == 0),
|
||||
"Unexpected packed tile count %u.\n", packed_mip_info.NumTilesForPackedMips);
|
||||
|
||||
if (packed_mip_info.NumStandardMips || !packed_mip_info.NumPackedMips)
|
||||
{
|
||||
ok(tile_shape.WidthInTexels == tests[i].tile_shape_w, "Unexpected tile width %u.\n", tile_shape.WidthInTexels);
|
||||
ok(tile_shape.HeightInTexels == tests[i].tile_shape_h, "Unexpected tile height %u.\n", tile_shape.HeightInTexels);
|
||||
ok(tile_shape.DepthInTexels == tests[i].tile_shape_d, "Unexpected tile depth %u.\n", tile_shape.DepthInTexels);
|
||||
}
|
||||
else
|
||||
{
|
||||
ok(!tile_shape.WidthInTexels && !tile_shape.HeightInTexels && !tile_shape.DepthInTexels,
|
||||
"Unexpected tile shape (%u,%u,%u) for packed resource.\n",
|
||||
tile_shape.WidthInTexels, tile_shape.HeightInTexels, tile_shape.DepthInTexels);
|
||||
}
|
||||
/* Docs say that tile shape should be cleared to zero if there is no standard mip, but drivers don't seem to care about this. */
|
||||
ok(tile_shape.WidthInTexels == tests[i].tile_shape_w, "Unexpected tile width %u.\n", tile_shape.WidthInTexels);
|
||||
ok(tile_shape.HeightInTexels == tests[i].tile_shape_h, "Unexpected tile height %u.\n", tile_shape.HeightInTexels);
|
||||
ok(tile_shape.DepthInTexels == tests[i].tile_shape_d, "Unexpected tile depth %u.\n", tile_shape.DepthInTexels);
|
||||
|
||||
for (j = 0; j < tests[i].expected_tiling_count; j++)
|
||||
{
|
||||
|
@ -3381,3 +3383,248 @@ void test_texture_feedback_instructions_dxil(void)
|
|||
test_texture_feedback_instructions(true);
|
||||
}
|
||||
|
||||
void test_sparse_buffer_memory_lifetime(void)
|
||||
{
|
||||
/* Attempt to bind sparse memory, then free the underlying heap, but keep the sparse resource
|
||||
* alive. This should confuse drivers that attempt to track BO lifetimes. */
|
||||
D3D12_UNORDERED_ACCESS_VIEW_DESC uav_desc;
|
||||
D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc;
|
||||
D3D12_FEATURE_DATA_D3D12_OPTIONS options;
|
||||
const UINT values[] = { 42, 42, 42, 42 };
|
||||
D3D12_ROOT_PARAMETER root_parameters[2];
|
||||
D3D12_TILE_REGION_SIZE region_size;
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE h_gpu;
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE h_cpu;
|
||||
D3D12_ROOT_SIGNATURE_DESC rs_desc;
|
||||
D3D12_DESCRIPTOR_RANGE desc_range;
|
||||
struct test_context context;
|
||||
struct resource_readback rb;
|
||||
ID3D12DescriptorHeap *cpu;
|
||||
ID3D12DescriptorHeap *gpu;
|
||||
D3D12_HEAP_DESC heap_desc;
|
||||
D3D12_RESOURCE_DESC desc;
|
||||
ID3D12Resource *sparse;
|
||||
ID3D12Resource *buffer;
|
||||
ID3D12Heap *heap_live;
|
||||
ID3D12Heap *heap;
|
||||
unsigned int i;
|
||||
HRESULT hr;
|
||||
|
||||
static const DWORD cs_sparse_query_dxbc[] =
|
||||
{
|
||||
#if 0
|
||||
RWStructuredBuffer<uint> RWBuf : register(u0);
|
||||
Buffer<uint> Buf : register(t0);
|
||||
|
||||
[numthreads(1, 1, 1)]
|
||||
void main(uint thr : SV_DispatchThreadID)
|
||||
{
|
||||
uint code;
|
||||
|
||||
// Sample mapped, but freed memory. See what CheckAccessFullyMapped returns.
|
||||
uint data = Buf.Load(thr, code);
|
||||
uint value = CheckAccessFullyMapped(code) ? (1u << 16) : 0u;
|
||||
value |= data & 0xffffu;
|
||||
RWBuf[2 * thr + 0] = value;
|
||||
|
||||
// Sample not yet mapped memory. See what CheckAccessFullyMapped returns.
|
||||
data = Buf.Load(thr + 1024 * 1024, code);
|
||||
value = CheckAccessFullyMapped(code) ? (1u << 16) : 0u;
|
||||
value |= data & 0xffffu;
|
||||
|
||||
RWBuf[2 * thr + 1] = value;
|
||||
}
|
||||
#endif
|
||||
0x43425844, 0x8c2a40af, 0x2a9b20a6, 0xa99f0977, 0x37daacf5, 0x00000001, 0x00000280, 0x00000004,
|
||||
0x00000030, 0x00000040, 0x00000050, 0x00000270, 0x4e475349, 0x00000008, 0x00000000, 0x00000008,
|
||||
0x4e47534f, 0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x00000218, 0x00050050, 0x00000086,
|
||||
0x0100086a, 0x04000858, 0x00107000, 0x00000000, 0x00004444, 0x0400009e, 0x0011e000, 0x00000000,
|
||||
0x00000004, 0x0200005f, 0x00020012, 0x02000068, 0x00000002, 0x0400009b, 0x00000001, 0x00000001,
|
||||
0x00000001, 0x8a0000df, 0x80000042, 0x00111103, 0x00100012, 0x00000000, 0x00100012, 0x00000001,
|
||||
0x00020006, 0x00107e46, 0x00000000, 0x050000ea, 0x00100022, 0x00000000, 0x0010000a, 0x00000001,
|
||||
0x09000037, 0x00100022, 0x00000000, 0x0010001a, 0x00000000, 0x00004001, 0x00010000, 0x00004001,
|
||||
0x00000000, 0x0b00008c, 0x00100012, 0x00000000, 0x00004001, 0x00000010, 0x00004001, 0x00000000,
|
||||
0x0010000a, 0x00000000, 0x0010001a, 0x00000000, 0x06000029, 0x00100022, 0x00000000, 0x0002000a,
|
||||
0x00004001, 0x00000001, 0x090000a8, 0x0011e012, 0x00000000, 0x0010001a, 0x00000000, 0x00004001,
|
||||
0x00000000, 0x0010000a, 0x00000000, 0x1300008c, 0x00100052, 0x00000000, 0x00004002, 0x00000014,
|
||||
0x00000000, 0x0000001f, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
|
||||
0x00020006, 0x00004002, 0x00100000, 0x00000000, 0x00000001, 0x00000000, 0x8b0000df, 0x80000042,
|
||||
0x00111103, 0x00100012, 0x00000000, 0x00100012, 0x00000001, 0x00100006, 0x00000000, 0x00107e46,
|
||||
0x00000000, 0x050000ea, 0x00100082, 0x00000000, 0x0010000a, 0x00000001, 0x09000037, 0x00100082,
|
||||
0x00000000, 0x0010003a, 0x00000000, 0x00004001, 0x00010000, 0x00004001, 0x00000000, 0x0b00008c,
|
||||
0x00100012, 0x00000000, 0x00004001, 0x00000010, 0x00004001, 0x00000000, 0x0010000a, 0x00000000,
|
||||
0x0010003a, 0x00000000, 0x090000a8, 0x0011e012, 0x00000000, 0x0010002a, 0x00000000, 0x00004001,
|
||||
0x00000000, 0x0010000a, 0x00000000, 0x0100003e, 0x30494653, 0x00000008, 0x00000100, 0x00000000,
|
||||
};
|
||||
static const D3D12_SHADER_BYTECODE cs_sparse_query = SHADER_BYTECODE(cs_sparse_query_dxbc);
|
||||
|
||||
if (!init_compute_test_context(&context))
|
||||
return;
|
||||
|
||||
hr = ID3D12Device_CheckFeatureSupport(context.device, D3D12_FEATURE_D3D12_OPTIONS, &options, sizeof(options));
|
||||
ok(hr == S_OK, "Failed to check feature support, hr %#x.\n", hr);
|
||||
|
||||
if (options.TiledResourcesTier < D3D12_TILED_RESOURCES_TIER_2)
|
||||
{
|
||||
skip("Tiled resources Tier 2 not supported by device.\n");
|
||||
destroy_test_context(&context);
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&rs_desc, 0, sizeof(rs_desc));
|
||||
memset(root_parameters, 0, sizeof(root_parameters));
|
||||
memset(&desc_range, 0, sizeof(desc_range));
|
||||
rs_desc.NumParameters = ARRAY_SIZE(root_parameters);
|
||||
rs_desc.pParameters = root_parameters;
|
||||
root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
|
||||
root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV;
|
||||
root_parameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
|
||||
root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
|
||||
root_parameters[1].DescriptorTable.NumDescriptorRanges = 1;
|
||||
root_parameters[1].DescriptorTable.pDescriptorRanges = &desc_range;
|
||||
desc_range.NumDescriptors = 1;
|
||||
desc_range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
|
||||
create_root_signature(context.device, &rs_desc, &context.root_signature);
|
||||
context.pipeline_state = create_compute_pipeline_state(context.device, context.root_signature, cs_sparse_query);
|
||||
|
||||
memset(&heap_desc, 0, sizeof(heap_desc));
|
||||
heap_desc.SizeInBytes = 4 * 1024 * 1024;
|
||||
heap_desc.Properties.Type = D3D12_HEAP_TYPE_DEFAULT;
|
||||
heap_desc.Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
|
||||
heap_desc.Flags = D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS;
|
||||
hr = ID3D12Device_CreateHeap(context.device, &heap_desc, &IID_ID3D12Heap, (void**)&heap);
|
||||
ok(SUCCEEDED(hr), "Failed to create heap, hr #%x.\n", hr);
|
||||
hr = ID3D12Device_CreateHeap(context.device, &heap_desc, &IID_ID3D12Heap, (void**)&heap_live);
|
||||
ok(SUCCEEDED(hr), "Failed to create heap, hr #%x.\n", hr);
|
||||
|
||||
memset(&desc, 0, sizeof(desc));
|
||||
desc.Width = 64 * 1024 * 1024;
|
||||
desc.Height = 1;
|
||||
desc.DepthOrArraySize = 1;
|
||||
desc.SampleDesc.Count = 1;
|
||||
desc.Format = DXGI_FORMAT_UNKNOWN;
|
||||
desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
|
||||
desc.MipLevels = 1;
|
||||
desc.Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
|
||||
desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
|
||||
desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
|
||||
hr = ID3D12Device_CreateReservedResource(context.device, &desc, D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
|
||||
NULL, &IID_ID3D12Resource, (void**)&sparse);
|
||||
ok(SUCCEEDED(hr), "Failed to create reserved resource, hr #%x.\n", hr);
|
||||
|
||||
{
|
||||
const D3D12_TILED_RESOURCE_COORDINATE region_start_coordinate = { 0 };
|
||||
const D3D12_TILE_RANGE_FLAGS range_flag = D3D12_TILE_RANGE_FLAG_NULL;
|
||||
const UINT offset = 0;
|
||||
const UINT count = desc.Width / (64 * 1024);
|
||||
region_size.UseBox = FALSE;
|
||||
region_size.NumTiles = desc.Width / (64 * 1024);
|
||||
ID3D12CommandQueue_UpdateTileMappings(context.queue, sparse, 1, ®ion_start_coordinate, ®ion_size,
|
||||
NULL, 1, &range_flag, &offset, &count, D3D12_TILE_MAPPING_FLAG_NONE);
|
||||
}
|
||||
|
||||
region_size.UseBox = FALSE;
|
||||
region_size.NumTiles = 1;
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
const D3D12_TILED_RESOURCE_COORDINATE region_start_coordinate = { i, 0, 0, 0 };
|
||||
const D3D12_TILE_RANGE_FLAGS range_flag = D3D12_TILE_RANGE_FLAG_NONE;
|
||||
const UINT offset = i;
|
||||
const UINT count = 1;
|
||||
|
||||
ID3D12CommandQueue_UpdateTileMappings(context.queue, sparse, 1, ®ion_start_coordinate, ®ion_size,
|
||||
i == 0 ? heap : heap_live, 1, &range_flag, &offset, &count, D3D12_TILE_MAPPING_FLAG_NONE);
|
||||
}
|
||||
wait_queue_idle(context.device, context.queue);
|
||||
|
||||
buffer = create_default_buffer(context.device, 128 * 1024,
|
||||
D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_DEST);
|
||||
cpu = create_cpu_descriptor_heap(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1);
|
||||
gpu = create_gpu_descriptor_heap(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 2);
|
||||
memset(&uav_desc, 0, sizeof(uav_desc));
|
||||
uav_desc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
|
||||
uav_desc.Format = DXGI_FORMAT_R32_UINT;
|
||||
uav_desc.Buffer.NumElements = 128 * 1024 / 4;
|
||||
uav_desc.Buffer.FirstElement = 0;
|
||||
ID3D12Device_CreateUnorderedAccessView(context.device, sparse, NULL, &uav_desc,
|
||||
ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(cpu));
|
||||
ID3D12Device_CreateUnorderedAccessView(context.device, sparse, NULL, &uav_desc,
|
||||
ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(gpu));
|
||||
|
||||
memset(&srv_desc, 0, sizeof(srv_desc));
|
||||
srv_desc.Buffer.FirstElement = 0;
|
||||
srv_desc.Buffer.NumElements = 2 * 1024 * 1024;
|
||||
srv_desc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER;
|
||||
srv_desc.Format = DXGI_FORMAT_R32_UINT;
|
||||
srv_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
|
||||
|
||||
h_cpu = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(gpu);
|
||||
h_cpu.ptr += ID3D12Device_GetDescriptorHandleIncrementSize(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
|
||||
ID3D12Device_CreateShaderResourceView(context.device, sparse, &srv_desc, h_cpu);
|
||||
|
||||
ID3D12GraphicsCommandList_SetDescriptorHeaps(context.list, 1, &gpu);
|
||||
ID3D12GraphicsCommandList_ClearUnorderedAccessViewUint(context.list,
|
||||
ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(gpu),
|
||||
ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(cpu), sparse, values, 0, NULL);
|
||||
transition_resource_state(context.list, sparse,
|
||||
D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
|
||||
ID3D12GraphicsCommandList_CopyBufferRegion(context.list, buffer, 0, sparse, 0, 128 * 1024);
|
||||
transition_resource_state(context.list, buffer,
|
||||
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_COPY_SOURCE);
|
||||
get_buffer_readback_with_command_list(buffer, DXGI_FORMAT_R32_UINT,
|
||||
&rb, context.queue, context.list);
|
||||
reset_command_list(context.list, context.allocator);
|
||||
ok(get_readback_uint(&rb, 0, 0, 0) == 42, "Got #%x, expected 42.\n", get_readback_uint(&rb, 0, 0, 0));
|
||||
ok(get_readback_uint(&rb, 64 * 1024 / 4, 0, 0) == 42, "Got #%x, expected 42.\n", get_readback_uint(&rb, 64 * 1024 / 4, 0, 0));
|
||||
release_resource_readback(&rb);
|
||||
|
||||
ID3D12Heap_Release(heap);
|
||||
|
||||
/* Access a resource where we can hypothetically access the freed heap memory. */
|
||||
/* On AMD Windows native at least, if we read the freed region, we read garbage, which proves it's not required to unbind explicitly.
|
||||
* We'd read 0 in that case. */
|
||||
ID3D12GraphicsCommandList_CopyBufferRegion(context.list, buffer, 0, sparse, 64 * 1024, 64 * 1024);
|
||||
|
||||
#define EXPLORE_UNDEFINED_BEHAVIOR 0
|
||||
|
||||
#if EXPLORE_UNDEFINED_BEHAVIOR
|
||||
/* This reads unmapped memory. */
|
||||
ID3D12GraphicsCommandList_CopyBufferRegion(context.list, buffer, 1024, sparse, 1024, 1024);
|
||||
#endif
|
||||
|
||||
transition_resource_state(context.list, buffer, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
|
||||
|
||||
h_gpu = ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(gpu);
|
||||
h_gpu.ptr += ID3D12Device_GetDescriptorHandleIncrementSize(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
|
||||
ID3D12GraphicsCommandList_SetDescriptorHeaps(context.list, 1, &gpu);
|
||||
ID3D12GraphicsCommandList_SetComputeRootSignature(context.list, context.root_signature);
|
||||
ID3D12GraphicsCommandList_SetPipelineState(context.list, context.pipeline_state);
|
||||
ID3D12GraphicsCommandList_SetComputeRootUnorderedAccessView(context.list, 0, ID3D12Resource_GetGPUVirtualAddress(buffer));
|
||||
ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(context.list, 1, h_gpu);
|
||||
#if EXPLORE_UNDEFINED_BEHAVIOR
|
||||
ID3D12GraphicsCommandList_Dispatch(context.list, 1, 1, 1);
|
||||
#endif
|
||||
|
||||
transition_resource_state(context.list, buffer, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
|
||||
|
||||
get_buffer_readback_with_command_list(buffer, DXGI_FORMAT_R32_UINT,
|
||||
&rb, context.queue, context.list);
|
||||
|
||||
#if EXPLORE_UNDEFINED_BEHAVIOR
|
||||
skip("Reading undefined value #%x.\n", get_readback_uint(&rb, 0, 0, 0));
|
||||
skip("Reading value #%x (expect 0).\n", get_readback_uint(&rb, 1, 0, 0));
|
||||
skip("Reading undefined value #%x.\n", get_readback_uint(&rb, 1024 / 4, 0, 0));
|
||||
#endif
|
||||
ok(get_readback_uint(&rb, 2048 / 4, 0, 0) == 42, "Got #%x, expected 42.\n", get_readback_uint(&rb, 2048 / 4, 0, 0));
|
||||
ok(get_readback_uint(&rb, 64 * 1024 / 4, 0, 0) == 42, "Got #%x, expected 42.\n", get_readback_uint(&rb, 64 * 1024 / 4, 0, 0));
|
||||
release_resource_readback(&rb);
|
||||
|
||||
ID3D12Resource_Release(buffer);
|
||||
ID3D12Resource_Release(sparse);
|
||||
ID3D12DescriptorHeap_Release(cpu);
|
||||
ID3D12DescriptorHeap_Release(gpu);
|
||||
ID3D12Heap_Release(heap_live);
|
||||
destroy_test_context(&context);
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,159 @@
|
|||
#define VKD3D_DBG_CHANNEL VKD3D_DBG_CHANNEL_API
|
||||
#include "d3d12_crosstest.h"
|
||||
|
||||
void test_primitive_restart_list_topology_stream_output(void)
|
||||
{
|
||||
D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
|
||||
ID3D12Resource *counter_buffer, *so_buffer;
|
||||
ID3D12GraphicsCommandList *command_list;
|
||||
D3D12_STREAM_OUTPUT_BUFFER_VIEW sobv;
|
||||
struct test_context_desc desc;
|
||||
ID3D12Resource *index_buffer;
|
||||
struct resource_readback rb;
|
||||
struct test_context context;
|
||||
D3D12_INDEX_BUFFER_VIEW ibv;
|
||||
ID3D12CommandQueue *queue;
|
||||
const struct vec4 *data;
|
||||
ID3D12Device *device;
|
||||
uint32_t counter;
|
||||
unsigned int i;
|
||||
HRESULT hr;
|
||||
|
||||
static const D3D12_SO_DECLARATION_ENTRY so_declaration[] =
|
||||
{
|
||||
{0, "SV_Position", 0, 0, 4, 0},
|
||||
};
|
||||
static const struct vec4 expected_output[] =
|
||||
{
|
||||
/* Strip */
|
||||
{ 2000.0f, 2000.0f, 2000.0f, 2000.0f },
|
||||
{ 3000.0f, 3000.0f, 3000.0f, 3000.0f },
|
||||
{ 4000.0f, 4000.0f, 4000.0f, 4000.0f },
|
||||
|
||||
/* List */
|
||||
{ 0.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ 1.0f, 1.0f, 1.0f, 1.0f },
|
||||
{ -1.0f, -1.0f, -1.0f, -1.0f },
|
||||
{ 9.0f, 9.0f, 9.0f, 9.0f },
|
||||
{ -1.0f, -1.0f, -1.0f, -1.0f },
|
||||
{ -1.0f, -1.0f, -1.0f, -1.0f },
|
||||
{ 2000.0f, 2000.0f, 2000.0f, 2000.0f },
|
||||
{ 3000.0f, 3000.0f, 3000.0f, 3000.0f },
|
||||
{ 4000.0f, 4000.0f, 4000.0f, 4000.0f },
|
||||
|
||||
/* Strip */
|
||||
{ 2000.0f, 2000.0f, 2000.0f, 2000.0f },
|
||||
{ 3000.0f, 3000.0f, 3000.0f, 3000.0f },
|
||||
{ 4000.0f, 4000.0f, 4000.0f, 4000.0f },
|
||||
};
|
||||
static const uint32_t index_data[] = { 0, 1, UINT32_MAX, 9, UINT32_MAX, UINT32_MAX, 2000, 3000, 4000 };
|
||||
static const UINT strides[] = { 16 };
|
||||
|
||||
static const DWORD vs_code[] =
|
||||
{
|
||||
#if 0
|
||||
float4 main(uint vid : SV_VertexID) : SV_Position
|
||||
{
|
||||
if (vid == ~0u)
|
||||
return float4(-1, -1, -1, -1);
|
||||
else
|
||||
return float4(vid, vid, vid, vid);
|
||||
}
|
||||
#endif
|
||||
0x43425844, 0x59eaaf80, 0xf7ab5160, 0xf0ce6da4, 0x82ce289b, 0x00000001, 0x00000140, 0x00000003,
|
||||
0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
|
||||
0x00000000, 0x00000006, 0x00000001, 0x00000000, 0x00000101, 0x565f5653, 0x65747265, 0x00444978,
|
||||
0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000001, 0x00000003,
|
||||
0x00000000, 0x0000000f, 0x505f5653, 0x7469736f, 0x006e6f69, 0x58454853, 0x000000a4, 0x00010050,
|
||||
0x00000029, 0x0100086a, 0x04000060, 0x00101012, 0x00000000, 0x00000006, 0x04000067, 0x001020f2,
|
||||
0x00000000, 0x00000001, 0x02000068, 0x00000001, 0x07000020, 0x00100012, 0x00000000, 0x0010100a,
|
||||
0x00000000, 0x00004001, 0xffffffff, 0x0304001f, 0x0010000a, 0x00000000, 0x08000036, 0x001020f2,
|
||||
0x00000000, 0x00004002, 0xbf800000, 0xbf800000, 0xbf800000, 0xbf800000, 0x0100003e, 0x01000012,
|
||||
0x05000056, 0x001020f2, 0x00000000, 0x00101006, 0x00000000, 0x0100003e, 0x01000015, 0x0100003e,
|
||||
};
|
||||
|
||||
static const D3D12_SHADER_BYTECODE vs = SHADER_BYTECODE(vs_code);
|
||||
|
||||
memset(&desc, 0, sizeof(desc));
|
||||
desc.root_signature_flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_STREAM_OUTPUT;
|
||||
desc.no_pipeline = true;
|
||||
if (!init_test_context(&context, &desc))
|
||||
return;
|
||||
|
||||
device = context.device;
|
||||
command_list = context.list;
|
||||
queue = context.queue;
|
||||
|
||||
init_pipeline_state_desc(&pso_desc, context.root_signature, 0, &vs, NULL, NULL);
|
||||
pso_desc.StreamOutput.NumEntries = ARRAY_SIZE(so_declaration);
|
||||
pso_desc.StreamOutput.pSODeclaration = so_declaration;
|
||||
pso_desc.StreamOutput.pBufferStrides = strides;
|
||||
pso_desc.StreamOutput.NumStrides = ARRAY_SIZE(strides);
|
||||
pso_desc.StreamOutput.RasterizedStream = D3D12_SO_NO_RASTERIZED_STREAM;
|
||||
pso_desc.IBStripCutValue = D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFFFFFF;
|
||||
hr = ID3D12Device_CreateGraphicsPipelineState(device, &pso_desc,
|
||||
&IID_ID3D12PipelineState, (void **)&context.pipeline_state);
|
||||
ok(SUCCEEDED(hr), "Failed to create PSO, hr #%x.\n", hr);
|
||||
|
||||
counter_buffer = create_default_buffer(device, 32,
|
||||
D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_STREAM_OUT);
|
||||
so_buffer = create_default_buffer(device, 4096,
|
||||
D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_STREAM_OUT);
|
||||
index_buffer = create_upload_buffer(device, sizeof(index_data), index_data);
|
||||
sobv.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(so_buffer);
|
||||
sobv.SizeInBytes = 4096;
|
||||
sobv.BufferFilledSizeLocation = ID3D12Resource_GetGPUVirtualAddress(counter_buffer);
|
||||
|
||||
ibv.Format = DXGI_FORMAT_R32_UINT;
|
||||
ibv.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(index_buffer);
|
||||
ibv.SizeInBytes = sizeof(index_data);
|
||||
|
||||
ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
|
||||
ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
|
||||
ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
|
||||
ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
|
||||
ID3D12GraphicsCommandList_SOSetTargets(command_list, 0, 1, &sobv);
|
||||
ID3D12GraphicsCommandList_IASetIndexBuffer(command_list, &ibv);
|
||||
|
||||
/* Primitive restart state only applies to strip primitives. */
|
||||
ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||
ID3D12GraphicsCommandList_DrawIndexedInstanced(command_list, ARRAY_SIZE(index_data), 1,
|
||||
0, 0, 0);
|
||||
ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
ID3D12GraphicsCommandList_DrawIndexedInstanced(command_list, ARRAY_SIZE(index_data), 1,
|
||||
0, 0, 0);
|
||||
ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||
ID3D12GraphicsCommandList_DrawIndexedInstanced(command_list, ARRAY_SIZE(index_data), 1,
|
||||
0, 0, 0);
|
||||
|
||||
transition_resource_state(command_list, counter_buffer,
|
||||
D3D12_RESOURCE_STATE_STREAM_OUT, D3D12_RESOURCE_STATE_COPY_SOURCE);
|
||||
transition_resource_state(command_list, so_buffer,
|
||||
D3D12_RESOURCE_STATE_STREAM_OUT, D3D12_RESOURCE_STATE_COPY_SOURCE);
|
||||
|
||||
get_buffer_readback_with_command_list(counter_buffer, DXGI_FORMAT_R32_UINT, &rb, queue, command_list);
|
||||
counter = get_readback_uint(&rb, 0, 0, 0);
|
||||
ok(counter == sizeof(expected_output), "Got unexpected counter %u, expected %u.\n",
|
||||
counter, (unsigned int)sizeof(expected_output));
|
||||
release_resource_readback(&rb);
|
||||
reset_command_list(command_list, context.allocator);
|
||||
get_buffer_readback_with_command_list(so_buffer, DXGI_FORMAT_UNKNOWN, &rb, queue, command_list);
|
||||
for (i = 0; i < ARRAY_SIZE(expected_output); ++i)
|
||||
{
|
||||
const struct vec4 *expected = &expected_output[i];
|
||||
data = get_readback_vec4(&rb, i, 0);
|
||||
ok(compare_vec4(data, expected, 1),
|
||||
"Got {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
|
||||
data->x, data->y, data->z, data->w, expected->x, expected->y, expected->z, expected->w);
|
||||
}
|
||||
release_resource_readback(&rb);
|
||||
|
||||
ID3D12Resource_Release(index_buffer);
|
||||
ID3D12Resource_Release(counter_buffer);
|
||||
ID3D12Resource_Release(so_buffer);
|
||||
destroy_test_context(&context);
|
||||
}
|
||||
|
||||
static void test_vertex_shader_stream_output(bool use_dxil)
|
||||
{
|
||||
D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
|
||||
|
|
|
@ -1187,3 +1187,247 @@ void test_create_fence(void)
|
|||
ok(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount);
|
||||
}
|
||||
|
||||
void test_fence_wait_robustness_inner(bool shared_handles)
|
||||
{
|
||||
VKD3D_UNUSED HANDLE shared_signal = NULL;
|
||||
VKD3D_UNUSED HANDLE shared_drain = NULL;
|
||||
VKD3D_UNUSED HANDLE shared_wait = NULL;
|
||||
ID3D12CommandAllocator *allocator[2];
|
||||
ID3D12Fence *signal_fence_dup = NULL;
|
||||
D3D12_COMMAND_QUEUE_DESC queue_desc;
|
||||
ID3D12Fence *drain_fence_dup = NULL;
|
||||
ID3D12Fence *wait_fence_dup = NULL;
|
||||
ID3D12GraphicsCommandList *list[2];
|
||||
ID3D12CommandQueue *compute_queue;
|
||||
struct test_context context;
|
||||
ID3D12Fence *signal_fence;
|
||||
ID3D12Fence *drain_fence;
|
||||
ID3D12Fence *wait_fence;
|
||||
ID3D12Resource *src;
|
||||
ID3D12Resource *dst;
|
||||
unsigned int i;
|
||||
HANDLE event;
|
||||
UINT value;
|
||||
HRESULT hr;
|
||||
|
||||
if (!init_compute_test_context(&context))
|
||||
return;
|
||||
|
||||
hr = ID3D12Device_CreateFence(context.device, 0,
|
||||
shared_handles ? D3D12_FENCE_FLAG_SHARED : D3D12_FENCE_FLAG_NONE,
|
||||
&IID_ID3D12Fence, (void**)&signal_fence);
|
||||
todo_if(shared_handles) ok(SUCCEEDED(hr), "Failed to create fence, hr #%x.\n", hr);
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
skip("Failed to create fence, skipping test ...\n");
|
||||
destroy_test_context(&context);
|
||||
return;
|
||||
}
|
||||
|
||||
hr = ID3D12Device_CreateFence(context.device, 0,
|
||||
shared_handles ? D3D12_FENCE_FLAG_SHARED : D3D12_FENCE_FLAG_NONE,
|
||||
&IID_ID3D12Fence, (void**)&wait_fence);
|
||||
ok(SUCCEEDED(hr), "Failed to create fence, hr #%x.\n", hr);
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
skip("Failed to create fence, skipping test ...\n");
|
||||
ID3D12Fence_Release(signal_fence);
|
||||
destroy_test_context(&context);
|
||||
return;
|
||||
}
|
||||
|
||||
hr = ID3D12Device_CreateFence(context.device, 0,
|
||||
shared_handles ? D3D12_FENCE_FLAG_SHARED : D3D12_FENCE_FLAG_NONE,
|
||||
&IID_ID3D12Fence, (void**)&drain_fence);
|
||||
ok(SUCCEEDED(hr), "Failed to create fence, hr #%x.\n", hr);
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
skip("Failed to create fence, skipping test ...\n");
|
||||
ID3D12Fence_Release(signal_fence);
|
||||
ID3D12Fence_Release(wait_fence);
|
||||
destroy_test_context(&context);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
if (shared_handles)
|
||||
{
|
||||
hr = ID3D12Device_CreateSharedHandle(context.device, (ID3D12DeviceChild*)signal_fence,
|
||||
NULL, GENERIC_ALL, NULL, &shared_signal);
|
||||
ok(SUCCEEDED(hr), "Failed to create shared handle, hr #%x.\n", hr);
|
||||
hr = ID3D12Device_CreateSharedHandle(context.device, (ID3D12DeviceChild*)wait_fence,
|
||||
NULL, GENERIC_ALL, NULL, &shared_wait);
|
||||
ok(SUCCEEDED(hr), "Failed to create shared handle, hr #%x.\n", hr);
|
||||
hr = ID3D12Device_CreateSharedHandle(context.device, (ID3D12DeviceChild*)drain_fence,
|
||||
NULL, GENERIC_ALL, NULL, &shared_drain);
|
||||
ok(SUCCEEDED(hr), "Failed to create shared handle, hr #%x.\n", hr);
|
||||
|
||||
ID3D12Fence_Release(signal_fence);
|
||||
ID3D12Fence_Release(wait_fence);
|
||||
ID3D12Fence_Release(drain_fence);
|
||||
|
||||
hr = ID3D12Device_OpenSharedHandle(context.device, shared_signal, &IID_ID3D12Fence, (void**)&signal_fence);
|
||||
ok(SUCCEEDED(hr), "Failed to open shared handle, hr #%x.\n", hr);
|
||||
hr = ID3D12Device_OpenSharedHandle(context.device, shared_wait, &IID_ID3D12Fence, (void**)&wait_fence);
|
||||
ok(SUCCEEDED(hr), "Failed to open shared handle, hr #%x.\n", hr);
|
||||
hr = ID3D12Device_OpenSharedHandle(context.device, shared_drain, &IID_ID3D12Fence, (void**)&drain_fence);
|
||||
ok(SUCCEEDED(hr), "Failed to open shared handle, hr #%x.\n", hr);
|
||||
|
||||
/* OpenSharedHandle takes a kernel level reference on the HANDLE. */
|
||||
hr = ID3D12Device_OpenSharedHandle(context.device, shared_signal, &IID_ID3D12Fence, (void**)&signal_fence_dup);
|
||||
ok(SUCCEEDED(hr), "Failed to open shared handle, hr #%x.\n", hr);
|
||||
hr = ID3D12Device_OpenSharedHandle(context.device, shared_wait, &IID_ID3D12Fence, (void**)&wait_fence_dup);
|
||||
ok(SUCCEEDED(hr), "Failed to open shared handle, hr #%x.\n", hr);
|
||||
hr = ID3D12Device_OpenSharedHandle(context.device, shared_drain, &IID_ID3D12Fence, (void**)&drain_fence_dup);
|
||||
ok(SUCCEEDED(hr), "Failed to open shared handle, hr #%x.\n", hr);
|
||||
|
||||
/* Observed behavior: Closing the last reference to the kernel HANDLE object unblocks all waiters.
|
||||
* This isn't really implementable in Wine as it stands since applications are free to share
|
||||
* the HANDLE and Dupe it arbitrarily.
|
||||
* For now, assume this is not a thing, we can report TDR-like situations if this comes up in practice. */
|
||||
if (shared_signal)
|
||||
CloseHandle(shared_signal);
|
||||
if (shared_wait)
|
||||
CloseHandle(shared_wait);
|
||||
if (shared_drain)
|
||||
CloseHandle(shared_drain);
|
||||
}
|
||||
#endif
|
||||
|
||||
memset(&queue_desc, 0, sizeof(queue_desc));
|
||||
queue_desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
|
||||
queue_desc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL;
|
||||
queue_desc.Type = D3D12_COMMAND_LIST_TYPE_COMPUTE;
|
||||
|
||||
src = create_default_buffer(context.device, 256 * 1024 * 1024, D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COPY_SOURCE);
|
||||
dst = create_default_buffer(context.device, 256 * 1024 * 1024, D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COPY_DEST);
|
||||
|
||||
ID3D12Device_CreateCommandQueue(context.device, &queue_desc, &IID_ID3D12CommandQueue, (void**)&compute_queue);
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
ID3D12Device_CreateCommandAllocator(context.device, D3D12_COMMAND_LIST_TYPE_COMPUTE,
|
||||
&IID_ID3D12CommandAllocator, (void**)&allocator[i]);
|
||||
ID3D12Device_CreateCommandList(context.device, 0, D3D12_COMMAND_LIST_TYPE_COMPUTE, allocator[i], NULL,
|
||||
&IID_ID3D12GraphicsCommandList, (void**)&list[i]);
|
||||
}
|
||||
|
||||
/* Heavy copy action. */
|
||||
for (i = 0; i < 128; i++)
|
||||
{
|
||||
ID3D12GraphicsCommandList_CopyResource(list[0], dst, src);
|
||||
ID3D12GraphicsCommandList_CopyResource(list[1], src, dst);
|
||||
}
|
||||
|
||||
ID3D12GraphicsCommandList_Close(list[0]);
|
||||
ID3D12GraphicsCommandList_Close(list[1]);
|
||||
|
||||
/* Note on ref-count checks: The debug layers can take transient public ref-counts it seems. */
|
||||
|
||||
ID3D12CommandQueue_ExecuteCommandLists(context.queue, 1, (ID3D12CommandList * const *)&list[0]);
|
||||
ID3D12CommandQueue_Signal(context.queue, signal_fence, 1);
|
||||
/* Validate that signal/wait does not take public ref-counts. */
|
||||
value = get_refcount(signal_fence);
|
||||
ok(value == 1, "Unexpected ref-count %u\n", value);
|
||||
|
||||
/* The GPU copy is 32 GB worth of BW. There is literally zero chance it would have completed in this amount of time. */
|
||||
value = (UINT)ID3D12Fence_GetCompletedValue(signal_fence);
|
||||
ok(value == 0, "Unexpected signal event %u.\n", value);
|
||||
|
||||
/* Try waiting for a signal that never comes. We'll be able to unblock this wait
|
||||
* when we fully release the fence. */
|
||||
ID3D12CommandQueue_Wait(compute_queue, signal_fence, UINT64_MAX);
|
||||
value = get_refcount(signal_fence);
|
||||
ok(value == 1, "Unexpected ref-count %u\n", value);
|
||||
|
||||
ID3D12CommandQueue_Signal(compute_queue, wait_fence, 1);
|
||||
value = get_refcount(wait_fence);
|
||||
ok(value == 1, "Unexpected ref-count %u\n", value);
|
||||
|
||||
/* The GPU copy is 32 GB worth of BW. There is literally zero chance it would have completed in this amount of time. */
|
||||
value = (UINT)ID3D12Fence_GetCompletedValue(wait_fence);
|
||||
ok(value == 0, "Unexpected signal event %u.\n", value);
|
||||
value = (UINT)ID3D12Fence_GetCompletedValue(signal_fence);
|
||||
ok(value == 0, "Unexpected signal event %u.\n", value);
|
||||
|
||||
ID3D12CommandQueue_Wait(compute_queue, wait_fence, 1);
|
||||
value = get_refcount(wait_fence);
|
||||
ok(value == 1, "Unexpected ref-count %u\n", value);
|
||||
|
||||
/* Check that we can queue up event completion.
|
||||
* Again, verify that releasing the fence unblocks all waiters ... */
|
||||
event = create_event();
|
||||
ID3D12Fence_SetEventOnCompletion(signal_fence, UINT64_MAX, event);
|
||||
|
||||
if (signal_fence_dup)
|
||||
ID3D12Fence_Release(signal_fence_dup);
|
||||
if (wait_fence_dup)
|
||||
ID3D12Fence_Release(wait_fence_dup);
|
||||
|
||||
/* The GPU copy is 32 GB worth of BW. There is literally zero chance it would have completed in this amount of time.
|
||||
* Makes sure that the fences aren't signalled when we try to free them.
|
||||
* (Sure, there is a theoretical race condition if GPU completes between this check and the release, but seriously ...). */
|
||||
value = (UINT)ID3D12Fence_GetCompletedValue(signal_fence);
|
||||
ok(value == 0, "Unexpected signal event %u.\n", value);
|
||||
value = (UINT)ID3D12Fence_GetCompletedValue(wait_fence);
|
||||
ok(value == 0, "Unexpected signal event %u.\n", value);
|
||||
|
||||
/* Test that it's valid to release fence while it's in flight.
|
||||
* If we don't cause device lost and drain_fence is waited on successfully we pass the test. */
|
||||
value = ID3D12Fence_Release(signal_fence);
|
||||
ok(value == 0, "Unexpected fence ref-count %u.\n", value);
|
||||
value = ID3D12Fence_Release(wait_fence);
|
||||
ok(value == 0, "Unexpected fence ref-count %u.\n", value);
|
||||
|
||||
ID3D12CommandQueue_ExecuteCommandLists(compute_queue, 1, (ID3D12CommandList * const *)&list[1]);
|
||||
ID3D12CommandQueue_Signal(compute_queue, drain_fence, 1);
|
||||
|
||||
wait_event(event, INFINITE);
|
||||
destroy_event(event);
|
||||
ID3D12Fence_SetEventOnCompletion(drain_fence, 1, NULL);
|
||||
value = (UINT)ID3D12Fence_GetCompletedValue(drain_fence);
|
||||
ok(value == 1, "Expected fence wait value 1, but got %u.\n", value);
|
||||
|
||||
if (drain_fence_dup)
|
||||
{
|
||||
/* Check we observe the counter in sibling fences as well. */
|
||||
value = (UINT)ID3D12Fence_GetCompletedValue(drain_fence_dup);
|
||||
ok(value == 1, "Expected fence wait value 1, but got %u.\n", value);
|
||||
ID3D12Fence_Release(drain_fence_dup);
|
||||
}
|
||||
|
||||
value = ID3D12Fence_Release(drain_fence);
|
||||
ok(value == 0, "Unexpected fence ref-count %u.\n", value);
|
||||
|
||||
/* Early freeing of fences might signal the drain fence too early, causing GPU hang. */
|
||||
wait_queue_idle(context.device, context.queue);
|
||||
wait_queue_idle(context.device, compute_queue);
|
||||
|
||||
ID3D12CommandQueue_Release(compute_queue);
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
ID3D12CommandAllocator_Release(allocator[i]);
|
||||
ID3D12GraphicsCommandList_Release(list[i]);
|
||||
}
|
||||
ID3D12Resource_Release(dst);
|
||||
ID3D12Resource_Release(src);
|
||||
|
||||
destroy_test_context(&context);
|
||||
}
|
||||
|
||||
void test_fence_wait_robustness(void)
|
||||
{
|
||||
test_fence_wait_robustness_inner(false);
|
||||
}
|
||||
|
||||
void test_fence_wait_robustness_shared(void)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
test_fence_wait_robustness_inner(true);
|
||||
#else
|
||||
skip("Shared fences not supported on native Linux build.\n");
|
||||
#endif
|
||||
}
|
|
@ -27,6 +27,10 @@ PFN_D3D12_GET_DEBUG_INTERFACE pfn_D3D12GetDebugInterface;
|
|||
const char *vkd3d_test_platform = "other";
|
||||
struct vkd3d_test_state_context vkd3d_test_state;
|
||||
|
||||
#ifdef _WIN32
|
||||
RENDERDOC_API_1_0_0 *renderdoc_api;
|
||||
#endif
|
||||
|
||||
bool compare_float(float f, float g, int ulps)
|
||||
{
|
||||
int x, y;
|
||||
|
@ -842,6 +846,9 @@ ID3D12CommandSignature *create_command_signature_(unsigned int line,
|
|||
case D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH:
|
||||
signature_desc.ByteStride = sizeof(D3D12_DISPATCH_ARGUMENTS);
|
||||
break;
|
||||
case D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH_RAYS:
|
||||
signature_desc.ByteStride = sizeof(D3D12_DISPATCH_RAYS_DESC);
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
@ -858,6 +865,7 @@ ID3D12CommandSignature *create_command_signature_(unsigned int line,
|
|||
|
||||
bool init_compute_test_context_(unsigned int line, struct test_context *context)
|
||||
{
|
||||
D3D12_COMMAND_LIST_TYPE command_list_type = D3D12_COMMAND_LIST_TYPE_COMPUTE;
|
||||
ID3D12Device *device;
|
||||
HRESULT hr;
|
||||
|
||||
|
@ -870,14 +878,21 @@ bool init_compute_test_context_(unsigned int line, struct test_context *context)
|
|||
}
|
||||
device = context->device;
|
||||
|
||||
context->queue = create_command_queue_(line, device,
|
||||
D3D12_COMMAND_LIST_TYPE_COMPUTE, D3D12_COMMAND_QUEUE_PRIORITY_NORMAL);
|
||||
#ifdef _WIN32
|
||||
begin_renderdoc_capturing(device);
|
||||
/* Workaround RenderDoc bug. It expects a DIRECT command queue to exist. */
|
||||
if (renderdoc_api)
|
||||
command_list_type = D3D12_COMMAND_LIST_TYPE_DIRECT;
|
||||
#endif
|
||||
|
||||
hr = ID3D12Device_CreateCommandAllocator(device, D3D12_COMMAND_LIST_TYPE_COMPUTE,
|
||||
context->queue = create_command_queue_(line, device,
|
||||
command_list_type, D3D12_COMMAND_QUEUE_PRIORITY_NORMAL);
|
||||
|
||||
hr = ID3D12Device_CreateCommandAllocator(device, command_list_type,
|
||||
&IID_ID3D12CommandAllocator, (void **)&context->allocator);
|
||||
ok_(line)(hr == S_OK, "Failed to create command allocator, hr %#x.\n", hr);
|
||||
|
||||
hr = ID3D12Device_CreateCommandList(device, 0, D3D12_COMMAND_LIST_TYPE_COMPUTE,
|
||||
hr = ID3D12Device_CreateCommandList(device, 0, command_list_type,
|
||||
context->allocator, NULL, &IID_ID3D12GraphicsCommandList, (void **)&context->list);
|
||||
ok_(line)(hr == S_OK, "Failed to create command list, hr %#x.\n", hr);
|
||||
|
||||
|
|
|
@ -19,6 +19,10 @@
|
|||
#ifndef __VKD3D_D3D12_TEST_UTILS_H
|
||||
#define __VKD3D_D3D12_TEST_UTILS_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "renderdoc_app.h"
|
||||
#endif
|
||||
|
||||
#define SHADER_BYTECODE(code) {code,sizeof(code)}
|
||||
|
||||
#define wait_queue_idle(a, b) wait_queue_idle_(__LINE__, a, b)
|
||||
|
@ -1049,6 +1053,45 @@ static inline void create_render_target_(unsigned int line, struct test_context
|
|||
ID3D12Device_CreateRenderTargetView(context->device, *render_target, NULL, *rtv);
|
||||
}
|
||||
|
||||
/* Utility code for capturing native D3D12 tests, which is why this only covers Win32.
|
||||
* Launch the d3d12.exe test binary from RenderDoc UI.
|
||||
* For Vulkan capturing, use VKD3D_AUTO_CAPTURE_COUNTS and friends instead. */
|
||||
#ifdef _WIN32
|
||||
extern RENDERDOC_API_1_0_0 *renderdoc_api;
|
||||
|
||||
static inline void begin_renderdoc_capturing(ID3D12Device *device)
|
||||
{
|
||||
pRENDERDOC_GetAPI get_api;
|
||||
HANDLE renderdoc;
|
||||
FARPROC fn_ptr;
|
||||
|
||||
if (!renderdoc_api)
|
||||
{
|
||||
renderdoc = GetModuleHandleA("renderdoc.dll");
|
||||
if (renderdoc)
|
||||
{
|
||||
fn_ptr = GetProcAddress(renderdoc, "RENDERDOC_GetAPI");
|
||||
if (fn_ptr)
|
||||
{
|
||||
/* Workaround compiler warnings about casting to function pointer. */
|
||||
memcpy(&get_api, &fn_ptr, sizeof(fn_ptr));
|
||||
if (!get_api(eRENDERDOC_API_Version_1_0_0, (void **)&renderdoc_api))
|
||||
renderdoc_api = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (renderdoc_api)
|
||||
renderdoc_api->StartFrameCapture(device, NULL);
|
||||
}
|
||||
|
||||
static inline void end_renderdoc_capturing(ID3D12Device *device)
|
||||
{
|
||||
if (renderdoc_api)
|
||||
renderdoc_api->EndFrameCapture(device, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
#define init_test_context(context, desc) init_test_context_(__LINE__, context, desc)
|
||||
static inline bool init_test_context_(unsigned int line, struct test_context *context,
|
||||
const struct test_context_desc *desc)
|
||||
|
@ -1066,6 +1109,10 @@ static inline bool init_test_context_(unsigned int line, struct test_context *co
|
|||
}
|
||||
device = context->device;
|
||||
|
||||
#ifdef _WIN32
|
||||
begin_renderdoc_capturing(device);
|
||||
#endif
|
||||
|
||||
context->queue = create_command_queue_(line, device, D3D12_COMMAND_LIST_TYPE_DIRECT, D3D12_COMMAND_QUEUE_PRIORITY_NORMAL);
|
||||
|
||||
hr = ID3D12Device_CreateCommandAllocator(device, D3D12_COMMAND_LIST_TYPE_DIRECT,
|
||||
|
@ -1117,6 +1164,10 @@ static inline void destroy_test_context_(unsigned int line, struct test_context
|
|||
{
|
||||
ULONG refcount;
|
||||
|
||||
#ifdef _WIN32
|
||||
end_renderdoc_capturing(context->device);
|
||||
#endif
|
||||
|
||||
if (context->pipeline_state)
|
||||
ID3D12PipelineState_Release(context->pipeline_state);
|
||||
if (context->root_signature)
|
||||
|
|
|
@ -123,6 +123,8 @@ decl_test(test_tgsm);
|
|||
decl_test(test_uav_load);
|
||||
decl_test(test_cs_uav_store);
|
||||
decl_test(test_uav_counters);
|
||||
decl_test(test_uav_counter_null_behavior_dxbc);
|
||||
decl_test(test_uav_counter_null_behavior_dxil);
|
||||
decl_test(test_decrement_uav_counter);
|
||||
decl_test(test_atomic_instructions_dxbc);
|
||||
decl_test(test_atomic_instructions_dxil);
|
||||
|
@ -135,6 +137,7 @@ decl_test(test_resolve_non_issued_query_data);
|
|||
decl_test(test_resolve_query_data_in_different_command_list);
|
||||
decl_test(test_resolve_query_data_in_reordered_command_list);
|
||||
decl_test(test_execute_indirect);
|
||||
decl_test(test_execute_indirect_state);
|
||||
decl_test(test_dispatch_zero_thread_groups);
|
||||
decl_test(test_unaligned_vertex_stride);
|
||||
decl_test(test_zero_vertex_stride);
|
||||
|
@ -199,6 +202,7 @@ decl_test(test_primitive_restart);
|
|||
decl_test(test_index_buffer_edge_case_stream_output);
|
||||
decl_test(test_vertex_shader_stream_output_dxbc);
|
||||
decl_test(test_vertex_shader_stream_output_dxil);
|
||||
decl_test(test_primitive_restart_list_topology_stream_output);
|
||||
decl_test(test_read_write_subresource);
|
||||
decl_test(test_queue_wait);
|
||||
decl_test(test_graphics_compute_queue_synchronization);
|
||||
|
@ -293,6 +297,7 @@ decl_test(test_integer_blending_pipeline_state);
|
|||
decl_test(test_discard_resource_uav);
|
||||
decl_test(test_unbound_rtv_rendering);
|
||||
decl_test(test_raytracing_local_rs_static_sampler);
|
||||
decl_test(test_raytracing_local_rs_static_sampler_collection);
|
||||
decl_test(test_rayquery);
|
||||
decl_test(test_typed_srv_uav_cast);
|
||||
decl_test(test_typed_srv_cast_clear);
|
||||
|
@ -301,3 +306,18 @@ decl_test(test_mesh_shader_create_pipeline);
|
|||
decl_test(test_mesh_shader_rendering);
|
||||
decl_test(test_mesh_shader_execute_indirect);
|
||||
decl_test(test_amplification_shader);
|
||||
decl_test(test_advanced_cbv_layout);
|
||||
decl_test(test_shader_waveop_maximal_convergence);
|
||||
decl_test(test_uav_3d_sliced_view);
|
||||
decl_test(test_pipeline_no_ps_nonzero_rts);
|
||||
decl_test(test_root_descriptor_offset_sign);
|
||||
decl_test(test_raytracing_no_global_root_signature);
|
||||
decl_test(test_raytracing_missing_required_objects);
|
||||
decl_test(test_raytracing_reject_duplicate_objects);
|
||||
decl_test(test_raytracing_embedded_subobjects);
|
||||
decl_test(test_raytracing_default_association_tiebreak);
|
||||
decl_test(test_raytracing_collection_identifiers);
|
||||
decl_test(test_fence_wait_robustness);
|
||||
decl_test(test_fence_wait_robustness_shared);
|
||||
decl_test(test_root_signature_empty_blob);
|
||||
decl_test(test_sparse_buffer_memory_lifetime);
|
||||
|
|
Loading…
Reference in New Issue