HLSL for Vulkan
DXC's SPIR-V back end (-spirv) makes HLSL a first-class Vulkan shading language; it's used by many engines and by the Vulkan samples.
DXC's SPIR-V back end (-spirv) makes HLSL a first-class Vulkan shading language; it's used by many engines and by the Vulkan samples. The __spirv__ macro is defined when targeting SPIR-V.
36.1 Compiling
dxc -spirv -T vs_6_0 -E VSMain -fspv-target-env=vulkan1.3 shader.hlsl -Fo shader.vert.spv
dxc -spirv -T ps_6_0 -E PSMain -fspv-target-env=vulkan1.3 shader.hlsl -Fo shader.frag.spv
:: Debug info for RenderDoc source-level debugging
dxc -spirv -T ps_6_0 -E PSMain -fspv-debug=vulkan-with-source -Od shader.hlsl -Fo shader.frag.spv
:: Validate / disassemble with SPIRV-Tools
spirv-val shader.frag.spv
spirv-dis shader.frag.spv36.2 Binding resources
Vulkan uses (set, binding) pairs instead of registers. Either annotate explicitly or let DXC map registers:
Without attributes, DXC maps register(xN, spaceM) → binding N, set M. Since b0, t0, s0, u0 would collide in the same set, shift them:
// Explicit Vulkan attributes (ignored when compiling to DXIL)
[[vk::binding(0, 0)]] ConstantBuffer<FrameCB> gFrameVK; // set 0, binding 0
[[vk::binding(1, 0)]] Texture2D<float4> gAlbedoVK;
[[vk::binding(2, 0)]] SamplerState gSamplerVK;
[[vk::combinedImageSampler]] [[vk::binding(3, 0)]] Texture2D<float4> gCombinedTex;
[[vk::combinedImageSampler]] [[vk::binding(3, 0)]] SamplerState gCombinedSamp;
struct PushData { float4x4 model; uint materialIndex; };
[[vk::push_constant]] PushData gPush; // push constants
[[vk::constant_id(0)]] const bool kUseShadows = true; // specialization constants
[[vk::constant_id(1)]] const int kSampleCount = 16;
struct VkVSIn
{
[[vk::location(0)]] float3 pos : POSITION; // vertex input locations
[[vk::location(1)]] float2 uv : TEXCOORD0;
};
// Render-pass input attachments (subpasses)
[[vk::input_attachment_index(0)]] [[vk::binding(4, 0)]] SubpassInput<float4> gGBufferAlbedo;
float4 ReadSubpass() { return gGBufferAlbedo.SubpassLoad(); }dxc -spirv -T ps_6_0 -E main -fvk-b-shift 0 0 -fvk-t-shift 100 0 -fvk-s-shift 200 0 -fvk-u-shift 300 0 shader.hlsl -Fo shader.spv36.3 Differences & useful flags
Vulkan (via DXC) -fvk-invert-y (VS/DS/GS/MS) or negative viewport height (Vulkan 1.1+) SV_Position.w in PS 1/w (FragCoord.w) cbuffer 16-byte rules std140/std430 by default
-fvk-use-dx-layout, -fvk-use-scalar-layout, -fvk-use-gl-layout Append/consume counters separate counter buffer Combined image samplers
-fspv-reflect adds semantic decorations -fspv-extension=SPV_KHR_..., [[vk::ext_instruction]] inline SPIR-V
VK_KHR_ray_tracing_pipeline / ray_query -fspv-target-env=vulkan1.2+, [[vk::shader_record_ext]] for SBT data
printf("x = %f", x) via NonSemantic.DebugPrintf enable in validation layers