Skip to content

Atomic<T> vs Untyped Atomics #2377

@cwfitzgerald

Description

@cwfitzgerald

Context

This is a continuation of a discussion that was had on the WebGPU matrix. There has been some discussion of this problem in #2229 but was not the primary topic.

As of the writing of this issue, the WGSL spec defines all atomics as operating on dedicated Atomic types. This is consistent with how MSL does atomics, but differs from how GLSL/SPIRV/HLSL/DXIL do atomics. They do "untyped" atomics where you can do an atomic operation on any T.

The purpose of this issue is to evaluate the issues with the current way WGSL does atomics and determine if WGSL could have "untyped" atomics.

The Problem with Atomic<T>: Machine Translation from Other Languages

A very common path for the use of WebGPU and by extension WGSL, is through porting a project onto the web platform. These projects are written in some other source language and are being transpiled to WGSL. As it stands, such a machine translation might not be possible without conservatively promoting too much to atomics.

Take the following GLSL:

layout(set = 0, binding = 0) buffer PrimeIndices {
    uint[] indices;
};

How should that be translated to WGSL if a static index 15 is accessed?

It could promote the entire array to atomics array<atomic<u32>> which would pessimise other reads.

It could pull some heroics and split the array into 3 parts, a array<u32, 15> header, a atomic<u32> middle and a array<u32> footer. This would over-promote anything that accessed 15 non-atomically, but leave the rest of the array unscathed. This messes with the minimum binding size and is definitely something I consider "crazy" to expect implementations to do.

How should that be translated to WGSL if a dynamic index is accessed?

The translator would have no choice but to over-promote to array<atomic<u32>>.

Can We Do Untyped Atomics

On all backends with the exception of MSL, we can do untyped atomics just fine. On metal, in order to do an atomic operation you need to have that explicit type.

Casting

When presented with an atomic, spirv-cross translates this to an explicit cast from the non-atomic type to the atomic type.

See https://shader-playground.timjones.io/6ac47edae3a6940746a1b92e06dc7836 for the full source, but the important bit is that it translates:

atomicExchange(indices[0], 2)

to

atomic_exchange_explicit((device atomic_uint*)&_10.indices[0], 2u, memory_order_relaxed);

This kind of re-interpretation seems a bit sketchy at first but is not without president within Apple's own example code. In their example code Modern Rendering with Metal they don't cast, but they reinterpret that same threadgroup variable as both a atomic_uint* (Renderer/Shaders/AAPLLightCulling.metal:551) and a float* (Renderer/Shaders/AAPLLightCulling.metal:531).

Mixing Atomics and Non-Atomics

The question becomes, if we determine that untyped atomics are a thing we want, how should we describe the behavior if the user mixes and matches atomics and non-atomics?

I don't have a solid formal answer to this, but logically this feels no different from racing non-atomic reads and non-atomic writes across a RW buffer without barriers. In the case of racing non-atomics, you end up with some unspecified value, possibly an old value, possibly reading a partial write. We don't want to ban that for obvious reasons, so this would be no worse than the situation there.

Trying to get around this by statically defining what is an atomic (through Atomic or validation) is just as overly restrictive as trying to solve the problem of the racing non-atomics and has similarly unspecified results.

Conclusion

I have tried to express a route that we could make untyped atomics work in WGSL. I think this is particularly important as it falls into the category of "preserving developer trust". For years before they could run on metal and use untyped atomics through spirv-cross, but us coming in and deciding that you can't do that, is the kind of thing that would really put people off of WebGPU.

If there are any questions or if anything needs clarification, please ask. I can also edit the post to include other pointers pro/con.

Metadata

Metadata

Assignees

No one assigned

    Labels

    wgslWebGPU Shading Language Issues

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions