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.
CodePudding user response:
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>