11 HLSL Support is under active development in the Clang codebase. This document
12 describes the high level goals of the project, the guiding principles, as well
13 as some idiosyncrasies of the HLSL language and how we intend to support them in
19 The long term goal of this project is to enable Clang to function as a
20 replacement for the `DirectXShaderCompiler (DXC)
21 <https://github.com/microsoft/DirectXShaderCompiler/>`_ in all its supported
22 use cases. Accomplishing that goal will require Clang to be able to process most
23 existing HLSL programs with a high degree of source compatibility.
28 HLSL ASTs do not need to be compatible between DXC and Clang. We do not expect
29 identical code generation or that features will resemble DXC's implementation or
30 architecture. In fact, we explicitly expect to deviate from DXC's implementation
36 This document lacks details for architectural decisions that are not yet
37 finalized. Our top priorities are quality, maintainability, and flexibility. In
38 accordance with community standards we are expecting a high level of test
39 coverage, and we will engineer our solutions with long term maintenance in mind.
40 We are also working to limit modifications to the Clang C++ code paths and
41 share as much functionality as possible.
43 Architectural Direction
44 =======================
46 HLSL support in Clang is expressed as C++ minus unsupported C and C++ features.
47 This is different from how other Clang languages are implemented. Most languages
48 in Clang are additive on top of C.
50 HLSL is not a formally or fully specified language, and while our goals require
51 a high level of source compatibility, implementations can vary and we have some
52 flexibility to be more or less permissive in some cases. For modern HLSL DXC is
53 the reference implementation.
55 The HLSL effort prioritizes following similar patterns for other languages,
56 drivers, runtimes and targets. Specifically, We will maintain separation between
57 HSLS-specific code and the rest of Clang as much as possible following patterns
58 in use in Clang code today (i.e. ParseHLSL.cpp, SemaHLSL.cpp, CGHLSL*.cpp...).
59 We will use inline checks on language options where the code is simple and
60 isolated, and prefer HLSL-specific implementation files for any code of
61 reasonable complexity.
63 In places where the HLSL language is in conflict with C and C++, we will seek to
64 make minimally invasive changes guarded under the HLSL language options. We will
65 seek to make HLSL language support as minimal a maintenance burden as possible.
70 A DXC driver mode will provide command-line compatibility with DXC, supporting
71 DXC's options and flags. The DXC driver is HLSL-specific and will create an
72 HLSLToolchain which will provide the basis to support targeting both DirectX and
78 Following the examples of other parser extensions HLSL will add a ParseHLSL.cpp
79 file to contain the implementations of HLSL-specific extensions to the Clang
80 parser. The HLSL grammar shares most of its structure with C and C++, so we will
81 use the existing C/C++ parsing code paths.
86 HLSL's Sema implementation will also provide an ``ExternalSemaSource``. In DXC,
87 an ``ExternalSemaSource`` is used to provide definitions for HLSL built-in data
88 types and built-in templates. Clang is already designed to allow an attached
89 ``ExternalSemaSource`` to lazily complete data types, which is a **huge**
90 performance win for HLSL.
92 If precompiled headers are used when compiling HLSL, the ``ExternalSemaSource``
93 will be a ``MultiplexExternalSemaSource`` which includes both the ``ASTReader``
94 and ``HLSLExternalSemaSource``. For Built-in declarations that are already
95 completed in the serialized AST, the ``HLSLExternalSemaSource`` will reuse the
96 existing declarations and not introduce new declarations. If the built-in types
97 are not completed in the serialized AST, the ``HLSLExternalSemaSource`` will
98 create new declarations and connect the de-serialized decls as the previous
104 Like OpenCL, HLSL relies on capturing a lot of information into IR metadata.
105 *hand wave* *hand wave* *hand wave* As a design principle here we want our IR to
106 be idiomatic Clang IR as much as possible. We will use IR attributes wherever we
107 can, and use metadata as sparingly as possible. One example of a difference from
108 DXC already implemented in Clang is the use of target triples to communicate
109 shader model versions and shader stages.
111 Our HLSL CodeGen implementation should also have an eye toward generating IR
112 that will map directly to targets other than DXIL. While IR itself is generally
113 not re-targetable, we want to share the Clang CodeGen implementation for HLSL
114 with other GPU graphics targets like SPIR-V and possibly other GPU and even CPU
120 The HLSL language is insufficiently documented, and not formally specified.
121 Documentation is available on `Microsoft's website
122 <https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl>`_.
123 The language syntax is similar enough to C and C++ that carefully written C and
124 C++ code is valid HLSL. HLSL has some key differences from C & C++ which we will
125 need to handle in Clang.
127 HLSL is not a conforming or valid extension or superset of C or C++. The
128 language has key incompatibilities with C and C++, both syntactically and
131 An Aside on GPU Languages
132 -------------------------
134 Due to HLSL being a GPU targeted language HLSL is a Single Program Multiple Data
135 (SPMD) language relying on the implicit parallelism provided by GPU hardware.
136 Some language features in HLSL enable programmers to take advantage of the
137 parallel nature of GPUs in a hardware abstracted language.
139 HLSL also prohibits some features of C and C++ which can have catastrophic
140 performance or are not widely supportable on GPU hardware or drivers. As an
141 example, register spilling is often excessively expensive on GPUs, so HLSL
142 requires all functions to be inlined during code generation, and does not
143 support a runtime calling convention.
145 Pointers & References
146 ---------------------
148 HLSL does not support referring to values by address. Semantically all variables
149 are value-types and behave as such. HLSL disallows the pointer dereference
150 operators (unary ``*``, and ``->``), as well as the address of operator (unary
151 &). While HLSL disallows pointers and references in the syntax, HLSL does use
152 reference types in the AST, and we intend to use pointer decay in the AST in
153 the Clang implementation.
155 HLSL ``this`` Keyword
156 ---------------------
158 HLSL does support member functions, and (in HLSL 2021) limited operator
159 overloading. With member function support, HLSL also has a ``this`` keyword. The
160 ``this`` keyword is an example of one of the places where HLSL relies on
161 references in the AST, because ``this`` is a reference.
166 In deviation from C, HLSL bitshifts are defined to mask the shift count by the
167 size of the type. In DXC, the semantics of LLVM IR were altered to accommodate
168 this, in Clang we intend to generate the mask explicitly in the IR. In cases
169 where the shift value is constant, this will be constant folded appropriately,
170 in other cases we can clean it up in the DXIL target.
172 Non-short Circuiting Logical Operators
173 --------------------------------------
175 In HLSL 2018 and earlier, HLSL supported logical operators (and the ternary
176 operator) on vector types. This behavior required that operators not short
177 circuit. The non-short circuiting behavior applies to all data types until HLSL
178 2021. In HLSL 2021, logical and ternary operators do not support vector types
179 instead builtin functions ``and``, ``or`` and ``select`` are available, and
180 operators short circuit matching C behavior.
185 HLSL has a ``precise`` qualifier that behaves unlike anything else in the C
186 language. The support for this qualifier in DXC is buggy, so our bar for
187 compatibility is low.
189 The ``precise`` qualifier applies in the inverse direction from normal
190 qualifiers. Rather than signifying that the declaration containing ``precise``
191 qualifier be precise, it signifies that the operations contributing to the
192 declaration's value be ``precise``. Additionally, ``precise`` is a misnomer:
193 values attributed as ``precise`` comply with IEEE-754 floating point semantics,
194 and are prevented from optimizations which could decrease *or increase*
197 Differences in Templates
198 ------------------------
200 HLSL uses templates to define builtin types and methods, but disallowed
201 user-defined templates until HLSL 2021. HLSL also allows omitting empty template
202 parameter lists when all template parameters are defaulted. This is an ambiguous
203 syntax in C++, but Clang detects the case and issues a diagnostic. This makes
204 supporting the case in Clang minimally invasive.
209 HLSL uses the OpenCL vector extensions, and also provides C++-style constructors
210 for vectors that are not supported by Clang.
215 HLSL does not support the C or C++ standard libraries. Like OpenCL, HLSL
216 describes its own library of built in types, complex data types, and functions.
218 Unsupported C & C++ Features
219 ----------------------------
221 HLSL does not support all features of C and C++. In implementing HLSL in Clang
222 use of some C and C++ features will produce diagnostics under HLSL, and others
223 will be supported as language extensions. In general, any C or C++ feature that
224 can be supported by the DXIL and SPIR-V code generation targets could be treated
225 as a clang HLSL extension. Features that cannot be lowered to DXIL or SPIR-V,
226 must be diagnosed as errors.
228 HLSL does not support the following C features:
233 * Variable Length Arrays
234 * ``_Complex`` and ``_Imaginary``
235 * C Threads or Atomics (or Obj-C blocks)
236 * ``union`` types `(in progress for HLSL 202x) <https://github.com/microsoft/DirectXShaderCompiler/pull/4132>`_
237 * Most features C11 and later
239 HLSL does not support the following C++ features:
243 * Multiple inheritance
245 * Anonymous or inline namespaces
246 * ``new`` & ``delete`` operators in all of their forms (array, placement, etc)
247 * Constructors and destructors
248 * Any use of the ``virtual`` keyword
249 * Most features C++11 and later