HLSL (High-Level Shading Language) Specifications

repository·main·Indexed 42 days ago

https://github.com/microsoft/hlsl-specs

Central 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.

Tokens
112.1K
Snippets
251
Records
414
Agent score
53%

What's inside HLSL

  1. Overview of DXIL 1.8 (Shader Model 6.8) changes

    main
    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.
  2. Introduction to Linear Algebra Matrix in HLSL

    main
    This 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's Wave Matrix into a single, cross-platform capability.
  3. Overview of DXIL 1.10 (Shader Model 6.10) Features

    main

    Shader 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.
  4. Long Vector Execution Test Plan Overview

    main

    This 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:

    1. DXIL OpCode tests: Verifying intrinsic mappings to DXIL opcodes.
    2. LLVM Instruction tests: Verifying coverage of specific LLVM instructions.
    3. HLSL Operator tests: Verifying operators that take long vectors as arguments.
    4. Standard loading/storing: Testing long vector access across various buffer types and data types, including ResourceDescriptorHeap loading.
    5. 'Creative' test cases: Testing edge cases like alignment boundaries and odd-numbered vector elements.
  5. New DXIL Features in Shader Model 6.9

    main

    Shader Model 6.9 (DXIL 1.9) introduces several new features and opcodes to the DXIL specification. Key additions include:

    • Opacity Micromaps (OMM): Adds the AllocateRayQuery2 opcode and new flags.
    • Shader Execution Reordering (SER): Introduces the %dx.types.HitObject type and 30 new DXIL opcodes.
    • DXIL Vectors: Enables native vector support (aligned with LLVM 3.7). This includes the rawBufferVectorLoad opcode for loading entire vectors and extended elementwise intrinsics that accept vector arguments.
    • 16bit IsSpecialFloat: Fixes a bug to allow IsSpecialFloat DXIL operations (used for isinf, isnan, isfinite, and isnormal) to be generated for 16-bit types.
  6. Compatibility of existing Load/Store with BaseAlignment

    main

    If you declare a buffer with [BaseAlignment(value)] but continue to use the standard Load or Store functions (instead of AlignedLoad/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 BaseAlignment is smaller than the alignment required by the largest scalar type in the requested data type, the compiler will issue an error. For example, attempting to Store<uint64_t> into a buffer with [BaseAlignment(4)] will fail because uint64_t requires 8-byte alignment.

    Note: If BaseAlignment is 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.

  7. Understand Mesh Node Output Arrays and Semantics

    main

    Mesh 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 (like groupshared memory).

    Supported Output Arrays

    ArrayMax DimensionRequired
    verticesverticesYes
    attributes for verticesverticesYes
    indicesprimitivesYes
    attributes for primitivesprimitivesNo

    System Value Semantics for Outputs

    Fields within the vertices and primitives arrays use system value semantics to define their role in the pipeline:

    For vertices array:

    • SV_Position (float4, Required)
    • SV_ClipDistance (float<1-4>, Optional)
    • SV_CullDistance (float<1-4>, Optional)

    For primitives array:

    • SV_RenderTargetArrayIndex (uint, Optional)
    • SV_ViewPortArrayIndex (uint, Optional)
    • SV_ShadingRate (uint, Optional)
    • SV_PrimitiveID (uint, Optional)
    • SV_CullPrimitive (uint, Optional)
  8. How effective alignment is calculated

    main

    The compiler determines the absolute alignment of a memory access by taking the minimum of two values:

    1. The buffer's declared BaseAlignment (absolute alignment of the base address).
    2. The operation's specified alignment parameter (relative alignment of the offset).

    Examples:

    • Scenario A: [BaseAlignment(32)] and AlignedLoad(offset, 16). Effective alignment = min(32, 16) = 16.
    • Scenario B: [BaseAlignment(32)] and AlignedLoad(offset, 64). Effective alignment = min(32, 64) = 32 (limited by the buffer's base alignment).
  9. How to use WorkgroupSpirvPointer for Groupshared Memory

    main

    Since 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 with Load and Store operations for groupshared data.

    To create a pointer, use vk::GetGroupSharedAddress(v), where v is 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);
  10. Understand the proposed conforming literal rules in HLSL 202x

    main

    This 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 the lf or LF suffix.

    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.
  11. How 16-bit isSpecialFloat operations are handled across Shader Models

    main

    The behavior of 16-bit special float intrinsics depends on the targeted Shader Model:

    1. Shader Model 6.9 and later: DXC generates native 16-bit DXIL isSpecialFloat operations. This is the preferred method for performance and correct 16-bit testing.
    2. 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, and isnormal if targeting SM 6.8 or earlier, or if 16-bit types are not enabled.

  12. Understand how DXC calculates absolute alignment for DXIL

    main

    When using AlignedLoad or AlignedStore with BaseAlignment, 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