Followers 0

# Understanding the “sampler array index must be a literal expression” error in ComputeShaders

## 6 posts in this topic

Let's say I have a compute shader that retrieves data from a Texture2DArray using the Id of the group like this:

Texture2DArray<float4> gTextureArray[2];
{

....
}



And let's say I launch it like this

deviceContext->Dispatch(2, 0, 0);

So, 2 groups, 32 threads each that read pixel values from a Texture2DArray. All the threads in GroupID.x = 0 will read values from gTextureArray[0] and all the threads in GroupID.y = 0 will read values from gTextureArray[1]. It turns out I can't compile that simple code, instead I get this compile error (cs_5_0)

error X3512: sampler array index must be a literal expression

Now, I know I can do this instead:

Texture2DArray<float4> gTextureArray[2];
{
float3 tmp = float3(0,0,0);
if(GroupID.x == 0)
else if(GroupID.x == 1)

....
}



Or use a switch in case I have lots of groups so it doesn't look that much awful (it still does)

Notice how there is no warp divergence since all threads in each group will go one branch or the other. My question is, am I missing something here? Why does HLSL not support that kind of indexing since I can not see any divergence or other problems, at least in this case?

Edited by joystick-hero
0

##### Share on other sites

First of all thanks for your answer and help. I didn't think about the syntactic sugar possibility.

However, this is why Texture2DArray was invented, instead of just Texture2D. At the moment you've got an array of two Texture2DArray's.

Did you actually want just one Texture2DArray with two Texture2D's inside it?

If so, the syntax is: tmp = gTextureArray.Load(int4(x,y, mip, arrayIndex)).rgb;

The problem is I kinda needed an array of Texture2DArrays because I need to bind 10240  Texture2D's (64x64 dimension) to this ComputeShader and it greatly exceeds the 2048 length limit for Texture2DArray's. The shader runs faster the more data you give it to process, unless you run out of memory but that's not the case so far xD.  And this was the only idea I had to sort out this problem, well this and TextureCubeArray's maybe? I don't know how those work tho and I had all my Texture2dArray C++ code in place.

I think the right syntax is tmp = gTextureArray.Load(int4(x,y, arrayIndex, mip)).rgb; ?

Unless the documentation is really confusing :c

Waterfalled code is really ugly stuff, so it looks like the compiler authors have decided that instead of doing it automatically behind the scenes (which might make you think that indexing arrays of textures is supported in hardware), they'd instead force you to write it yourself so you're aware of what's going on.

Aside from the fact that it doesn't look much pretty, are there any performance reasons to not use some waterfalled code? Because if the threads in the warps don't diverge I didn't think about another bad consequences.

Edited by joystick-hero
0

##### Share on other sites

The textures's contents are the result of previous scene renders from several viewpoints. I don't know if there's an easy way to instruct DirectX to render to some Texture2D area as opposed to an entire one :c

0

##### Share on other sites

Thanks MJP. I guess that simple-why-I-didn't-think-about-that solution solves all my problems. Gonna try that. Now I'm glad I don't have a picture of me in my profile pic. So there are no performance problems with my original code I suppose? Only it's painfully ugly and not scalable at all xD

0

## Create an account

Register a new account