Closes#108058.
This PR:
- Adds the `uint` `Load` and `Store` methods (`Load/Store`,
`Load2/Store2`, `Load3/Store3`, `Load4/Store4`) to the existing
`ByteAddressBuffer` objects
- Adds the new templated `Load` and `Store` methods to
`ByteAddressBuffer` objects, which allow types other than `uint` (e.g.
aggregate types) to be used with them directly
- One exception to this is array types, which are rejected by the
methods (as array returns will be disallowed in 202x)
- Adds the relevant `AST`, `CodeGenHLSL`, and `SemaHLSL` tests for these
methods
*Note: the `HLSL Tests` check is failing because this implementation
makes the `ByteAddressBuffer` tests XPASS. Will remove the XFAILs from
these tests in a follow-up.*
During the declaration of HLSL resource types, we add a delay to the
completion of such declarations to happen during
`HLSLExternalSemaSource::CompleteType`. Such might cause the parser to
declare the resources twice, like here
https://hlsl.godbolt.org/z/aT4b1Goeb, triggering an assert.
This patch fixes this issue by removing the resources out of the
completions declaration list once they are declared.
Fix: #153619
This patch implements the `Texture2D` resource type and its `Sample`
member
function in Clang. It includes the necessary AST and Sema changes to
support
the new type and its built-in methods, as well as CodeGen support for
both
DirectX and SPIR-V targets.
Key changes:
- Added `ResourceDimension` to `HLSLAttributedResourceType` and
`HLSLResourceDimension` attribute.
- Implemented `Texture2D` and `SamplerState` in
`HLSLExternalSemaSource`.
- Added `__builtin_hlsl_resource_sample` and associated Sema checking.
- Updated `DirectXTargetCodeGenInfo` and `CommonSPIRTargetCodeGenInfo`
to handle texture types.
- Added AST, Sema, and CodeGen tests for `Texture2D`.
Part 2 of https://github.com/llvm/llvm-project/issues/175630
Adds `GetDimensions` methods to all supported buffer resource classes (`{RW}Buffer`, `*StructuredBuffer`, `{RW}ByteAddressBuffer`). The method is implemented by calling one of both built-in functions `__builtin_hlsl_resource_getdimensions_x` and `__builtin_hlsl_resource_getstride` as described in proposal https://github.com/llvm/wg-hlsl/pull/350.
The `__builtin_hlsl_resource_getstride` is implemented directly by Clang codegen by setting the buffer stride to the output variable.
The `__building_hlsl_buffer_getdimensions` built-in function gets translated to LLVM intrinsic `@llvm.dx.resource.getdimensions.x`.
Closes#112984
fixes#160190fixes#116710
This change just makes MaxMatrixDimension configurable by language mode.
It was previously introduced in
94b43118e2
when there was not a need to make dimensions configurable.
Current testing to this effect exists in:
- clang/test/Sema/matrix-type-builtins.c
- clang/test/SemaCXX/matrix-type-builtins.cpp
- clang/test/SemaHLSL/BuiltIns/matrix-basic_types-errors.hlsl
New Tests to confirm configurability by language mode:
- clang/unittests/Frontend/CompilerInvocationTest.cpp
I considered adding a driver flag to
`clang/include/clang/Driver/Options.td` but HLSL matrix max dim is
always 4 so we don't need this configurable beyond that size for our use
case.
This commit implements the Sema and CodeGen portions of the typed buffer
counter proposal described in the HLSL WG proposal 0023.
This change introduces the necessary Sema and CodeGen logic to handle
implicit counter variables for typed buffers. This includes:
- Extending `HLSLResourceBindingAttr` to store the implicit counter
binding order ID.
- Introducing the
`__builtin_hlsl_resource_counterhandlefromimplicitbinding`
builtin.
- Updating `SemaHLSL` to correctly initialize global resource
declarations
and resource arrays with implicit counter buffers.
- Adding CodeGen support for the new builtin, which generates a
`llvm.spv.resource.counterhandlefromimplicitbinding` intrinsic for the
SPIR-V target and aliases the main resource handle for the DXIL target.
- Adding and updating tests to verify the new functionality.
Fixes#137032
This is part 1 of implementing the typed buffer counters proposal:
https://github.com/llvm/wg-hlsl/blob/main/proposals/0023-typed-buffer-counters.md
This patch adds the initial plumbing for supporting counter variables
associated with structured buffers for the SPIR-V backend. It introduces
an `IsCounter` attribute to `HLSLAttributedResourceType` and threads it
through the AST, type printing, and mangling. It also adds a
`__counter_handle` member to the relevant buffer types in
`HLSLBuiltinTypeDeclBuilder`.
Contributes to https://github.com/llvm/llvm-project/issues/137032
fixes#109839
This change is really simple. It creates a matrix alias that will let
HLSL use the existing clang `matrix_type` infra.
The only additional change was to add explict alias for the typed
dimensions of 1-4 inclusive matricies available in HLSL.
Testing therefore is limited to exercising the alias, sema errors, and
basic codegen.
future work will add things like constructors and accessors.
The main difference in this attempt is the type printer and less of an
emphasis on tests where things overlap with existing `matrix_type`
testing like cast behavior.
Removes resource constructors that take binding information per proposal update https://github.com/llvm/wg-hlsl/pull/336. The constructors are replaced by static `__createFromBinding` and `__createFromImplicitBinding` methods on the resource class.
Adds static methods `__createFromBinding` and `__createFromImplicitBinding` to resource classes. These methods will be
used for resource initialization instead of resource constructors that take binding information.
Updated proposal: https://github.com/llvm/wg-hlsl/pull/336
The wrapper used to hold the handle for resource type has just the
default copy constructor and assignment operator. This causes clang to
insert memcpys when it does an assignment of a resource type. The
memcpy then cause optimizations to fail when the memcpy is turned into a
load and store of an i64.
To fix this, we should define copying of a resource type by adding the
operator= and copy constructor.
Partially fixes#154669
This reintroduces `Type.h`, having earlier been renamed to `TypeBase.h`,
as a redirection to `TypeBase.h`, and redirects most users to include
the former instead.
This is a preparatory patch for being able to provide inline definitions
for `Type` methods which would otherwise cause a circular dependency
with `Decl{,CXX}.h`.
Doing these operations into their own NFC patch helps the git rename
detection logic work, preserving the history.
This patch makes clang just a little slower to build (~0.17%), just
because it makes more code indirectly include `DeclCXX.h`.
This is a preparatory patch, to be able to provide inline definitions
for `Type` functions which depend on `Decl{,CXX}.h`. As the latter also
depends on `Type.h`, this would not be possible without some
reorganizing.
Splitting this rename into its own patch allows git to track this as a
rename, and preserve all git history, and not force any code
reformatting.
A later NFC patch will reintroduce `Type.h` as redirection to
`TypeBase.h`, rewriting most places back to directly including `Type.h`
instead of `TypeBase.h`, leaving only a handful of places where this is
necessary.
Then yet a later patch will exploit this by making more stuff inline.
Adds constructor for resources with implicit binding and applies it to
all resources without binding at the global scope.
Adds Clang builtin function
`__builtin_hlsl_resource_handlefromimplicitbinding` that gets translated
to `llvm.dx|spv.resource.handlefromimplicitbinding` intrinsic calls.
Specific bindings are assigned in DXILResourceImplicitBinding pass.
Design proposals:
https://github.com/llvm/wg-hlsl/blob/main/proposals/0024-implicit-resource-binding.mdhttps://github.com/llvm/wg-hlsl/blob/main/proposals/0025-resource-constructors.md
One change from the proposals is that the `orderId` parameter is added
onto the constructor. Originally it was supposed to be generated in
codegen when the `llvm.dx|spv.resource.handlefromimplicitbinding` call
is emitted, but that is not possible because the call is inside a
constructor, and the constructor body is generated once per resource
type and not resource instance. So the only way to inject instance-based
data like `orderId` into the
`llvm.dx|spv.resource.handlefromimplicitbinding` call is that it must
come in via the constructor argument.
Closes#136784
- Adds resource constructor that takes explicit binding for all resource
classes.
- Updates implementation of default resource constructor to initialize
resource handle to `poison`.
- Removes initialization of resource classes from Codegen.
- Initialization of `cbuffer` still needs to happen in `CGHLSLRuntime`
because it does not have a corresponding resource class type.
- Adds `ImplicitCastExpr` for builtin function calls. Sema adds these
automatically when a method of a template class is instantiated, but
some resource classes like `ByteAddressBuffer` are not templates so they
need to have this added explicitly.
Design proposal: llvm/wg-hlsl#197
Closes#134154
Moving builder classes into separate files
`HLSLBuiltinTypeDeclBuilder.cpp`/`.h`, changing a some
`HLSLExternalSemaSource` methods to private and removing unused methods.
This is a prep work before we start adding more builtin types and
methods, like textures, resource constructors or matrices. For example
constructors could make use of the `BuiltinTypeMethodBuilder`, but this
helper class was defined in `HLSLExternalSemaSource.cpp` after the
method that creates a constructor. Rather than reshuffling the code one
big source file I am moving the builders into a separate cpp & header
file and placing the helper classes declarations up top.
Currently the new header only exposes `BuiltinTypeDeclBuilder` to
`HLSLExternalSemaSource`. In the future but we might decide to expose
more helper classes as needed.
Adds `T Load(int)` method on `StructuredBuffer`, `RWStructuredBuffer`
and `RasterizerOrderedStructuredBuffer`.
Uses the existing `addLoadMethods` in HLSLExternalSemalSource so most of
this change is just tests.
Fixes#112977
Class BuiltinTypeMethodBuilder has a user-defined destructor so likely
compiler generated special functions may behave incorrectly. Delete
explicitly copy constructor and copy assignment operator to avoid
potential errors.
The methods are using existing clang builtins
`__builtin_hlsl_buffer_update_counter` and
`__builtin_hlsl_resource_getpointer` to update the buffer counter and
then load or store the value.
Fixes#112968
This is the first one in a series of PRs adding the requirements for
#58654
This PR adds `ByteAddressBuffer`, `RWByteAddressBuffer ` and
`RasterizerOrderedByteAddressBuffer ` definitions as well as their
handle lowering to `dx.RawBuffer`.
closes#58654
---------
Co-authored-by: Joao Saffran <jderezende@microsoft.com>
This introduces `__builtin_hlsl_resource_getpointer`, which lowers to
`llvm.dx.resource.getpointer` and is used to implement indexing into
resources.
This will only work through the backend for typed buffers at this point,
but the changes to structured buffers should be correct as far as the
frontend is concerned.
Note: We probably want this to return a reference in the HLSL device
address space, but for now we're just using address space 0. Creating a
device address space and updating this code can be done later as
necessary.
Fixes#95956
Introduce BuiltinTypeMethodBuilder::PlaceHolder values and use them in
the callBuiltin method in order to specify how we want to forward
arguments and pass the resource handle to builtins.
Introduces `__builtin_hlsl_buffer_update_counter` clang buildin that is
used to implement the `IncrementCounter` and `DecrementCounter` methods
on `RWStructuredBuffer` and `RasterizerOrderedStructuredBuffer` (see
Note).
The builtin is translated to LLVM intrisic `llvm.dx.bufferUpdateCounter`
or `llvm.spv.bufferUpdateCounter`.
Introduces `BuiltinTypeMethodBuilder` helper in `HLSLExternalSemaSource`
that enables adding methods to builtin types using builder pattern like
this:
```
BuiltinTypeMethodBuilder(Sema, RecordBuilder, "MethodName", ReturnType)
.addParam("param_name", Type, InOutModifier)
.callBuiltin("buildin_name", { BuiltinParams })
.finalizeMethod();
```
Fixes#113513
[First version](llvm/llvm-project#114148) of this PR was reverted
because of build break.
Introduces `__builtin_hlsl_buffer_update_counter` clang buildin that is
used to implement the `IncrementCounter` and `DecrementCounter` methods
on `RWStructuredBuffer` and `RasterizerOrderedStructuredBuffer` (see
Note).
The builtin is translated to LLVM intrisic `llvm.dx.bufferUpdateCounter`
or `llvm.spv.bufferUpdateCounter`.
Introduces `BuiltinTypeMethodBuilder` helper in `HLSLExternalSemaSource`
that enables adding methods to builtin types using builder pattern like
this:
```
BuiltinTypeMethodBuilder(Sema, RecordBuilder, "MethodName", ReturnType)
.addParam("param_name", Type, InOutModifier)
.callBuiltin("buildin_name", { BuiltinParams })
.finalizeMethod();
```
Fixes#113513
This PR is step one on the journey to implement resource element type
validation via C++20 concepts. The PR sets up the infrastructure for
injecting implicit concept decls / concept specialization expressions
into the AST, which will then be evaluated after template arguments are
instantiated. This is not meant to be a complete implementation of the
desired validation for HLSL,
there are a couple of missing elements:
We need the __builtin_hlsl_is_typed_resource_element_compatible builtin
to be implemented.
We need other constraints, like is_intangible
We need to put the first 2 points together, and construct a finalized
constraint expression, which should differ between typed and raw buffers
This is just an initial PR that puts some of the core infrastructure in
place.
This PR is an edit of #112600, so that new tests that were put into main
don't fail
Fixes#75676
This PR is step one on the journey to implement resource element type
validation via C++20 concepts. The PR sets up the infrastructure for
injecting implicit concept decls / concept specialization expressions
into the AST, which will then be evaluated after template arguments are
instantiated. This is not meant to be a complete implementation of the
desired validation for HLSL,
there are a couple of missing elements:
1. We need the __builtin_hlsl_is_typed_resource_element_compatible
builtin to be implemented.
2. We need other constraints, like is_intangible
3. We need to put the first 2 points together, and construct a finalized
constraint expression, which should differ between typed and raw buffers
This is just an initial PR that puts some of the core infrastructure in
place.
Adds `AppendStructuredBuffer` and `ConsumeStructuredBuffer` definition
to HLSLExternalSemaSource. Adds separate tests for the AST shape and
element types, and adds constructor/handle.fromBinding test case to
shared test file for structured buffers.
These buffers do not have any subscript operators. Append and Consume
methods will be added later in llvm/llvm-project#112968.
Fixes#112777
Adds `RasterizerOrderedStructuredBuffer` definition to
HLSLExternalSemaSource. Adds separate tests for the AST shape and
element types. Adds constructor/handle.fromBinding and subscript test
cases to shared test file for structured buffers. Additional methods
will be added later.
Fixes#112776
Add tests for RWStructuredBuffer class definition. Use shared test files
for all structured buffers' constructor and subscript tests. Keep AST
and element-type tests separate for each buffer type because they longer
and failures would be harder to match.
Fixes#112775
Translates `RWBuffer` and `StructuredBuffer` resources buffer types to
DirectX target types `dx.TypedBuffer` and `dx.RawBuffer`.
Includes a change of `HLSLAttributesResourceType` from 'sugar' type to
full canonical type. This is required for codegen and other clang
infrastructure to work property on HLSL resource types.
Fixes#95952 (part 2/2)
Replace `element_type*` handles in HLSLExternalSemaSource with
`__hlsl_resource_t` builtin type.
The handle used to be defined as `element_type*` which was used by the
provisional subscript operator implementation. Now that the handle is
`__hlsl_resource_t` the subscript placeholder implementation was updated
to add `element_type* e;` field to the resource struct. and return a
reference to that. This field is just a temporary workaround until the
indexing is implemented properly in llvm/llvm-project#95956, at which
point the field will be removed. This seemed like a better solution than
disabling many of the existing tests that already use the `[]` operator.
One test has to be disabled nevertheless because an error based on
interactions of const and template instantiation (potential bug that can
be investigated once indexing is implemented the right way).
Fixes#84824
The `__builtin_hlsl_create_handle` called from the constructor of
resource buffer class was supposed to initialize the resource handle
based on resource type and registry binding information. It is not
possible to do though that because the registry binding information is
not accessible from the constructor during codegen.
Instead, the handle should be initialized to an empty or null handle
with something like `__builtin_hlsl_create_null_handle`. This PR is
removing `__builtin_hlsl_create_handle` first and the
`__builtin_hlsl_create_null_handle` will be added to the constructor
once the handle type changes to `__hlsl_resource_t` and
HLSLAttributeResourceType is updated to be a canonical type, which will
allow the initialization assignment.
The actual handle initialization based on the registry binding will be
implemented part 2/2 of llvm/llvm-project#105076 once the dependent
tasks are completed.
Part 1/2 of llvm/llvm-project#105076.
This PR introduces new HLSL resource type attribute
`[[hlsl::raw_buffer]]`. Presence of this attribute on a resource handle
means that the resource does not require typed element access. The
attribute will be used on resource handles that represent buffers like
`StructuredBuffer` or `ByteAddressBuffer` and in DXIL it will be
translated to target extension type `dx.RawBuffer`.
Fixes#107907
Introducing a new HLSL resource type attribute `[[contained_type(T)]]`
which describes the "contained type" of a buffer or resource type.
Specifically, the attribute will be used on the resource handle in
templated buffer types like so:
template <typename T> struct RWBuffer {
__hlsl_resource_t [[hlsl::contained_type(T)]] [[hlsl::resource_class(UAV)]] h;
};
Fixes#104855
This PR adds `StructuredBuffer` to `HLSLExternalSemaSource.cpp`, by
copying the logic from RWBuffer but just replacing the name with
StructuredBuffer. The change now allows StructuredBuffers to be defined
in HLSL, though they function the same as RWBuffers.
Further work to apply the appropriate attributes that distinguish
StructuredBuffers from other Buffer types will be deferred.
This improves our position on
https://github.com/llvm/llvm-project/issues/106189
Converts existing resource attributes `[[hlsl::resource_class(..)]]` and
`[[is_rov]]` from declaration attributes to type attributes.
During type attribute processing all HLSL resource type attributes are
validated and collected by `SemaHLSL`
(`SemaHLSL::handleResourceTypeAttr`). At the end of the declaration they
are be combined into a single `HLSLAttributedResourceType` instance
(`SemaHLSL::ProcessResourceTypeAttributes`) that wraps the original type
and stores all of the necessary information about the resource.
`SemaHLSL` will also need to short-term-store the `TypeLoc` information
for the newly created type that will be grabbed by `TypeSpecLocFiller`
soon after it is created.
Updates all places that expected resource attributes on declarations
like resource binding diagnostic, builtin types in
HLSLExternalSemaSource, or codegen.
Also includes implementation of
`TreeTransform<Derived>::TransformHLSLAttributedResourceType` that
enables the use of attributed resource types inside templates.
Fixes#104861
Part 2/2
There are currently no diagnostics being emitted for when a resource is
bound to a register with an incorrect binding type prefix. For example,
a CBuffer type resource should be bound with a a binding type prefix of
'b', but if instead the prefix is 'u', no errors will be emitted. This
PR implements such diagnostics. The focus of this PR is to implement
both the flag setting and diagnostic emisison steps specified in the
relevant spec: https://github.com/microsoft/hlsl-specs/pull/230
The relevant issue is: https://github.com/llvm/llvm-project/issues/57886
This is a continuation / refresh of this PR:
https://github.com/llvm/llvm-project/pull/87578