DirectX Shader Compiler (DXC)

repository·main·Indexed 25 days ago

https://github.com/microsoft/directxshadercompiler

A compiler based on LLVM and Clang used to transform High-Level Shader Language (HLSL) programs into DirectX Intermediate Language (DXIL) for DirectX, or SPIR-V for Vulkan. It includes tools like dxc.exe and dxv.exe, support for Metal shader libraries, and a DXR Fallback Compiler for running DXR features on hardware without native driver support.

Tokens
191K
Snippets
425
Records
979
Agent score
85%

What's inside DirectX Shader Compiler

  1. Overview of DirectX Shader Compiler

    main
    The DirectX HLSL Compiler is a toolset used to compile High-Level Shader Language (HLSL) programs into DirectX Intermediate Language (DXIL) representation. It is built on the LLVM and Clang (version 3.7) infrastructure. Developers use it to generate shader programs for graphics, games, and computation within the DirectX ecosystem.
  2. Overview of DXC components

    main

    The DirectX Shader Compiler (DXC) provides several key components for shader development:

    • dxc.exe: A command-line tool for compiling HLSL programs for shader model 6.0 or higher.
    • dxcompiler.[dll|so]: A dynamic library providing a componentized compiler, assembler, disassembler, and validator.
    • dxil.[dll|so]: A dynamic library providing DXIL validation and hashing support.
    • dxv.exe: A command-line tool used to validate DXIL IR (compiled HLSL programs).
    • C++ Headers: For programmatic interaction with the dynamic libraries.
    • HLSL Headers: High-level abstractions for writing HLSL code.
  3. Overview of LLVM Analysis and Transform Passes

    main

    LLVM optimizations are implemented as Passes that traverse portions of a program. These passes are categorized into three main types:

    • Analysis Passes: Compute information used by other passes, for debugging, or for program visualization.
    • Transform Passes: Mutate the program in some way. These passes can use or invalidate the results of analysis passes.
    • Utility Passes: Provide general utility that does not fit the other categories (e.g., extracting functions to bitcode or writing a module to bitcode).
  4. Overview of DXR Fallback Compiler capabilities

    main

    The DXR Fallback Compiler enables DXR features on hardware without native DXR driver support by transforming the DXR pipeline into a State Machine traversal. It handles challenges that standard DX12 compute shaders cannot, including:

    • Combining multiple orthogonal shaders into a single large compute shader.
    • Using all new DXR HLSL intrinsics.
    • Invoking other shaders mid-code (e.g., TraceRay and CallShader).
    • Recursive shader call invocations.
  5. Understand the LLVMBuild organization system

    main
    The DirectX Shader Compiler uses the LLVMBuild system to organize its modular libraries and tools. The project is structured into components (libraries, build tools, or command-line tools), where each major subdirectory typically contains an LLVMBuild.txt file that explicitly defines that component's structure and dependencies.
  6. Understand Clang Modules vs. C Preprocessor Includes

    main

    This documentation describes the Clang Modules system, which provides a semantic alternative to the traditional C preprocessor #include mechanism.

    Note: This information applies to the original Clang project, not the DirectX Compiler. Module support is not currently compiled or supported in the DirectX Compiler context.

    Key Differences

    Feature#include (Preprocessor)import (Modules)
    MechanismTextual inclusion of header files.Loading a pre-compiled binary representation of the module API.
    Scalability$M \times N$ work (re-parsing headers for every translation unit).$M + N$ work (module is parsed once; importing is constant-time).
    FragilitySubject to macro collisions and include-order dependencies.Standalone parsing; preprocessor definitions preceding an import do not affect the module API.
    ToolingHard to distinguish API from implementation or identify language variants.Modules explicitly describe the API and specify supported languages.

    Limitations of Modules

    • No Versioning: Modules do not include version information; use existing language versioning mechanisms.
    • No Namespaces: Modules do not provide automatic namespacing. Name conflicts (e.g., two structs with the same name in different modules) will still occur.
    • No Binary Distribution: Maintaining a stable binary module format across different architectures and compilers is not supported; headers are still required for interoperability.
  7. Understand the LLVM code coverage mapping workflow

    main

    The LLVM code coverage mapping format is a self-contained data format embedded into LLVM IR and object files. It enables the mapping between source code ranges and execution counts.

    The process involves two main stages:

    1. Compilation Stage: When Clang compiles a file with -fcoverage-mapping, it generates mapping information that describes the relationship between source ranges and profiling instrumentation counters. This data is embedded into the LLVM IR and the final executable.
    2. Reporting Stage: The llvm-cov tool extracts this mapping information from the object files. It then associates the execution counts (from the profile data) with the source ranges to generate coverage reports.
  8. Understand LLVM Debugging Information Philosophy

    main

    LLVM's debugging information is designed to map source-language Abstract Syntax Trees (AST) onto LLVM code with minimal impact on the compiler. Key design principles include:

    • Minimal Impact: Transformations, analyses, and code generators do not need modification to support debug information.
    • Optimization Compatibility: Debug information interacts with LLVM optimizations in well-defined ways and does not prevent optimizations like inlining or basic block reordering.
    • Language Agnostic: LLVM supports arbitrary programming languages by using a small set of intrinsic functions to define mappings, rather than requiring knowledge of source-level semantics.
    • Debugger Compatibility: It allows compilation to native machine code with standard debugging formats (e.g., DWARF), enabling compatibility with traditional debuggers like GDB or DBX.

    Note for HLSL/DXIL users: For information specific to HLSL and DXIL, refer to the Source Level Debugging with HLSL documentation.

  9. Understand the Clang Parser Library architecture

    main

    The Clang Parser Library uses a recursive-descent parser that retrieves tokens from the preprocessor and notifies a client of parsing progress.

    Note for developers extending the parser: While the parser historically supported an abstract Action interface with virtual methods (e.g., ActOnBinOp()), it no longer supports general Action clients due to the requirements of C++ support. It now communicates exclusively with the Sema library.

    When interacting with the Abstract Syntax Tree (AST), the parser uses opaque wrapper types such as ExprResult and StmtResult. Only the Sema library is responsible for inspecting the actual AST node contents within these wrappers.