This is directly related to #2055 and is somewhat related to #1621. We already discussed it by email with @dneto0 more than 2 years ago but without reaching a conclusion (that I can find/remember), so I'm opening this issue to restart the discussion in a more public and archivable way.
In the Vulkan memory model (formal model: https://github.com/KhronosGroup/Vulkan-MemoryModel/blob/master/alloy/spirv.als, spec text: https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/vkspec.html#memory-model), for a write to be propagated to a read in a different invocation, they have to be non-private (exactly which operations this should correspond to in WGSL is the exact topic of #1621), there has to be an "availability" operation that affects the write, and there has to be a "visibility" operation that affects the read.
The Vulkan memory model offers an extremely fine-grained control over these availability and visibility operations. In particular, they can either be attached to a specific write and read (only affecting those), or can be attached to a release/acquire operation (i.e. barriers in WGSL), implicitly affecting every non-private write/read that is before/after that barrier.
Since no other shading language offers such control, I am strongly against offering it at the WGSL level.
If we assume that we want every non-private/coherent write to be automatically propagated/visible to every read that happens-after it, then we need to pick a strategy to insert such availability/visibility annotations when converting WGSL to Vulkan. To the best of my knowledge, there are two approaches to do so:
- Approach 1: annotate every relevant write and read with MakePointerAvailable/MakePointerVisible. Do not annotate any other operation.
- Approach 2: annotate every barrier with MakeAvailable/MakeVisible. Do not annotate any other operation.
Approach 1 is the one currently used by #2055. It is also the one used by SPIRV-Tools when converting from old-style SPIRV that uses "coherent" annotations.
Approach 2 allows some significant simplifications of the formal memory model (I intend to finish a version of it with just the parts that are used by WGSL, which I started in early 2019 and forgot about since then).
@dneto0 said:
Stepping back, the reason the Vulkan memory model has both per-op AV/VIS ops and also the bulk ones at synchronziation points is that different workloads can perform better with one pattern vs. the other. But our transform just blindly picks the one strategy.
So I intend to track two open questions in this issue:
- Are the two approaches perfectly equivalent in results, or do they have any difference in corner cases?
- Can we get some actual performance data with both approaches and see whether one turns out faster in most/all workloads?
This is directly related to #2055 and is somewhat related to #1621. We already discussed it by email with @dneto0 more than 2 years ago but without reaching a conclusion (that I can find/remember), so I'm opening this issue to restart the discussion in a more public and archivable way.
In the Vulkan memory model (formal model: https://github.com/KhronosGroup/Vulkan-MemoryModel/blob/master/alloy/spirv.als, spec text: https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/vkspec.html#memory-model), for a write to be propagated to a read in a different invocation, they have to be non-private (exactly which operations this should correspond to in WGSL is the exact topic of #1621), there has to be an "availability" operation that affects the write, and there has to be a "visibility" operation that affects the read.
The Vulkan memory model offers an extremely fine-grained control over these availability and visibility operations. In particular, they can either be attached to a specific write and read (only affecting those), or can be attached to a release/acquire operation (i.e. barriers in WGSL), implicitly affecting every non-private write/read that is before/after that barrier.
Since no other shading language offers such control, I am strongly against offering it at the WGSL level.
If we assume that we want every non-private/coherent write to be automatically propagated/visible to every read that happens-after it, then we need to pick a strategy to insert such availability/visibility annotations when converting WGSL to Vulkan. To the best of my knowledge, there are two approaches to do so:
Approach 1 is the one currently used by #2055. It is also the one used by SPIRV-Tools when converting from old-style SPIRV that uses "coherent" annotations.
Approach 2 allows some significant simplifications of the formal memory model (I intend to finish a version of it with just the parts that are used by WGSL, which I started in early 2019 and forgot about since then).
@dneto0 said:
So I intend to track two open questions in this issue: