HLSL (High-Level Shading Language) Specifications
repository·main·Indexed 42 days ago
https://github.com/microsoft/hlsl-specsCentral repository for HLSL language specifications, feature proposals, and design considerations. Includes documentation on language and runtime versioning, style conventions, preprocessor macros for feature detection, and the formal proposal lifecycle for DirectX-specific features.
What's inside HLSL
- DXIL 1.8, which corresponds to Shader Model 6.8, introduces new features to HLSL that require updated representations in DXIL. These changes were implemented as a fast-track extension and are available in DXC 1.8. The update includes changes to address spaces, constant definitions, types, opcodes, and metadata.
Introduction to Linear Algebra Matrix in HLSL
mainThis proposal introduces linear algebra matrix operations to HLSL, planned for Shader Model (SM) 6.10. The goal is to provide a unified language feature for cross-thread data dependencies, moving away from platform-specific terminology (like Wave operations in Direct3D or Subgroup operations in Vulkan) toward a standardized linear algebra model. This feature aims to merge concepts from the Vulkan extension for SIMD matrix types (vk::Cooperative Matrix) and DirectX'sWave Matrixinto a single, cross-platform capability.Overview of DXIL 1.10 (Shader Model 6.10) Features
mainShader Model 6.10 (DXIL 1.10) introduces several new features and operations to HLSL, primarily focused on matrix operations, debugging, raytracing enhancements, and wave intrinsics.
Key updates include:
linalg::Matrix: Support for matrix-matrix and matrix-vector operations on dimensions > 4 using wave-cooperative hardware.DebugBreak: A new DXIL operation for breakpoint instructions.- Raytracing Enhancements: New operations for querying Triangle Object Positions and Clustered Geometry (cluster IDs).
- Wave Intrinsics: New intrinsics for Group Wave Index (returning wave index and wave count within a thread group).
- Memory Management: Introduction of Variable Group Shared Memory to declare maximum shared memory usage for portability.
- Deprecation: Removal of support for "node" shaders.
Long Vector Execution Test Plan Overview
mainThis test plan defines the strategy for verifying HLSL intrinsics and operators that support long vectors in Shader Model 6.9. The goal is to ensure that DXIL opcodes and LLVM instructions can compile, run, and produce correct output when provided with both long and native vector inputs.
Testing is categorized into five areas:
- DXIL OpCode tests: Verifying intrinsic mappings to DXIL opcodes.
- LLVM Instruction tests: Verifying coverage of specific LLVM instructions.
- HLSL Operator tests: Verifying operators that take long vectors as arguments.
- Standard loading/storing: Testing long vector access across various buffer types and data types, including
ResourceDescriptorHeaploading. - 'Creative' test cases: Testing edge cases like alignment boundaries and odd-numbered vector elements.
New DXIL Features in Shader Model 6.9
mainShader Model 6.9 (DXIL 1.9) introduces several new features and opcodes to the DXIL specification. Key additions include:
- Opacity Micromaps (OMM): Adds the
AllocateRayQuery2opcode and new flags. - Shader Execution Reordering (SER): Introduces the
%dx.types.HitObjecttype and 30 new DXIL opcodes. - DXIL Vectors: Enables native vector support (aligned with LLVM 3.7). This includes the
rawBufferVectorLoadopcode for loading entire vectors and extended elementwise intrinsics that accept vector arguments. - 16bit IsSpecialFloat: Fixes a bug to allow
IsSpecialFloatDXIL operations (used forisinf,isnan,isfinite, andisnormal) to be generated for 16-bit types.
- Opacity Micromaps (OMM): Adds the
Compatibility of existing Load/Store with BaseAlignment
mainIf you declare a buffer with
[BaseAlignment(value)]but continue to use the standardLoadorStorefunctions (instead ofAlignedLoad/AlignedStore), the compiler applies an implied alignment based on the largest scalar type in the aggregate type.Calculation:
min(BaseAlignment, largest_scalar_type_size)Error Condition: If the
BaseAlignmentis smaller than the alignment required by the largest scalar type in the requested data type, the compiler will issue an error. For example, attempting toStore<uint64_t>into a buffer with[BaseAlignment(4)]will fail becauseuint64_trequires 8-byte alignment.Note: If
BaseAlignmentis not specified, the compiler uses the standard HLSL rule: the alignment requirement is the size in bytes of the largest scalar type contained in the aggregate type.Understand Mesh Node Output Arrays and Semantics
mainMesh nodes do not allow direct outputs to other nodes (no
[Empty]NodeOutput[Array]parameters). Instead, they use shared output arrays similar to traditional mesh shaders. These arrays reside in memory shared across the threadgroup (likegroupsharedmemory).Supported Output Arrays
Array Max Dimension Required verticesvertices Yes attributesforverticesvertices Yes indicesprimitives Yes attributesforprimitivesprimitives No System Value Semantics for Outputs
Fields within the
verticesandprimitivesarrays use system value semantics to define their role in the pipeline:For
verticesarray:SV_Position(float4, Required)SV_ClipDistance(float<1-4>, Optional)SV_CullDistance(float<1-4>, Optional)
For
primitivesarray:SV_RenderTargetArrayIndex(uint, Optional)SV_ViewPortArrayIndex(uint, Optional)SV_ShadingRate(uint, Optional)SV_PrimitiveID(uint, Optional)SV_CullPrimitive(uint, Optional)
How effective alignment is calculated
mainThe compiler determines the absolute alignment of a memory access by taking the minimum of two values:
- The buffer's declared
BaseAlignment(absolute alignment of the base address). - The operation's specified
alignmentparameter (relative alignment of the offset).
Examples:
- Scenario A:
[BaseAlignment(32)]andAlignedLoad(offset, 16). Effective alignment =min(32, 16)= 16. - Scenario B:
[BaseAlignment(32)]andAlignedLoad(offset, 64). Effective alignment =min(32, 64)= 32 (limited by the buffer's base alignment).
- The buffer's declared
How to use WorkgroupSpirvPointer for Groupshared Memory
mainSince HLSL does not allow groupshared memory objects to be passed by reference, the
WorkgroupSpirvPointer<T>type is used as a workaround. This is an opaque pointer type used to interface withLoadandStoreoperations for groupshared data.To create a pointer, use
vk::GetGroupSharedAddress(v), wherevis an object in groupshared memory.Usage Rules:
WorkgroupSpirvPointers must be used only as function-scope automatics, static global variables, or function parameters.
groupshared float shared_data[64]; // Get pointer to a single element WorkgroupSpirvPointer<float> scalar_ptr = vk::GetGroupSharedAddress(shared_data[0]); // Get pointer to the whole array WorkgroupSpirvPointer<float[64]> array_ptr = vk::GetGroupSharedAddress(shared_data);Understand the proposed conforming literal rules in HLSL 202x
mainThis proposal changes how HLSL handles literal values to align with C/C++ and OpenGL standards. This change is targeted for HLSL 202x and is implemented in DXC.
Floating-point Literals
- Un-suffixed literals: By default, floating-point literals are treated as 32-bit float (matching OpenGL behavior).
- Double precision: To specify a
double, you must use thelforLFsuffix.
Integer Literals
Integer literals follow C rules for type selection based on the value and the base:
- Base-10 (Decimal) non-suffixed: The type is the first integer type from [
int32_t,int64_t] that can represent the value. - Octal, Hexadecimal, or Binary non-suffixed: The type is the first type from [
int32_t,uint32_t,int64_t,uint64_t] that can represent the value.
How 16-bit isSpecialFloat operations are handled across Shader Models
mainThe behavior of 16-bit special float intrinsics depends on the targeted Shader Model:
- Shader Model 6.9 and later: DXC generates native 16-bit DXIL
isSpecialFloatoperations. This is the preferred method for performance and correct 16-bit testing. - Shader Model 6.8 and earlier: The functionality is emulated using LLVM IR rather than using a native 16-bit DXIL op. This ensures compatibility while providing the expected HLSL interface.
Validation Note: The DXIL validator will disallow 16-bit DXIL overloads for
isinf,isnan,isfinite, andisnormalif targeting SM 6.8 or earlier, or if 16-bit types are not enabled.- Shader Model 6.9 and later: DXC generates native 16-bit DXIL
Understand how DXC calculates absolute alignment for DXIL
mainWhen using
AlignedLoadorAlignedStorewithBaseAlignment, the DXC compiler automatically calculates the absolute alignment passed to the underlying DXIL operations.The calculation follows this logic:
- Absolute Alignment =
min(BaseAlignment, function_alignment_parameter)
This conversion ensures that while HLSL uses relative alignment (offset relative to base address), the DXIL operations receive the correct absolute alignment (final memory address alignment).
// HLSL Source: [BaseAlignment(32)] RWByteAddressBuffer MyBuffer : register(u0); uint4 data = MyBuffer.AlignedLoad<uint4>(offset, 16); // DXC Calculation: // 1. Buffer base alignment: 32 // 2. Function relative offset alignment: 16 // 3. Absolute alignment for DXIL: min(32, 16) = 16- Absolute Alignment =