@@ -312,21 +312,24 @@ https://godbolt.org/z/3TW565acT
312312#### Example 8
313313
314314For resources declared at global scope, DXC validates that they fit within the
315- specified register slots. If they do not fit, an error is reported during
316- validation, though the error message is cryptic and the source location points
315+ specified register slots. If they do not fit, errors are reported, though the
316+ error messages are not clear and the source location points
317317to where the resource is first used rather than where it is declared.
318318
319319```
320320RWBuffer<float> Buf[10] : register(u4294967293);
321321
322322[numthreads(4,1,1)]
323323void main() {
324- Buf[0][0] = 0;
324+ Buf[0][0] = 0; // line 5
325325}
326326```
327327https://godbolt.org/z/93d317Ej4
328328```
329- <source>:12:3: error: Constant values must be in-range for operation.
329+ <source>:5:3: error: Constant values must be in-range for operation.
330+ <source>:5:3: error: Resource handle should returned by createHandle.
331+ <source>:5:13: error: store should be on uav resource.
332+ <source>:5:13: error: buffer load/store only works on Raw/Typed/StructuredBuffer.
330333```
331334
332335#### Example 9
@@ -386,6 +389,113 @@ https://godbolt.org/z/Mo8Paoq7G
386389<source>:5:7: error: register space cannot be specified on global constants.
387390```
388391
392+ ### Static Structs with Resources
393+
394+ Structs with resources can be declared as static. Same as other statically
395+ declared resources, these struct resource members are not automatically bound.
396+ Instead, the user must explicitly initialize them by assigning an existing
397+ resource to the struct member.
398+
399+ #### Example 11
400+
401+ ```
402+ struct M {
403+ RWBuffer<float> Bufs[10];
404+ };
405+
406+ RWBuffer<float> GlobalBufs[10];
407+
408+ static M m = { GlobalBufs };
409+
410+ [numthreads(4,4,4)]
411+ void main(uint3 ID : SV_GroupID) {
412+ m.Bufs[ID.y][1] = m.Bufs[ID.x][0];
413+ }
414+ ```
415+ https://godbolt.org/z/8fcTfz6d8
416+
417+ Unlike resource arrays in non-static global struct instances, resource arrays
418+ inside static or local struct variables may be dynamically indexable. This is
419+ possible when all resource elements are initialized from a range of the same
420+ dynamically indexable global resource array, as shown in the example above where
421+ ` m.Bufs ` is initialized from ` GlobalBufs ` .
422+
423+ ### Local variables and Function Parameters
424+
425+ Structs with resources can also be declared as local variables or used as function parameters.
426+
427+ #### Example 12
428+
429+ ```
430+ struct N {
431+ RWBuffer<float> Buf;
432+ };
433+
434+ N n : register(u2);
435+
436+ void foo(N paramN, uint i) {
437+ paramN.Buf[i] = 10;
438+ }
439+
440+ [numthreads(4,4,4)]
441+ void main(uint3 ID : SV_GroupID) {
442+ N localN = n;
443+ localN.Buf[10] = 0.13;
444+ foo(localN, ID.x);
445+ }
446+ ```
447+ https://godbolt.org/z/eKq3jzM5r
448+
449+ ### Initialization list
450+
451+ Local or static declarations of structs with resources can be initialized using
452+ initialized lists.
453+
454+ #### Example 13
455+
456+ ```
457+ struct P {
458+ RWBuffer<float> Bufs[4];
459+ };
460+
461+ RWBuffer<float> GlobalBufs[4];
462+
463+ static P p1 = { GlobalBufs };
464+
465+ [numthreads(4,4,4)]
466+ void main(uint3 ID : SV_GroupID) {
467+ P p2 = { GlobalBufs[3], GlobalBufs[2],
468+ GlobalBufs[1], GlobalBufs[0]};
469+
470+ p1.Bufs[ID.y][0] = p2.Bufs[ID.x][0];
471+ }
472+ ```
473+ https://godbolt.org/z/zzKe8bjff
474+
475+ ### Assignments
476+
477+ Assignment to resource or resource array members of a global non-static structs
478+ is not allowed.
479+
480+ ``` c++
481+ struct P {
482+ RWBuffer<float > Buf;
483+ };
484+
485+ P p : register(u2);
486+
487+ RWBuffer<float > GlobalBuf;
488+
489+ [numthreads(4 ,4 ,4 )]
490+ void main (uint3 ID : SV_GroupID) {
491+ p.Buf = GlobalBuf; // error
492+ p.Buf[ 0] = 10;
493+ }
494+ ```
495+ https://godbolt.org/z/f9dd4GYWq
496+
497+ DXC reports an error `cast<X>() argument of incompatible type!`.
498+
389499### Summary
390500
391501- DXC supports resources as members of structs, generating global resources
@@ -409,9 +519,15 @@ https://godbolt.org/z/Mo8Paoq7G
409519- DXC validates register ranges for global resources but does not check for
410520 overflow in struct members, which may result in silently overflow.
411521
522+ - Structs with resources can be declared as static or local variables, used as
523+ function parameters, and initialized with initializer lists.
524+
412525## Motivation
413526
414- We need to support resources in structs in Clang.
527+ While resources in structs may not be a widely used HLSL feature, DXC does
528+ support them, and so should the Clang implementation. This also presents an
529+ opportunity to address usability issues, such as the unpredictable implicit
530+ binding order, to make the feature more robust and user-friendly.
415531
416532## Proposed solution
417533
0 commit comments