I am having a problem with compute shaders in Unity that I don't fully understand. I'm getting an error saying:
ArgumentException: Array passed to ComputeBuffer.SetData(array) must be blittable. Data.i is not blittable because it is not of value type (System.Double[]) Data.w is not blittable because it is not of value type (System.Double[])
UnityEngine.ComputeBuffer.SetData (System.Array data) (at <3be1a7ff939c43f181c0a10b5a0189ac>:0) Script1.Compute () (at Assets/Script1.cs:46) Script1.Start () (at Assets/Script1.cs:37)
As far as I know, the data I'm sending is of type double[]. Here is the C# code:
public class Script1 : MonoBehaviour
{
public double[] inputs;
public double[] weights = { 3.1, 2.1, 8.7 };
float bias = 3;
float output = 0;
public ComputeShader compute1;
ComputeBuffer buffer;
public struct Data
{
public double[] i;
public double[] w;
public float b;
public float o;
}
Data[] d;
// Start is called before the first frame update
void Start()
{
d = new Data[1];
d[0] = new Data
{
i = new double[] { 1.2, 5.1, 2.1 },
w = weights,
b = bias,
o = output
};
buffer = new ComputeBuffer(d.Length, 56);
Compute();
}
void Compute()
{
float[] result = new float[2];
int kernelHandle = compute1.FindKernel("CSMain");
compute1.SetBuffer(kernelHandle, "buffer", buffer);
buffer.SetData(d);
buffer.SetData(result);
compute1.Dispatch(kernelHandle, 24, 1, 1);
buffer.GetData(result);
}
private void OnDestroy()
{
buffer.Dispose();
}
}
And here is the code in the Compute Shader.
// Each #kernel tells which function to compile; you can have many kernels
#pragma kernel CSMain
// Create a RenderTexture with enableRandomWrite flag and set it
// with cs.SetTexture
RWTexture2D<float4> Result;
struct d
{
double i[3], w[3];
float b, o;
};
RWStructuredBuffer<d> buffer;
[numthreads(24,1,1)]
void CSMain (uint3 id : SV_DispatchThreadID)
{
// TODO: insert actual code here!
float result[] = { buffer[0].i[0] * buffer[0].w[0] + buffer[0].i[1] * buffer[0].w[1] + buffer[0].i[2] * buffer[0].w[2] + buffer[0].b, 0 };
}
Is there a different way to send a double array to and from Compute Shaders? I've tried casting as (System.Double) and it just says that it's not necessary and gives the same error.
You can not pass types to compute shaders that are non-blittable.
While your double[]
itself actually would be blittable as it only contains values of a blittable type (double
) it becomes non-blittable since you nest it within another struct
.
One-dimensional arrays of blittable primitive types, such as an array of integers. However, a type that contains a variable array of blittable types is not itself blittable.
You could try to rather use e.g. a NativeArray<double>