-
Notifications
You must be signed in to change notification settings - Fork 52
[0002] Detail attributes that will replace HLSL annotations #534
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
3662c1a
d0b4581
3e0433d
672bb51
517cb26
4c11ab3
5b55476
a740f8a
c2b3dc2
0e40bab
091c1eb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,7 +9,7 @@ params: | |
| --- | ||
|
|
||
|
|
||
|
|
||
| * Planned Version: 202y | ||
|
|
||
| ## Introduction | ||
|
|
@@ -86,7 +86,7 @@ above can be written as: | |
|
|
||
| ```c++ | ||
| struct { | ||
| uint i [[hlsl::SV_RenderTargetArrayIndex]]; | ||
| uint i [[hlsl::system_value(RenderTargetArrayIndex)]]; | ||
| } | ||
| ``` | ||
|
|
||
|
|
@@ -110,11 +110,11 @@ Below are a few more examples of C++ attributes that we could support: | |
|
|
||
| Texture2D<float4> Tex [[hlsl::register(1, 0)]]; // applies to `Tex`; | ||
|
|
||
| uint i [[hlsl::SV_RenderTargetArrayIndex]]; // applies to `i`. | ||
| [[hlsl::SV_RenderTargetArrayIndex]] uint j; // applies to `j`. | ||
| uint &[[hlsl::AddressSpace(1)]] Ref = ...; // applies to the type `uint &`. | ||
| uint i [[hlsl::system_value(RenderTargetArrayIndex)]]; // applies to `i`. | ||
| [[hlsl::system_value(RenderTargetArrayIndex)]] uint j; // applies to `j`. | ||
| uint &[[hlsl::address_space(1)]] Ref = ...; // applies to the type `uint &`. | ||
|
|
||
| [[hlsl::SV_Target]] // applies to the function `fn`. | ||
| [[hlsl::system_value(Target)]] // applies to the function `fn`. | ||
| float3 fn( ) { | ||
| [[hlsl::fast]] // applies to the compound expression `{...}`. | ||
| { | ||
|
|
@@ -233,6 +233,197 @@ following grammar formulations are valid: | |
| \terminal{using} \textit{identifier} \opt{attribute-specifier-seq} \terminal{=} \textit{type-id} \terminal{;}\br | ||
| \end{grammar} | ||
| ``` | ||
|
|
||
|  | ||
|
|
||
| ### Attribute Specification Language | ||
|
|
||
| Attributes annotate source constructs with information. An attribute is said to | ||
| be _applied to_ the entity or statement identified by the source construct. | ||
|
|
||
| Some attributes may be required by an implementation for correct code | ||
| generation, others may be optionally ignored. An implementation must issue a | ||
| diagnostic on all ignored attributes unless otherwise specified by the | ||
| definition of the attribute behavior. | ||
|
|
||
| > Note: an example here would be optimization hint attributes which an | ||
| > implementation is allowed to ignore without diagnosing. | ||
|
|
||
| Each attribute may define specific behavior for how its arguments are parsed. | ||
| Attributes that do not define custom parsing behavior shall be parsed according to the general rules outlined here. | ||
| > Note: The clause above enables attributes like the clang availability | ||
| > attribute which supports named parameters (e.g. | ||
| > `[[clang::availability(shadermodel, introduced=6.3)]]`), HLSL has a use for | ||
| > similar functionality. | ||
|
|
||
| An empty attribute specifier has no effect. The order in which attributes | ||
| applied to the same source construct are written shall not be significant. When | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So this means attribute overriding/duplication/conflict will be determined by each attribute definition? Like if I did
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yea, and conflicting attributes should generally be an error. |
||
| parsing attributes any token that satisfies the requirements of an identifier | ||
| shall be treated as an identifier even if it has alternate meaning outside the | ||
| attribute (e.g. keywords). Name lookup is not performed on identifiers within | ||
| _attribute-token_. The _attribute-token_ refers to the attribute being parsed, | ||
| which determines requirements for parsing the optional | ||
| _attribute-argument-clause_. | ||
|
|
||
| If an attribute is applied to an entity or statement for which the attribute is | ||
| not allowed to be applied, the program is ill-formed. | ||
|
|
||
| The behavior of _attribute-token_ not specified in this specification is | ||
| implementation-defined. | ||
|
|
||
| Two consecutive square bracket tokens shall only appear when introducing an | ||
| _attribute-specifier_. Any other occurrence of two consecutive square brackets is | ||
| ill-formed. | ||
hekota marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| ### Removal of HLSL Annotation Syntax | ||
|
|
||
| With the introduction of C++ attribute syntax the HLSL annotation syntax will be | ||
| removed from the language. In Clang, C++ attribute syntax can be supported in | ||
| both HLSL 202x and 202y language modes with deprecation warnings reported for the old HLSL annotation syntax, including fix-it and | ||
| rewriting tool support in Clang. This will allow easier migration of code from | ||
| HLSL 202x to 202y. This feature will not be supported in DXC. | ||
|
|
||
| The following new attributes are introduced to replace HLSL annotations. | ||
|
|
||
| #### hlsl::user_value(string[, int=0]) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In SPIR-V, we currently ignore the user semantics. We assign a location based on the order in which variables are declared, or using the This does does not really work for SPIR-V since we have no good way to turn the string into a location index. The only thing we do with the the user semantic is to keep it around for reflection information. I don't know if we want to try to come up with something like Maybe something like @Keenuts any more thoughts?
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've read this more as a 'rewrite' of the attribute form with a new syntax, but also assumed we'd need to ignore this in SPIR-V since Location index is independant from the user semantic. I think we could keep the split we have today and either use the parameter index ignoring the content, or ass vk-specific attributes for component/location.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I had been thinking of this as just replacing the semantic as captured in reflection for SPIRV. That's more or less all it really is for DX too although it is expressed into the signatures rather than shader reflection. I'd like to think more about how to handle location and component packing. |
||
|
|
||
| The new `hlsl::user_value` attribute replaces user-defined semantics. The first | ||
| argument to the attribute is a string which can contain any valid C-string. The | ||
| second optional value is an index. | ||
|
|
||
| Consider the following valid HLSL: | ||
|
|
||
| ```hlsl | ||
| struct VSOutput { | ||
| float2 TexCoord : TEXCOORD; | ||
| }; | ||
|
|
||
| float4 main(VSOutput input) : SV_TARGET { | ||
| return input.xyxy; | ||
| } | ||
| ``` | ||
|
|
||
| Under HLSL 202y this code will be rewritten as: | ||
|
|
||
| ```hlsl | ||
| struct VSOutput { | ||
| float2 TexCoord [[hlsl::user_value("TEXCOORD")]]; | ||
| }; | ||
|
|
||
| float4 main(VSOutput input) : [[hlsl::system_value(SV_Target)]] { | ||
| return input.xyxy; | ||
| } | ||
| ``` | ||
|
|
||
| #### hlsl::system_value(enum[, int=0]) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Keenuts Which system values have an index, and how do we handle those for SPIR-V in DXC?
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It depends on the system value: |
||
|
|
||
| The new `hlsl::system_value` attribute replaces system value semantics. The | ||
| first argument is an enumeration which specifies which system value is being | ||
| bound, and the second optional value is an index. | ||
|
|
||
| Consider the following valid HLSL: | ||
|
|
||
| ```hlsl | ||
| float4 main( float4 p : SV_Position ) : SV_Target2 { | ||
| return p; | ||
| } | ||
| ``` | ||
|
|
||
| Under HLSL 202y this code will be rewritten as: | ||
|
|
||
| ```hlsl | ||
| float4 main(float4 p [[hlsl::system_value(SV_Position)]]) [[hlsl::system_value(SV_Target, 2)]] { | ||
| return p; | ||
| } | ||
| ``` | ||
|
|
||
| #### hlsl::packoffset(int[, int=0]) | ||
|
|
||
| The new `hlsl::packoffset` attribute replaces the `packoffset` HLSL annotation. | ||
| The attribute takes one required and one optional integer arguments. The second | ||
| integer must be greater than or equal to 0 and less than or equal to 3. | ||
|
|
||
| The first value specifies the starting row for packing data, and the second | ||
| value specifies the starting column. Existing `packoffset` arguments written | ||
| `c<row>.<column_letter>` map to the new attribute as `hlsl::packoffset(<row>, | ||
| <column_index>)`, where `<column_index>` maps as in the table below. | ||
|
|
||
| | column_letter | column_index | | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. considering
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My reasoning for getting rid of the prefix character In terms of the column index. I can see an argument for it remaining a letter. I struggle a bit with it because it is effectively a sub-index to 32-bit offsets, which actually isn't valid for all types. For example you can't use an offset of
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess the other advantage that integers would have is that they can be integer constant expressions not just static values. So using integers would enable someone to do something like: We could also consider supporting either integers or identifiers. I'd be curious for @tex3d's thoughts here too.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yeah I wasn't concerned about dropping the I think it's not really an issue since we are also rewriting the rest of the attribute but its at least worth considering given the tools and guides written around the notion that the second value is a letter. I personally thing integer is simpler/clearer and think from a clean slate that it's the right decision, I just want to make sure we aren't negatively impacting users
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @V-FEXrt - I think you meant moving from
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah sorry, that's what I meant. I don't think it's an issue worth blocking over. Just something to consider |
||
| | ------------- | ------------ | | ||
| | x | 0 | | ||
| | y | 1 | | ||
| | z | 2 | | ||
| | w | 3 | | ||
|
|
||
| Consider the following valid HLSL: | ||
|
|
||
| ```hlsl | ||
| cbuffer CB { | ||
| float2 g1 : packoffset(c1); | ||
| float2 g2 : packoffset(c1.z); | ||
| } | ||
| ``` | ||
|
|
||
| Under HLSL 202y this code will be rewritten as: | ||
|
|
||
| ```hlsl | ||
| cbuffer CB { | ||
| float2 g1 [[hlsl::packoffset(1)]]; | ||
| float2 g2 [[hlsl::packoffset(1, 2)]]; | ||
| } | ||
| ``` | ||
|
|
||
| #### hlsl::binding(int[, int=0]) | ||
|
|
||
| The new `hlsl::binding` attribute replaces the `register` HLSL annotation. The | ||
| attribute takes one required and one optional integer arguments. The first | ||
| integer argument specifies the binding index. the second integer specifies | ||
| the binding scope of the binding index. The interpretation of this attribute is | ||
| defined by the target runtime's binding model. | ||
|
|
||
| In DirectX, the first value maps as the register value, and the second the | ||
| register space. DirectX scopes bindings by resource class, allowing the same | ||
| register and space assignments to be specified for resources of different types | ||
| (e.g. a UAV and SRV may have the same register and space values without | ||
| aliasing). | ||
|
|
||
| In Vulkan, the first value maps as the binding index, and the second maps as the | ||
| descriptor set index. | ||
|
|
||
| Consider the following valid HLSL: | ||
|
|
||
| ```hlsl | ||
| SamplerState samp1 : register(s5); | ||
| Texture2D tex1 : register(t0, space3); | ||
| RWByteAddressBuffer buf1 : register(u4, space1); | ||
| ``` | ||
|
|
||
| Under HLSL 202y this code will be rewritten as: | ||
|
|
||
| ```hlsl | ||
| SamplerState samp1 [[hlsl::binding(5)]]; | ||
| Texture2D tex1 [[hlsl::binding(0, 3)]]; | ||
| RWByteAddressBuffer buf1 [[hlsl::binding(4, 1)]]; | ||
| ``` | ||
|
|
||
| #### hlsl::payload_access(<enum>, ...) | ||
|
|
||
| The new `hlsl::payload_access` attribute replaces the `read` and `write` HLSL | ||
| annotations for raytracing payload access qualifiers. The attribute takes an | ||
| enum value specifying `read` or `write` to denote the type of access and a | ||
| variable argument list of enumeration values specifying the stage that the | ||
| access qualifier applies to. Consider the following currently valid HLSL: | ||
|
|
||
| ```hlsl | ||
| struct [raypayload] Payload { | ||
| float f : read(caller, anyhit) : write(caller, anyhit); | ||
| }; | ||
| ``` | ||
|
|
||
| Under HLSL 202y this code will be rewritten as: | ||
|
|
||
| ```hlsl | ||
| using namespace hlsl; | ||
| struct [[raypayload]] Payload { | ||
| float f [[payload_access(read, caller, anyhit), payload_access(write, caller, anyhit)]]; | ||
| }; | ||
| ``` | ||
hekota marked this conversation as resolved.
Show resolved
Hide resolved
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rendering error?
