mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-27 01:06:06 +00:00

This adds a brief blurb about hlsl.h in the HLSLSupport documentation where a high level view of the architecture is explained.
298 lines
13 KiB
ReStructuredText
298 lines
13 KiB
ReStructuredText
============
|
|
HLSL Support
|
|
============
|
|
|
|
.. contents::
|
|
:local:
|
|
|
|
Introduction
|
|
============
|
|
|
|
HLSL Support is under active development in the Clang codebase. This document
|
|
describes the high level goals of the project, the guiding principles, as well
|
|
as some idiosyncrasies of the HLSL language and how we intend to support them in
|
|
Clang.
|
|
|
|
Project Goals
|
|
=============
|
|
|
|
The long term goal of this project is to enable Clang to function as a
|
|
replacement for the `DirectXShaderCompiler (DXC)
|
|
<https://github.com/microsoft/DirectXShaderCompiler/>`_ in all its supported
|
|
use cases. Accomplishing that goal will require Clang to be able to process most
|
|
existing HLSL programs with a high degree of source compatibility.
|
|
|
|
Non-Goals
|
|
---------
|
|
|
|
HLSL ASTs do not need to be compatible between DXC and Clang. We do not expect
|
|
identical code generation or that features will resemble DXC's implementation or
|
|
architecture. In fact, we explicitly expect to deviate from DXC's implementation
|
|
in key ways.
|
|
|
|
Guiding Principles
|
|
==================
|
|
|
|
This document lacks details for architectural decisions that are not yet
|
|
finalized. Our top priorities are quality, maintainability, and flexibility. In
|
|
accordance with community standards we are expecting a high level of test
|
|
coverage, and we will engineer our solutions with long term maintenance in mind.
|
|
We are also working to limit modifications to the Clang C++ code paths and
|
|
share as much functionality as possible.
|
|
|
|
Architectural Direction
|
|
=======================
|
|
|
|
HLSL support in Clang is expressed as C++ minus unsupported C and C++ features.
|
|
This is different from how other Clang languages are implemented. Most languages
|
|
in Clang are additive on top of C.
|
|
|
|
HLSL is not a formally or fully specified language, and while our goals require
|
|
a high level of source compatibility, implementations can vary and we have some
|
|
flexibility to be more or less permissive in some cases. For modern HLSL DXC is
|
|
the reference implementation.
|
|
|
|
The HLSL effort prioritizes following similar patterns for other languages,
|
|
drivers, runtimes and targets. Specifically, We will maintain separation between
|
|
HSLS-specific code and the rest of Clang as much as possible following patterns
|
|
in use in Clang code today (i.e. ParseHLSL.cpp, SemaHLSL.cpp, CGHLSL*.cpp...).
|
|
We will use inline checks on language options where the code is simple and
|
|
isolated, and prefer HLSL-specific implementation files for any code of
|
|
reasonable complexity.
|
|
|
|
In places where the HLSL language is in conflict with C and C++, we will seek to
|
|
make minimally invasive changes guarded under the HLSL language options. We will
|
|
seek to make HLSL language support as minimal a maintenance burden as possible.
|
|
|
|
DXC Driver
|
|
----------
|
|
|
|
A DXC driver mode will provide command-line compatibility with DXC, supporting
|
|
DXC's options and flags. The DXC driver is HLSL-specific and will create an
|
|
HLSLToolchain which will provide the basis to support targeting both DirectX and
|
|
Vulkan.
|
|
|
|
Parser
|
|
------
|
|
|
|
Following the examples of other parser extensions HLSL will add a ParseHLSL.cpp
|
|
file to contain the implementations of HLSL-specific extensions to the Clang
|
|
parser. The HLSL grammar shares most of its structure with C and C++, so we will
|
|
use the existing C/C++ parsing code paths.
|
|
|
|
Sema
|
|
----
|
|
|
|
HLSL's Sema implementation will also provide an ``ExternalSemaSource``. In DXC,
|
|
an ``ExternalSemaSource`` is used to provide definitions for HLSL built-in data
|
|
types and built-in templates. Clang is already designed to allow an attached
|
|
``ExternalSemaSource`` to lazily complete data types, which is a **huge**
|
|
performance win for HLSL.
|
|
|
|
If precompiled headers are used when compiling HLSL, the ``ExternalSemaSource``
|
|
will be a ``MultiplexExternalSemaSource`` which includes both the ``ASTReader``
|
|
and -. For Built-in declarations that are already
|
|
completed in the serialized AST, the ``HLSLExternalSemaSource`` will reuse the
|
|
existing declarations and not introduce new declarations. If the built-in types
|
|
are not completed in the serialized AST, the ``HLSLExternalSemaSource`` will
|
|
create new declarations and connect the de-serialized decls as the previous
|
|
declaration.
|
|
|
|
CodeGen
|
|
-------
|
|
|
|
Like OpenCL, HLSL relies on capturing a lot of information into IR metadata.
|
|
*hand wave* *hand wave* *hand wave* As a design principle here we want our IR to
|
|
be idiomatic Clang IR as much as possible. We will use IR attributes wherever we
|
|
can, and use metadata as sparingly as possible. One example of a difference from
|
|
DXC already implemented in Clang is the use of target triples to communicate
|
|
shader model versions and shader stages.
|
|
|
|
Our HLSL CodeGen implementation should also have an eye toward generating IR
|
|
that will map directly to targets other than DXIL. While IR itself is generally
|
|
not re-targetable, we want to share the Clang CodeGen implementation for HLSL
|
|
with other GPU graphics targets like SPIR-V and possibly other GPU and even CPU
|
|
targets.
|
|
|
|
hlsl.h
|
|
------
|
|
|
|
HLSL has a library of standalone functions. This is similar to OpenCL and CUDA,
|
|
and is analogous to C's standard library. The implementation approach for the
|
|
HLSL library functionality draws from patterns in use by OpenCL and other Clang
|
|
resource headers. All of the clang resource headers are part of the
|
|
``ClangHeaders`` component found in the source tree under
|
|
`clang/lib/Headers <https://github.com/llvm/llvm-project/tree/main/clang/lib/Headers>`_.
|
|
|
|
.. note::
|
|
|
|
HLSL's complex data types are not defined in HLSL's header because many of
|
|
the semantics of those data types cannot be expressed in HLSL due to missing
|
|
language features. Data types that can't be expressed in HLSL are defined in
|
|
code in the ``HLSLExternalSemaSource``.
|
|
|
|
Similar to OpenCL, the HLSL library functionality is implicitly declared in
|
|
translation units without needing to include a header to provide declarations.
|
|
In Clang this is handled by making ``hlsl.h`` an implicitly included header
|
|
distributed as part of the Clang resource directory.
|
|
|
|
Similar to OpenCL, HLSL's implicit header will explicitly declare all overloads,
|
|
and each overload will map to a corresponding ``__builtin*`` compiler intrinsic
|
|
that is handled in ClangCodeGen. CUDA uses a similar pattern although many CUDA
|
|
functions have full definitions in the included headers which in turn call
|
|
corresponding ``__builtin*`` compiler intrinsics. By not having bodies HLSL
|
|
avoids the need for the inliner to clean up and inline large numbers of small
|
|
library functions.
|
|
|
|
HLSL's implicit headers also define some of HLSL's typedefs. This is consistent
|
|
with how the AVX vector header is implemented.
|
|
|
|
Concerns have been expressed that this approach may result in slower compile
|
|
times than the approach DXC uses where library functions are treated more like
|
|
Clang ``__builtin*`` intrinsics. No real world use cases have been identified
|
|
where parsing is a significant compile-time overhead, but the HLSL implicit
|
|
headers can be compiled into a module for performance if needed.
|
|
|
|
Further, by treating these as functions rather than ``__builtin*`` compiler
|
|
intrinsics, the language behaviors are more consistent and aligned with user
|
|
expectation because normal overload resolution rules and implicit conversions
|
|
apply as expected.
|
|
|
|
It is a feature of this design that clangd-powered "go to declaration" for
|
|
library functions will jump to a valid header declaration and all overloads will
|
|
be user readable.
|
|
|
|
HLSL Language
|
|
=============
|
|
|
|
The HLSL language is insufficiently documented, and not formally specified.
|
|
Documentation is available on `Microsoft's website
|
|
<https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl>`_.
|
|
The language syntax is similar enough to C and C++ that carefully written C and
|
|
C++ code is valid HLSL. HLSL has some key differences from C & C++ which we will
|
|
need to handle in Clang.
|
|
|
|
HLSL is not a conforming or valid extension or superset of C or C++. The
|
|
language has key incompatibilities with C and C++, both syntactically and
|
|
semantically.
|
|
|
|
An Aside on GPU Languages
|
|
-------------------------
|
|
|
|
Due to HLSL being a GPU targeted language HLSL is a Single Program Multiple Data
|
|
(SPMD) language relying on the implicit parallelism provided by GPU hardware.
|
|
Some language features in HLSL enable programmers to take advantage of the
|
|
parallel nature of GPUs in a hardware abstracted language.
|
|
|
|
HLSL also prohibits some features of C and C++ which can have catastrophic
|
|
performance or are not widely supportable on GPU hardware or drivers. As an
|
|
example, register spilling is often excessively expensive on GPUs, so HLSL
|
|
requires all functions to be inlined during code generation, and does not
|
|
support a runtime calling convention.
|
|
|
|
Pointers & References
|
|
---------------------
|
|
|
|
HLSL does not support referring to values by address. Semantically all variables
|
|
are value-types and behave as such. HLSL disallows the pointer dereference
|
|
operators (unary ``*``, and ``->``), as well as the address of operator (unary
|
|
&). While HLSL disallows pointers and references in the syntax, HLSL does use
|
|
reference types in the AST, and we intend to use pointer decay in the AST in
|
|
the Clang implementation.
|
|
|
|
HLSL ``this`` Keyword
|
|
---------------------
|
|
|
|
HLSL does support member functions, and (in HLSL 2021) limited operator
|
|
overloading. With member function support, HLSL also has a ``this`` keyword. The
|
|
``this`` keyword is an example of one of the places where HLSL relies on
|
|
references in the AST, because ``this`` is a reference.
|
|
|
|
Bitshifts
|
|
---------
|
|
|
|
In deviation from C, HLSL bitshifts are defined to mask the shift count by the
|
|
size of the type. In DXC, the semantics of LLVM IR were altered to accommodate
|
|
this, in Clang we intend to generate the mask explicitly in the IR. In cases
|
|
where the shift value is constant, this will be constant folded appropriately,
|
|
in other cases we can clean it up in the DXIL target.
|
|
|
|
Non-short Circuiting Logical Operators
|
|
--------------------------------------
|
|
|
|
In HLSL 2018 and earlier, HLSL supported logical operators (and the ternary
|
|
operator) on vector types. This behavior required that operators not short
|
|
circuit. The non-short circuiting behavior applies to all data types until HLSL
|
|
2021. In HLSL 2021, logical and ternary operators do not support vector types
|
|
instead builtin functions ``and``, ``or`` and ``select`` are available, and
|
|
operators short circuit matching C behavior.
|
|
|
|
Precise Qualifier
|
|
-----------------
|
|
|
|
HLSL has a ``precise`` qualifier that behaves unlike anything else in the C
|
|
language. The support for this qualifier in DXC is buggy, so our bar for
|
|
compatibility is low.
|
|
|
|
The ``precise`` qualifier applies in the inverse direction from normal
|
|
qualifiers. Rather than signifying that the declaration containing ``precise``
|
|
qualifier be precise, it signifies that the operations contributing to the
|
|
declaration's value be ``precise``. Additionally, ``precise`` is a misnomer:
|
|
values attributed as ``precise`` comply with IEEE-754 floating point semantics,
|
|
and are prevented from optimizations which could decrease *or increase*
|
|
precision.
|
|
|
|
Differences in Templates
|
|
------------------------
|
|
|
|
HLSL uses templates to define builtin types and methods, but disallowed
|
|
user-defined templates until HLSL 2021. HLSL also allows omitting empty template
|
|
parameter lists when all template parameters are defaulted. This is an ambiguous
|
|
syntax in C++, but Clang detects the case and issues a diagnostic. This makes
|
|
supporting the case in Clang minimally invasive.
|
|
|
|
Vector Extensions
|
|
-----------------
|
|
|
|
HLSL uses the OpenCL vector extensions, and also provides C++-style constructors
|
|
for vectors that are not supported by Clang.
|
|
|
|
Standard Library
|
|
----------------
|
|
|
|
HLSL does not support the C or C++ standard libraries. Like OpenCL, HLSL
|
|
describes its own library of built in types, complex data types, and functions.
|
|
|
|
Unsupported C & C++ Features
|
|
----------------------------
|
|
|
|
HLSL does not support all features of C and C++. In implementing HLSL in Clang
|
|
use of some C and C++ features will produce diagnostics under HLSL, and others
|
|
will be supported as language extensions. In general, any C or C++ feature that
|
|
can be supported by the DXIL and SPIR-V code generation targets could be treated
|
|
as a clang HLSL extension. Features that cannot be lowered to DXIL or SPIR-V,
|
|
must be diagnosed as errors.
|
|
|
|
HLSL does not support the following C features:
|
|
|
|
* Pointers
|
|
* References
|
|
* ``goto`` or labels
|
|
* Variable Length Arrays
|
|
* ``_Complex`` and ``_Imaginary``
|
|
* C Threads or Atomics (or Obj-C blocks)
|
|
* ``union`` types `(in progress for HLSL 202x) <https://github.com/microsoft/DirectXShaderCompiler/pull/4132>`_
|
|
* Most features C11 and later
|
|
|
|
HLSL does not support the following C++ features:
|
|
|
|
* RTTI
|
|
* Exceptions
|
|
* Multiple inheritance
|
|
* Access specifiers
|
|
* Anonymous or inline namespaces
|
|
* ``new`` & ``delete`` operators in all of their forms (array, placement, etc)
|
|
* Constructors and destructors
|
|
* Any use of the ``virtual`` keyword
|
|
* Most features C++11 and later
|