This patchset implements support for DXIL shaders (SM 6.0+) via dxil-spirv (github.com/HansKristian-Work/dxil-spirv).
There are three main parts of this patchset.
First, support for SM 5.1 register spaces are introduced. These patches have been submitted before, but it was only reviewed after a rebase, and that rebase broke the patches due to some uninitialized member variables introduced in the UAV clear patch set which came inbetween. I've fixed those, and cleaned up the patches a little bit. I need SM 5.1 register spaces implemented because the DXIL implementation needs it as well. I also fixed some additional cases for SM 5.1 which were not implemented in the last patch set, like SM 5.1 root constants and root descriptors.
To aid debugging, I also added SPIR-V dumping to the VKD3D_SHADER_DUMP_PATH which was very useful to study difference between DXBC and DXIL outputs.
Second, we have the dxil-spirv integration. There are various small refactors needed to enable this, mostly just moving a few helper functions in vkd3d-shader around to the private header so they can be accessed by dxil.c. Vulkan 1.1 is enabled if active, because subgroup operations requires it. SM 6.0 support is only activated if subgroup operations are sufficiently supported and DXIL is enabled. There are other features required for SM 6.0 such as 16-bit arithmetic and storage, but that is left for later. We will need to revisit the binding model to enable that properly.
The actual DXIL implementation lives in dxil.c. dxbc.c will detect that a shader blob is DXIL by looking for TAG_DXIL and dispatch the work to dxil.c if DXIL support is enabled. DXIL blobs are basically identical to DXBC blobs, except TAG_DXIL is used instead of TAG_SHDR, and ISG1 is used instead of ISGN, etc.
To make integration as smooth as possible, dxil-spirv relies on callbacks rather than feeding structures to the compiler to resolve resource bindings and similar. This way, we won't have to translate the vkd3d_shader_* structures.
Finally, most of the commits here are to add DXIL testing paths for many of the tests in tests/d3d12.c. The dxil-spirv repo has a lot of tests already to cover codegen, so these tests are mostly to verify that the integration works. Adding these tests *did* find some bugs in the dxil-spirv implementation as well, but it mostly went without any major problems.
When emitting DXIL, the blob sizes are not word-aligned, so they are embedded as byte arrays instead. They are also much larger than equivalent DXBC blobs, due to LLVM IR bloat. I ran -Qstrip_debug -Qstrip_reflect in DXC when compiling these shaders.
The main strategy I used to add DXIL tests was to turn the existing tests into a function ala static void test_something(bool use_dxil) and just select the right shader code as required.
I had to add some utility functions as well because the D3D12 validation layers refuse to mix and match SM 5.1 and below with SM 6.0 and above. These utilities just use different default shader blobs. Another note is that to make the DXIL shaders pass validation on native D3D12 it is required that the DXIL is signed by Microsoft's validator.
Hans-Kristian Arntzen (41): vkd3d: Deal correctly with SM 5.1 register spaces. vkd3d: Add test case for SM 5.1 register spaces. vkd3d: Add test case for root constants in SM 5.1. vkd3d-shader: Add path for debug dumping SPIR-V as well. vkd3d: Add dxil-spirv to autoconf vkd3d: Attempt to parse ISG1 as well when parsing input signatures. vkd3d-shader: Add entry point to query if DXIL is supported. vkd3d: Attempt to create a Vulkan 1.1 instance and device. vkd3d: Query subgroup properties and expose SM 6.0 if present. vkd3d: Move vkd3d_find_shader into private header. vkd3d: Add helper function to query if a blob is DXIL. vkd3d-shader: Expose debug shader dumping in private header. vkd3d-shader: Add integration for DXIL shaders. vkd3d: Add test helper function to determine if DXIL is supported. vkd3d: Add helper test function to set up a default pipeline with DXIL. vkd3d: Add DXIL test for geometry shader. vkd3d: Add DXIL test for layered rendering. vkd3d: Add DXIL test for ps_layer. vkd3d: Add DXIL test for quad_tessellation. vkd3d: Add DXIL test for tess control point phase. vkd3d: Add DXIL test for tess fork phase. vkd3d: Add DXIL test for line tessellation. vkd3d: Add DXIL test for stream output. vkd3d: Add DXIL test for bufinfo. vkd3d: Add DXIL test for register spaces. vkd3d: Add DXIL test for constant buffers (root const/desc). vkd3d: Add DXIL test for dual source blending. vkd3d: Add DXIL test for face culling. vkd3d: Add DXIL test for render_target_a8. vkd3d-shader: Hook up RT output swizzle path in DXIL. vkd3d: Add DXIL test for sample mask. vkd3d: Add DXIL test for coverage. vkd3d: Add create_pipeline_state_dxil test utility. vkd3d: Add DXIL test for shader_sample_position. vkd3d: Add DXIL test for rasterizer sample count. vkd3d-shader: Hook up RASTERIZER_SAMPLE_COUNT parameter. vkd3d: Add DXIL test for clip distance. vkd3d: Add DXIL test for combined ClipCull. vkd3d: Add DXIL test for eval attribute. vkd3d: Add DXIL test for instance_id. vkd3d: Add DXIL test for vertex ID.
Makefile.am | 8 +- configure.ac | 11 + include/vkd3d_shader.h | 18 + libs/vkd3d-shader/dxbc.c | 58 +- libs/vkd3d-shader/dxil.c | 470 ++ libs/vkd3d-shader/spirv.c | 215 +- libs/vkd3d-shader/vkd3d_shader.map | 1 + libs/vkd3d-shader/vkd3d_shader_main.c | 99 +- libs/vkd3d-shader/vkd3d_shader_private.h | 38 + libs/vkd3d/command.c | 32 +- libs/vkd3d/device.c | 69 +- libs/vkd3d/state.c | 65 +- libs/vkd3d/utils.c | 3 + libs/vkd3d/vkd3d_private.h | 5 + tests/d3d12.c | 5983 +++++++++++++++++++--- tests/d3d12_test_utils.h | 193 +- 16 files changed, 6544 insertions(+), 724 deletions(-) create mode 100644 libs/vkd3d-shader/dxil.c