Writing to render texture in for loop not working (metal)

I have written a compute shader that fills a 3D render texture with simplex noise. It works perfectly with on my Windows machine with DirectX, but when compiling on Mac with Metal it produces very strange results. I have narrowed the issue down to the for loop. It seems that writing to a render texture in a for loop doesn’t work properly on Metal. Is this simply a limitation of Metal, or am I missing something?

octaves is set by a C# script and id is the dispatch thread id

RWTexture3D<float> noiseValues;
int octaves;

for (int i = 0; i < octaves; i++)
        {
            noiseValues[id] += SimplexNoise(float3(id + chunkPos) / scale * frequency + offset) * amplitude;
            amplitude *= persistence;
            frequency *= lacunarity;
        }

I also tried replacing octaves with a literal, which still does not work:

// Still broken
for (int i = 0; i < 9; i++)
            {
                noiseValues[id] += SimplexNoise(float3(id + chunkPos) / scale * frequency + offset) * amplitude;
                amplitude *= persistence;
                frequency *= lacunarity;
            }

However, adding [unroll] above the second loop does work, which makes sense as it is essentially the same as copy and pasting the code 9 times. The thing is, for my uses I need it to loop based on a number set from a C# script, so I can’t unroll it.

Some other things I have tried include using a ByteAdressBuffer for the octaves variable and adding [loop] and [allow_uav_condition].

Below are screenshots of the 3D render texture in the inspector:

On windows, working

On Mac using Metal

(image upload gives error for some reason so had to upload elsewhere)

I managed to fix this a while back but forgot to update this post, so I’ll do it now in case anyone has the same problem. The issue was that you can’t read from the texture from within the loop (at least on Metal), and the += operator requires a read.

The solution is simply to create a sum variable, add to that from within the loop, and then write this sum to the texture after the loop. This is actually way more efficient than the original way I was doing it, as it doesn’t require any reads of the texture and only a single write, so I would recommend doing it like this on DirectX as well.

I was also able to get rid of the [unroll] and change it back to the octaves variable after doing this.