I want to implement an A-Buffer algorithm for order-independent-transparency in my Metal application. The description of the technique mentions using an atomic counter. I've never used one of these or even heard of them. I just read about atomic variables in the Metal Shading Language Specification, but I can't figure out how to actually implement or use one.
Does anyone have experience with these in Metal? Can you point me to an example of how to set up and use a simple integer counter? Basically each render pass I need to be able to increment an integer from within the fragment shader, starting from zero. This is used to index into the A-Buffer.
Thanks!
Well, your question is lacking sufficient detail to provide much more than a general overview. You might consider adding an incomplete shader function, with pseudo-code where you're not sure how to implement something.
Anyway, an atomic counter is a variable of type atomic_uint
(or atomic_int
if you need sign). To be useful, the variable needs to be shared across a particular address space. Your example sounds like it needs device
address space. So, you would want a device
variable backed by a buffer. You would declare it as:
fragment FragmentOut my_fragment_func(device atomic_uint &counter [[buffer(0)]], ...)
{
...
}
You could also use a struct type for the parameter and have a field of the struct be your atomic_uint
variable.
To atomically increment the atomic variable by 1 and obtain the prior value, you could do this:
uint value = atomic_fetch_add_explicit(&counter, 1, memory_order_relaxed);
The initial value of the atomic variable is taken from the contents of the buffer at a point before the draw or dispatch command is executed. It's not documented as such in the spec, but the size and bit-interpretation of an atomic type seems to match the corresponding non-atomic type. That is, you would write a uint
(a.k.a. unsigned int
or uint32_t
) to the buffer to initialize an atomic_uint
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With