Skip to content

Commit 7165566

Browse files
llvm-beanzhekota
andauthored
[0002] Detail attributes that will replace HLSL annotations (microsoft#534)
This adds language about removing HLSL annotation syntax as well as some proposed specification language. It also details the specific transformations of HLSL annotation attributes to general attributes. Fixes microsoft#527 --------- Co-authored-by: Helena Kotas <[email protected]>
1 parent 65815b0 commit 7165566

File tree

1 file changed

+198
-7
lines changed

1 file changed

+198
-7
lines changed

proposals/0002-cxx-attributes.md

Lines changed: 198 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ params:
99
---
1010

1111

12-
12+
1313
* Planned Version: 202y
1414

1515
## Introduction
@@ -86,7 +86,7 @@ above can be written as:
8686
8787
```c++
8888
struct {
89-
uint i [[hlsl::SV_RenderTargetArrayIndex]];
89+
uint i [[hlsl::system_value(RenderTargetArrayIndex)]];
9090
}
9191
```
9292

@@ -110,11 +110,11 @@ Below are a few more examples of C++ attributes that we could support:
110110

111111
Texture2D<float4> Tex [[hlsl::register(1, 0)]]; // applies to `Tex`;
112112

113-
uint i [[hlsl::SV_RenderTargetArrayIndex]]; // applies to `i`.
114-
[[hlsl::SV_RenderTargetArrayIndex]] uint j; // applies to `j`.
115-
uint &[[hlsl::AddressSpace(1)]] Ref = ...; // applies to the type `uint &`.
113+
uint i [[hlsl::system_value(RenderTargetArrayIndex)]]; // applies to `i`.
114+
[[hlsl::system_value(RenderTargetArrayIndex)]] uint j; // applies to `j`.
115+
uint &[[hlsl::address_space(1)]] Ref = ...; // applies to the type `uint &`.
116116

117-
[[hlsl::SV_Target]] // applies to the function `fn`.
117+
[[hlsl::system_value(Target)]] // applies to the function `fn`.
118118
float3 fn( ) {
119119
[[hlsl::fast]] // applies to the compound expression `{...}`.
120120
{
@@ -233,6 +233,197 @@ following grammar formulations are valid:
233233
\terminal{using} \textit{identifier} \opt{attribute-specifier-seq} \terminal{=} \textit{type-id} \terminal{;}\br
234234
\end{grammar}
235235
```
236-
237236
![Latex Rendering](0002-assets/ClassGrammarRender.png)
238237

238+
### Attribute Specification Language
239+
240+
Attributes annotate source constructs with information. An attribute is said to
241+
be _applied to_ the entity or statement identified by the source construct.
242+
243+
Some attributes may be required by an implementation for correct code
244+
generation, others may be optionally ignored. An implementation must issue a
245+
diagnostic on all ignored attributes unless otherwise specified by the
246+
definition of the attribute behavior.
247+
248+
> Note: an example here would be optimization hint attributes which an
249+
> implementation is allowed to ignore without diagnosing.
250+
251+
Each attribute may define specific behavior for how its arguments are parsed.
252+
Attributes that do not define custom parsing behavior shall be parsed according to the general rules outlined here.
253+
> Note: The clause above enables attributes like the clang availability
254+
> attribute which supports named parameters (e.g.
255+
> `[[clang::availability(shadermodel, introduced=6.3)]]`), HLSL has a use for
256+
> similar functionality.
257+
258+
An empty attribute specifier has no effect. The order in which attributes
259+
applied to the same source construct are written shall not be significant. When
260+
parsing attributes any token that satisfies the requirements of an identifier
261+
shall be treated as an identifier even if it has alternate meaning outside the
262+
attribute (e.g. keywords). Name lookup is not performed on identifiers within
263+
_attribute-token_. The _attribute-token_ refers to the attribute being parsed,
264+
which determines requirements for parsing the optional
265+
_attribute-argument-clause_.
266+
267+
If an attribute is applied to an entity or statement for which the attribute is
268+
not allowed to be applied, the program is ill-formed.
269+
270+
The behavior of _attribute-token_ not specified in this specification is
271+
implementation-defined.
272+
273+
Two consecutive square bracket tokens shall only appear when introducing an
274+
_attribute-specifier_. Any other occurrence of two consecutive square brackets is
275+
ill-formed.
276+
277+
### Removal of HLSL Annotation Syntax
278+
279+
With the introduction of C++ attribute syntax the HLSL annotation syntax will be
280+
removed from the language. In Clang, C++ attribute syntax can be supported in
281+
both HLSL 202x and 202y language modes with deprecation warnings reported for the old HLSL annotation syntax, including fix-it and
282+
rewriting tool support in Clang. This will allow easier migration of code from
283+
HLSL 202x to 202y. This feature will not be supported in DXC.
284+
285+
The following new attributes are introduced to replace HLSL annotations.
286+
287+
#### hlsl::user_value(string[, int=0])
288+
289+
The new `hlsl::user_value` attribute replaces user-defined semantics. The first
290+
argument to the attribute is a string which can contain any valid C-string. The
291+
second optional value is an index.
292+
293+
Consider the following valid HLSL:
294+
295+
```hlsl
296+
struct VSOutput {
297+
float2 TexCoord : TEXCOORD;
298+
};
299+
300+
float4 main(VSOutput input) : SV_TARGET {
301+
return input.xyxy;
302+
}
303+
```
304+
305+
Under HLSL 202y this code will be rewritten as:
306+
307+
```hlsl
308+
struct VSOutput {
309+
float2 TexCoord [[hlsl::user_value("TEXCOORD")]];
310+
};
311+
312+
float4 main(VSOutput input) : [[hlsl::system_value(SV_Target)]] {
313+
return input.xyxy;
314+
}
315+
```
316+
317+
#### hlsl::system_value(enum[, int=0])
318+
319+
The new `hlsl::system_value` attribute replaces system value semantics. The
320+
first argument is an enumeration which specifies which system value is being
321+
bound, and the second optional value is an index.
322+
323+
Consider the following valid HLSL:
324+
325+
```hlsl
326+
float4 main( float4 p : SV_Position ) : SV_Target2 {
327+
return p;
328+
}
329+
```
330+
331+
Under HLSL 202y this code will be rewritten as:
332+
333+
```hlsl
334+
float4 main(float4 p [[hlsl::system_value(SV_Position)]]) [[hlsl::system_value(SV_Target, 2)]] {
335+
return p;
336+
}
337+
```
338+
339+
#### hlsl::packoffset(int[, int=0])
340+
341+
The new `hlsl::packoffset` attribute replaces the `packoffset` HLSL annotation.
342+
The attribute takes one required and one optional integer arguments. The second
343+
integer must be greater than or equal to 0 and less than or equal to 3.
344+
345+
The first value specifies the starting row for packing data, and the second
346+
value specifies the starting column. Existing `packoffset` arguments written
347+
`c<row>.<column_letter>` map to the new attribute as `hlsl::packoffset(<row>,
348+
<column_index>)`, where `<column_index>` maps as in the table below.
349+
350+
| column_letter | column_index |
351+
| ------------- | ------------ |
352+
| x | 0 |
353+
| y | 1 |
354+
| z | 2 |
355+
| w | 3 |
356+
357+
Consider the following valid HLSL:
358+
359+
```hlsl
360+
cbuffer CB {
361+
float2 g1 : packoffset(c1);
362+
float2 g2 : packoffset(c1.z);
363+
}
364+
```
365+
366+
Under HLSL 202y this code will be rewritten as:
367+
368+
```hlsl
369+
cbuffer CB {
370+
float2 g1 [[hlsl::packoffset(1)]];
371+
float2 g2 [[hlsl::packoffset(1, 2)]];
372+
}
373+
```
374+
375+
#### hlsl::binding(int[, int=0])
376+
377+
The new `hlsl::binding` attribute replaces the `register` HLSL annotation. The
378+
attribute takes one required and one optional integer arguments. The first
379+
integer argument specifies the binding index. the second integer specifies
380+
the binding scope of the binding index. The interpretation of this attribute is
381+
defined by the target runtime's binding model.
382+
383+
In DirectX, the first value maps as the register value, and the second the
384+
register space. DirectX scopes bindings by resource class, allowing the same
385+
register and space assignments to be specified for resources of different types
386+
(e.g. a UAV and SRV may have the same register and space values without
387+
aliasing).
388+
389+
In Vulkan, the first value maps as the binding index, and the second maps as the
390+
descriptor set index.
391+
392+
Consider the following valid HLSL:
393+
394+
```hlsl
395+
SamplerState samp1 : register(s5);
396+
Texture2D tex1 : register(t0, space3);
397+
RWByteAddressBuffer buf1 : register(u4, space1);
398+
```
399+
400+
Under HLSL 202y this code will be rewritten as:
401+
402+
```hlsl
403+
SamplerState samp1 [[hlsl::binding(5)]];
404+
Texture2D tex1 [[hlsl::binding(0, 3)]];
405+
RWByteAddressBuffer buf1 [[hlsl::binding(4, 1)]];
406+
```
407+
408+
#### hlsl::payload_access(<enum>, ...)
409+
410+
The new `hlsl::payload_access` attribute replaces the `read` and `write` HLSL
411+
annotations for raytracing payload access qualifiers. The attribute takes an
412+
enum value specifying `read` or `write` to denote the type of access and a
413+
variable argument list of enumeration values specifying the stage that the
414+
access qualifier applies to. Consider the following currently valid HLSL:
415+
416+
```hlsl
417+
struct [raypayload] Payload {
418+
float f : read(caller, anyhit) : write(caller, anyhit);
419+
};
420+
```
421+
422+
Under HLSL 202y this code will be rewritten as:
423+
424+
```hlsl
425+
using namespace hlsl;
426+
struct [[raypayload]] Payload {
427+
float f [[payload_access(read, caller, anyhit), payload_access(write, caller, anyhit)]];
428+
};
429+
```

0 commit comments

Comments
 (0)