Compute Shader: Best way to make a 3d array?

I’m looking for a 3d array in a compute shader (HLSL) that I can both read and write to from the compute shader.

It’s possible to make a 3d array like this:

int grid[10][40][4];

But it’s not possible to write to it from the compute shader, only read. From scripts you can write to it. I think it’s possible to make it “groupshared”, so a group of threads could share it, but this is not feasible for me (all threads need to at least be able to read from the same array).

I think I have two solutions though.

1. This solution is fine, but the 3rd dimension has a max of 4 depth (and I can only put int, float, half etc. in the array).

Texture2D<int4> grid;

Example use (hard to iterate through 3rd dimension: xyzw):
grid[uint(1,2)].z

2. This solution seems like a terrible way to make an array, and I haven’t tested if it works (it compiles though!)

{
int z[4];
};

struct Grid1
{
Grid2 y[40];
};

StructuredBuffer<Grid1> grid;```

**Example use:**
```grid[1].y[2].z[3];```

**Am I missing something? Thanks!**

Maybe use 3D render texture or map and remap 3d data into single dimensional rwstructuredbuffer.

I couldn’t quite find a 3d render texture or map anywhere, but I came up with this:

I fill out this (in CPU)

int grid1[10][40][4];

with indices to the int I need to get in

StructuredBuffer<int> grid2;

Seems simple. Thanks!

grid2[grid1[×][y][z]];

The above solution doesn’t quite work as there doesn’t seem to be any way to write to a “primitive” array in the compute shader from the CPU. And there’s no way to write to it from the computer shader unless it is set as groupshared.

So now I’m looking at writing to a RWTexture3D from the CPU. It seems like others are having trouble with that.

Just use a linear buffer with dimX * dimY * dimZ number of elements. Then index into it using:

x + dimX * y + dimX * dimY * z

1 Like

Thanks, @bgolus , that’s what I ended up doing.

I figured having a table could save those few computations every time I have to look up anything. But it’s probably not worth the effort. And it takes up memory. And it’s less flexible to a change of size in the array.

In general I’m finding it hard to see what puzzle pieces I have to work with in compute shaders. Why can I make an array in the compute shader that can’t be accessed from CPU and the compute shader can only read from it? Then it’s useless. Unless you groupshare it.

Compute shaders are pretty rad though

Where do the parenthesis go?

No where? It works out correctly just using PEDMAS without them.

But otherwise if you really must have them:
x + (dimX * y) + (dimX * dimY * z)