DirectX Shader Compiler (DXC)
repository·main·Indexed 25 days ago
https://github.com/microsoft/directxshadercompilerA 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.
What's inside DirectX Shader Compiler
- 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.
Overview of DXC components
mainThe 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.
Overview of LLVM Analysis and Transform Passes
mainLLVM 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).
Overview of DXR Fallback Compiler capabilities
mainThe 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.,
TraceRayandCallShader). - Recursive shader call invocations.
Overview of the lit testing tool
mainlit is a portable, lightweight software testing tool designed to execute LLVM and Clang-style test suites. It summarizes test results and provides clear indications of failures through a simple user interface.Understand the LLVMBuild organization system
mainThe DirectX Shader Compiler uses theLLVMBuildsystem 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 anLLVMBuild.txtfile that explicitly defines that component's structure and dependencies.Understand the CodeGen Library's role in IR generation
mainTheCodeGenlibrary takes an Abstract Syntax Tree (AST) as input and produces LLVM IR code from it.Understand Clang Modules vs. C Preprocessor Includes
mainThis documentation describes the Clang Modules system, which provides a semantic alternative to the traditional C preprocessor
#includemechanism.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)Mechanism Textual 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). Fragility Subject to macro collisions and include-order dependencies. Standalone parsing; preprocessor definitions preceding an import do not affect the module API. Tooling Hard 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.
Understand the LLVM code coverage mapping workflow
mainThe 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:
- 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. - Reporting Stage: The
llvm-covtool 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.
- Compilation Stage: When Clang compiles a file with
Use the Clang Frontend library for tool development
mainThe Clang Frontend library provides functionality for developers building tools on top of the Clang libraries. A primary use case is accessing methods for outputting diagnostics.Understand LLVM Debugging Information Philosophy
mainLLVM'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 HLSLdocumentation.Understand the Clang Parser Library architecture
mainThe 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
Actioninterface with virtual methods (e.g.,ActOnBinOp()), it no longer supports generalActionclients due to the requirements of C++ support. It now communicates exclusively with theSemalibrary.When interacting with the Abstract Syntax Tree (AST), the parser uses opaque wrapper types such as
ExprResultandStmtResult. Only theSemalibrary is responsible for inspecting the actual AST node contents within these wrappers.