|  | # SPIR-V translation of WGSL pointers and references | 
|  |  | 
|  | WGSL was updated to have two kinds of memory views: pointers and references. | 
|  | See https://github.com/gpuweb/gpuweb/pull/1569 | 
|  |  | 
|  | In summary: | 
|  |  | 
|  | * Reference types are never explicitly mentioned in WGSL source. | 
|  | * A use of a variable is a value of reference type corresponding | 
|  | to the reference memory view of the storage allocated for the | 
|  | variable. | 
|  | * Let-declared constants can be of pointer type, but not reference | 
|  | type. | 
|  | * Function parameter can be of pointer type, but not reference type. | 
|  | * A variable's store type is never a pointer type, and never a | 
|  | reference type. | 
|  | * The "Load Rule" allows a reference to decay to the underlying | 
|  | store type, by issuing a load of the value in the underlying memory. | 
|  | * For an assignment: | 
|  | * The right-hand side evaluates to a non-reference type (atomic-free | 
|  | plain type). | 
|  | * The left-hand side evaluates to a reference type, whose store | 
|  | type is the same as the result of evaluating the right hand side. | 
|  | * The address-of (unary `&`) operator converts a reference to a | 
|  | pointer. | 
|  | * The dereference (unary `*`) operator converts a pointer to a | 
|  | reference. | 
|  |  | 
|  | TODO: Passing textures and samplers to helper functions might be | 
|  | done by "handler value", or by pointer-to-handle. | 
|  |  | 
|  | ## Writing SPIR-V from WGSL | 
|  |  | 
|  | The distinction in WGSL between reference and pointer disappears | 
|  | at the SPIR-V level.  Both types map into pointer types in SPIR-V. | 
|  |  | 
|  | To translate a valid WGSL program to SPIR-V: | 
|  |  | 
|  | * The dereference operator (unary `*`) is the identity operation. | 
|  | * The address-of operator (unary `&`) is the identity operation. | 
|  | * Assignment maps to OpStore. | 
|  | * The Load Rule translates to OpLoad. | 
|  |  | 
|  | ## Reading SPIR-V to create WGSL | 
|  |  | 
|  | The main changes to the SPIR-V reader are: | 
|  |  | 
|  | * When translating a SPIR-V pointer expression, track whether the | 
|  | corresponding WGSL expression is of corresponding WGSL pointer | 
|  | type or correspoinding WGSL type. | 
|  | * Insert dereference (unary-`*`) or address-of (unary-`&`) operators | 
|  | as needed to generate valid WGSL expressions. | 
|  |  | 
|  | The choices can be made deterministic, as described below. | 
|  |  | 
|  | The SPIR-V reader only supports baseline functionality in Vulkan. | 
|  | Therefore we assume no VariablePointers or VariablePointersStorageBuffer | 
|  | capabilities.  All pointers are | 
|  | [SPIR-V logical pointers](https://www.khronos.org/registry/spir-v/specs/unified1/SPIRV.html#LogicalPointerType). | 
|  | The [SPIR-V Universal Validation Rules](https://www.khronos.org/registry/spir-v/specs/unified1/SPIRV.html#_universal_validation_rules) | 
|  | specify where logical pointers can appear as results of instructions | 
|  | or operands of instructions. | 
|  |  | 
|  | Each SPIR-V pointer result expression is a logical pointer, and | 
|  | therefore is one of: | 
|  |  | 
|  | * OpVariable: map to the reference type. | 
|  | * OpFunctionParameter: map to the pointer type. | 
|  | * OpCopyObject: | 
|  | * When these only have one use, then these often fold away. | 
|  | Otherwise, they map to a a let-declared constant. | 
|  | * Map to the pointer type. | 
|  | * OpAccessChain, OpInBoundsAccessChain: | 
|  | * This could map to either pointer or reference, and adjustments | 
|  | in other areas could make it work.  However, we recommend mapping | 
|  | this to the reference type. | 
|  | * OpImageTexelPointer is not supported in WGSL. | 
|  | It is used to get a pointer into a storage texture, for use with | 
|  | atomic instructions.  But image atomics is not supported in | 
|  | WebGPU/WGSL. | 
|  |  | 
|  | Each SPIR-V pointer operand is also a logical pointer, and is an | 
|  | operand to one of: | 
|  | * OpLoad Pointer operand: | 
|  | * Map to reference, inserting a dereference operator if needed. | 
|  | * OpStore Pointer operand: | 
|  | * Map to reference, inserting a dereference operator if needed. | 
|  | * OpStore Pointer operand: | 
|  | * OpAccessChain, OpInBoundsAccessChain Base operand: | 
|  | * WGSL array-access and subfield access only works on references. | 
|  | * [Gpuweb issue 1530](https://github.com/gpuweb/gpuweb/issues/1530) | 
|  | is filed to allow those operations to work on pointers. | 
|  | * Map to reference, inserting a dereference operator if needed. | 
|  | * OpFunctionCall function argument pointer operands | 
|  | * Function operands can't be references. | 
|  | * Map to pointer, inserting an address-of operator if needed. | 
|  | * OpAtomic instruction Pointer operand | 
|  | * These map to WGSL atomic builtins. | 
|  | * Map to pointer, inserting an address-of operator if needed. | 
|  | * Note: As of this writing, the atomic instructions are not supported | 
|  | by the SPIR-V reader. | 
|  | * OpCopyObject source operand | 
|  | * This could have been mapped either way, but it's easiest to | 
|  | map to pointer, to match the choice for OpCopyObject result type. | 
|  | * Map to pointer, inserting an address-of operator if needed. | 
|  | * OpCopyMemory, source and destination operands | 
|  | * This acts as an assignment. | 
|  | * Map both source and destination to reference, inserting dereference | 
|  | operators if needed. | 
|  | * Note: As of this writing, OpCopyMemory is not supported by the | 
|  | SPIR-V reader. | 
|  | * Extended instruction set instructions Modf and Frexp | 
|  | * These map to builtins. | 
|  | * Map the pointer operand to pointer, inserting an address-of | 
|  | operator if needed. |