ShaderCompiler/Hlsl.h file

HLSL (Direct3D 11, Shader Model 4/5) source-to-source emitter for ShaderCompiler.

The tool lowers each ".shader" into a MODERN-GLSL stage source (in/out, texture(), "out vec4 COLOR;", std140 UBO blocks, gl_VertexID). This emitter grows a real per-statement/expression AST from that source (on the SAME reusable lexer + preprocessor the GLSL-to-C++ transpiler uses — GlslExprTokenizer and Preprocessor) and emits an HLSL translation of one stage, then the offline --hlsl-check mode compiles each stage via d3dcompiler_47's D3DCompile to validate it. This is TOOL-ONLY: it adds no RHI backend and touches no engine code.

The key GLSL -> HLSL rewrites:

  • Types: vec2/3/4 -> float2/3/4, mat3/4 -> float3x3/float4x4, ivecN -> intN, bvecN -> boolN; precision and layout qualifiers are dropped.
  • Matrix algebra: a * whose operands are matrix/vector (never scalar) becomes mul(a, b) — GLSL M * v -> HLSL mul(M, v) (column-vector convention). A lightweight type inference over the AST decides matrix-vs-componentwise per multiply.
  • Uniforms: layout(std140) uniform Block { ... } -> cbuffer Block : register(b#); loose uniforms gather into one cbuffer. Block members are global names in HLSL, so bare-member and instance-name qualified (block.member) accesses both resolve to the member name.
  • Textures: uniform sampler2D uTex -> Texture2D uTex : register(t#); SamplerState uTex_sampler : register(s#); and texture(uTex, uv) -> uTex.Sample(uTex_sampler, uv) (textureLod -> .SampleLevel).
  • I/O: vertex attributes + gl_VertexID (SV_VertexID) form the VS input struct; VS out varyings + gl_Position (SV_Position) form the VS output struct; FS in varyings + gl_FragCoord (SV_Position) form the PS input struct; a single FS out (the usual out vec4 COLOR) is returned as SV_Target. MULTIPLE FS out declarations render to SV_Target0..N in DECLARATION ORDER (of the emitted stage source) through an emitted PsOutput struct — the same order the offline SPIR-V emission assigns as layout(location = 0..N), so both backends write the same attachment for the same output (explicit layout(location) qualifiers on fragment outputs are declined to keep that scheme unambiguous). Attributes/varyings/gl_* are copied to/from file-scope static globals so helper functions read them exactly as in GLSL.
  • Built-ins: mix->lerp, fract->frac, dFdx/dFdy->ddx/ddy, inversesqrt->rsqrt, atan(y,x)->atan2(y,x), mod(a,b)->(a - b*floor(a/b)); dot/length/normalize/clamp/... keep their names.

Constructs outside the handled subset (e.g. geometry/compute features) make Transform() return false with a diagnostic rather than emit invalid HLSL.

Namespaces

namespace ShaderCompiler

Classes

class ShaderCompiler::HlslEmitter
Transforms an already-lowered modern-GLSL stage source into HLSL (Shader Model 4/5).