Skip to content

Commit

Permalink
Fix INF proposal numbering and pages build (#289)
Browse files Browse the repository at this point in the history
We already have an INF-0004 proposal, so this should be INF-0005, and
the starting raw tag was deleted which caused the GitHub pages build to
fail.
  • Loading branch information
llvm-beanz authored Jul 30, 2024
1 parent c2f89a4 commit c5097b0
Showing 1 changed file with 32 additions and 31 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
* Proposal: [0004](INF-0004-register-types-and-diagnostics.md)
<!-- {% raw %} -->
* Proposal: [INF-0005](INF-0005-register-types-and-diagnostics.md)
* Author(s): [Joshua Batista](https://github.com/bob80905)
* Sponsor: TBD
* Status: **Under Consideration**
Expand All @@ -14,8 +15,8 @@ For example:
RWBuffer<float> rwbuf : register(u0);
```
In this syntax, `: register(u0)` indicates a resource binding location for a
UAV resource. Further, the resource type (or variable type) is `RWBuffer`, with a
resource element type of `float` being declared as the variable `rwbuf`.
UAV resource. Further, the resource type (or variable type) is `RWBuffer`, with a
resource element type of `float` being declared as the variable `rwbuf`.
The register type is `u` and the register number is `0`.
There are a variety of rules for register bindings that require compiler
diagnostics. This document proposes a clear set of rules and diagnostics for
Expand All @@ -36,43 +37,43 @@ For example, in the case of:
`float b : register(u4);`

an error will be emitted recommending the use of the 'b, c, or i' register
type. However the 'i' register type is no longer in support, and the 'b'
type. However the 'i' register type is no longer in support, and the 'b'
register type is only reserved for resource types that are constant buffers.
It is worth noting that there is an overloading of the register(...) keyword
using the 'c' register type to indicate an offset into a constant buffer for
numeric types only, as opposed to specifying a resource binding.
Additionally, it is possible the user is unaware that this variable won't
actually be used as a resource, but the compiler doesn't communicate that
to the user. We should make it clear in this document which variables are
Additionally, it is possible the user is unaware that this variable won't
actually be used as a resource, but the compiler doesn't communicate that
to the user. We should make it clear in this document which variables are
compatible with which register types.

## Proposed Solution

The resource binding attribute will be attached to any declaration object (Decl)
that has the `: register(...)` annotation. In Sema, this attribute has a function to
validate its correctness, called `handleResourceBindingAttr`, within
`clang\lib\Sema\SemaHLSL.cpp`. The diagnostic infrastructure will be implemented
validate its correctness, called `handleResourceBindingAttr`, within
`clang\lib\Sema\SemaHLSL.cpp`. The diagnostic infrastructure will be implemented
within this validation function to analyze the declaration that the annotation
is applied to, and validate that the register type used within the annotation is semantically
compatible with the Decl. All of this analysis and validation will be executed
inside a new function, `DiagnoseHLSLRegisterAttribute`. This function will be
responsible for validating the semantic meaning behind the application of the
attribute, while the rest of `handleResourceBindingAttr` is responsible for
attribute, while the rest of `handleResourceBindingAttr` is responsible for
validating the syntax of the attribute.

### Recognized Register Types

There are two types of register bindings, resource bindings and constant register bindings.

Resource register bindings bind a resource like a texture or sampler to a location that is
Resource register bindings bind a resource like a texture or sampler to a location that is
mapped using the root signature in DX12.

Constant register bindings were originally used to bind values to one of three specialized
constant register banks in DX9. In DX10 and above, the `c` register binding for the `float`
register bank maps to an offset into the `$Globals` constant buffer and the other two bindings
Constant register bindings were originally used to bind values to one of three specialized
constant register banks in DX9. In DX10 and above, the `c` register binding for the `float`
register bank maps to an offset into the `$Globals` constant buffer and the other two bindings
are unused.

This table lists the recognized register types, the associated resource class if applicable,
This table lists the recognized register types, the associated resource class if applicable,
along with some brief notes.

| Register | Resource | Notes |
Expand All @@ -82,7 +83,7 @@ along with some brief notes.
| `s` | Sampler | `SamplerState` or `SamplerComparisonState` |
| `b` | CBV | `cbuffer`/`ConstantBuffer` resource; also unsupported legacy `bool` constant register |
| `c` | N/A | legacy `float` constant register - offset into `$Globals` |
| `i` | N/A | unsupported legacy `int` constant register
| `i` | N/A | unsupported legacy `int` constant register

### Register binding contexts

Expand All @@ -97,29 +98,29 @@ Register bindings may be applied to declarations in several contexts. This tabl
| (array of) scalar, vector, or matrix numeric or bool types | `c` | global outside `cbuffer` or `tbuffer` decl | `c` specifies starting location for numeric/bool values in `$Globals` constant buffer |


`DiagnoseHLSLRegisterAttribute` will validate that the variable type is bound using the
expected register type. `DiagnoseHLSLRegisterAttribute` will be
`DiagnoseHLSLRegisterAttribute` will validate that the variable type is bound using the
expected register type. `DiagnoseHLSLRegisterAttribute` will be
responsible for determining if register types are used correctly in certain
legacy contexts, or whether such uses are invalid. Specifically, the `c` register
type may only be used in global contexts. In those contexts, a resource isn't being bound,
rather a variable is being placed in the $Globals buffer with a specified offset.
Using `c` within a cbuffer or tbuffer is legacy behavior that should no longer be
supported, so `DiagnoseHLSLRegisterAttribute` will emit a warning in this case
Using `c` within a cbuffer or tbuffer is legacy behavior that should no longer be
supported, so `DiagnoseHLSLRegisterAttribute` will emit a warning in this case
that will be treated as an error by default. When this attribute appears in a non-global
context, `packoffset` will be recommended as an alternative.
The `i` register type is also a legacy DirectX 9 register type that
The `i` register type is also a legacy DirectX 9 register type that
will no longer be supported, and so a warning will be emitted that is treated
as an error by default when this register type is used.
The `b` register type, when used on a variable that isn't a resource, and doesn't
have a `CBuffer` resource class, is also legacy behavior that will no longer be
supported. In such cases, a warning will be emitted that is treated as an error by
default, and a suggestion will be made that the register type is only used for resources with
the `CBuffer` resource class.
These warnings are all part of a distinct warning group, `LegacyConstantRegisterBinding`
These warnings are all part of a distinct warning group, `LegacyConstantRegisterBinding`
which can be silenced if a developer would prefer to enable compilation of legacy shaders.

Another common case for this annotation to appear in HLSL is for user-defined-types (UDTs).
UDTs may have multiple register annotations applied onto the variable declaration.
UDTs may have multiple register annotations applied onto the variable declaration.
`DiagnoseHLSLRegisterAttribute` will be responsible for ensuring that none of the
register annotations conflict (none may have the same register type). `DiagnoseHLSLRegisterAttribute`
will also ensure that any register annotations with a specific register type applied to
Expand All @@ -129,15 +130,15 @@ is no corresponding member, a warning will be emitted that is treated as an erro
because this behavior was permissible in legacy versions of the compiler. These warnings
are also part of the same warning group, `LegacyConstantRegisterBinding`.

`DiagnoseHLSLRegisterAttribute` will also be responsible for emitting a diagnostic
if any other invalid register type is detected. If `DiagnoseHLSLRegisterAttribute`
finds any critical errors, the attribute, `HLSLResourceBindingAttr`, won't be added
`DiagnoseHLSLRegisterAttribute` will also be responsible for emitting a diagnostic
if any other invalid register type is detected. If `DiagnoseHLSLRegisterAttribute`
finds any critical errors, the attribute, `HLSLResourceBindingAttr`, won't be added
to the Decl, and compilation will fail. However, `DiagnoseHLSLRegisterAttribute` may
emit some warnings and allow the attribute to be attached. In summary,
`DiagnoseHLSLRegisterAttribute` will be responsible for analyzing the context of the
emit some warnings and allow the attribute to be attached. In summary,
`DiagnoseHLSLRegisterAttribute` will be responsible for analyzing the context of the
decl to which the register annotation is being applied, and using the data in the
annotation to determine what diagnostics, if any, to emit.
`DiagnoseHLSLRegisterAttribute` will be fully responsible for halting compilation
annotation to determine what diagnostics, if any, to emit.
`DiagnoseHLSLRegisterAttribute` will be fully responsible for halting compilation
if there is any semantic fault in the application of the register annotation.


Expand All @@ -151,4 +152,4 @@ TODO: Fill out and agree on detailed design
* Justin Bogner
* Damyan Pepper
* Farzon Lotfi
<!-- {% endraw %} -->
<!-- {% endraw %} -->

0 comments on commit c5097b0

Please sign in to comment.