@@ -467,38 +467,75 @@ enum CachedConstant {
467
467
ZeroValue ( Word ) ,
468
468
}
469
469
470
+ /// The SPIR-V representation of a [`crate::GlobalVariable`].
471
+ ///
472
+ /// In the Vulkan spec 1.3.296, the section [Descriptor Set Interface][dsi] says:
473
+ ///
474
+ /// > Variables identified with the `Uniform` storage class are used to access
475
+ /// > transparent buffer backed resources. Such variables *must* be:
476
+ /// >
477
+ /// > - typed as `OpTypeStruct`, or an array of this type,
478
+ /// >
479
+ /// > - identified with a `Block` or `BufferBlock` decoration, and
480
+ /// >
481
+ /// > - laid out explicitly using the `Offset`, `ArrayStride`, and `MatrixStride`
482
+ /// > decorations as specified in "Offset and Stride Assignment".
483
+ ///
484
+ /// This is followed by identical language for the `StorageBuffer`,
485
+ /// except that a `BufferBlock` decoration is not allowed.
486
+ ///
487
+ /// When we encounter a global variable in the [`Storage`] or [`Uniform`]
488
+ /// address spaces whose type is not already [`Struct`], this backend implicitly
489
+ /// wraps the global variable in a struct: we generate a SPIR-V global variable
490
+ /// holding an `OpTypeStruct` with a single member, whose type is what the Naga
491
+ /// global's type would suggest, decorated as required above.
492
+ ///
493
+ /// The [`helpers::global_needs_wrapper`] function determines whether a given
494
+ /// [`crate::GlobalVariable`] needs to be wrapped.
495
+ ///
496
+ /// [dsi]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#interfaces-resources-descset
497
+ /// [`Storage`]: crate::AddressSpace::Storage
498
+ /// [`Uniform`]: crate::AddressSpace::Uniform
499
+ /// [`Struct`]: crate::TypeInner::Struct
470
500
#[ derive( Clone ) ]
471
501
struct GlobalVariable {
472
- /// ID of the OpVariable that declares the global.
502
+ /// The SPIR-V id of the `OpVariable` that declares the global.
503
+ ///
504
+ /// If this global has been implicitly wrapped in an `OpTypeStruct`, this id
505
+ /// refers to the wrapper, not the original Naga value it contains. If you
506
+ /// need the Naga value, use [`access_id`] instead of this field.
473
507
///
474
- /// If you need the variable's value, use [`access_id`] instead of this
475
- /// field. If we wrapped the Naga IR `GlobalVariable`'s type in a struct to
476
- /// comply with Vulkan's requirements, then this points to the `OpVariable`
477
- /// with the synthesized struct type, whereas `access_id` points to the
478
- /// field of said struct that holds the variable's actual value.
508
+ /// If this global is not implicitly wrapped, this is the same as
509
+ /// [`access_id`].
479
510
///
480
511
/// This is used to compute the `access_id` pointer in function prologues,
481
- /// and used for `ArrayLength` expressions, which do need the struct.
512
+ /// and used for `ArrayLength` expressions, which need to pass the wrapper
513
+ /// struct.
482
514
///
483
515
/// [`access_id`]: GlobalVariable::access_id
484
516
var_id : Word ,
485
517
486
- /// For `AddressSpace::Handle` variables, this ID is recorded in the function
487
- /// prelude block (and reset before every function) as `OpLoad` of the variable.
488
- /// It is then used for all the global ops, such as `OpImageSample`.
518
+ /// The loaded value of a `AddressSpace::Handle` global variable.
519
+ ///
520
+ /// If the current function uses this global variable, this is the id of an
521
+ /// `OpLoad` instruction in the function's prologue that loads its value.
522
+ /// (This value is assigned as we write the prologue code of each function.)
523
+ /// It is then used for all operations on the global, such as `OpImageSample`.
489
524
handle_id : Word ,
490
525
491
- /// Actual ID used to access this variable.
492
- /// For wrapped buffer variables, this ID is `OpAccessChain` into the
493
- /// wrapper. Otherwise, the same as `var_id`.
526
+ /// The SPIR-V id of a pointer to this variable's Naga IR value.
527
+ ///
528
+ /// If the current function uses this global variable, and it has been
529
+ /// implicitly wrapped in an `OpTypeStruct`, this is the id of an
530
+ /// `OpAccessChain` instruction in the function's prologue that refers to
531
+ /// the wrapped value inside the struct. (This value is assigned as we write
532
+ /// the prologue code of each function.) If you need the wrapper struct
533
+ /// itself, use [`var_id`] instead of this field.
534
+ ///
535
+ /// If this global is not implicitly wrapped, this is the same as
536
+ /// [`var_id`].
494
537
///
495
- /// Vulkan requires that globals in the `StorageBuffer` and `Uniform` storage
496
- /// classes must be structs with the `Block` decoration, but WGSL and Naga IR
497
- /// make no such requirement. So for such variables, we generate a wrapper struct
498
- /// type with a single element of the type given by Naga, generate an
499
- /// `OpAccessChain` for that member in the function prelude, and use that pointer
500
- /// to refer to the global in the function body. This is the id of that access,
501
- /// updated for each function in `write_function`.
538
+ /// [`var_id`]: GlobalVariable::var_id
502
539
access_id : Word ,
503
540
}
504
541
0 commit comments