ComputeShader.SetFloats()

Originally I have in

C#

_floatArray = new float[2];
_floatArray[0] = 1f;
_floatArray[1] = 0.5f;

Compute Shader

float FloatArray[2];

And use ComputeShader.SetFloats() to pass the values from C# to Compute Shader.
Reading the values in Compute Shader, I found that only FloatArray[0] has the value. So FloatArray[1] will equals to 0.

Unity dev (Marton E.) replied me that:

This is expected behavior and user code should be modified to follow packing rules.

HLSL specs says:
“Arrays are not packed in HLSL by default. To avoid forcing the shader to take on ALU overhead for offset computations, every element in an array is stored in a four-component vector. Note that you can achieve packing for arrays (and incur the addressing calculations) by using casting.”

Unity documentation says:
“This function can be used to set float vector, float array or float vector array values. For example, float4 myArray[4] in the compute shader can be filled by passing 16 floats. See Compute Shaders for information on data layout rules and cross-platform compatibility.”

Unity implementation doesn’t do casting suggested in HLSL documentation but just goes for unpacked storage (same as std140 GLSL directive) therefore calling SetFloats with a float[] argument should be aligned according to HLSL rules, i.e. float[] should be packed as every array item on 16 byte (float4) boundary.

So I should have in

C#

 _floatArray = new float[4 * 4];
 _floatArray[0] = 1f;
 _floatArray[4] = 0.5f;
 _floatArray[8] = 0.75f;
 _floatArray[12] = 1f;

Compute Shader

float FloatArray[4];

And read values in Compute Shader with
FloatArray[0]FloatArray[1]FloatArray[2], FloatArray[3] like usual.

——-

One more note for Mac Metal:

Metal does not enforce similar packing restriction but in order to maintain compatibility (along with GLCore) it was implemented the same way.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s