Hi, we are trying to make a tool which relies on compute shaders and works under Windows to run on Metal as well. The tool is a GPU lightmapper and uses Render Textures, Texture Arrays and Compute Buffers. We tried to test RenderTextures and they seem to work, however we can not get to properly use ComputeBuffers.
What is the current support for Compute Shaders in Metal !? Where can we read about limitations, max threads count etc… ?
Any example on Compute Shaders and Metal !?
Here is a simple example which uses suppose to initialize Compute Buffer with red color and later in C# script the data from the buffer is used to apply colors to a texture. The example is working on Windows but on Metal !?
Tried with 5.6 and 2017 as well !
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TextComputeScript : MonoBehaviour
{
public ComputeShader shader;
public Texture2D tempTexture;
ComputeBuffer colorBuffer;
Vector4[] outColorBuffer;
Color[] colors;
/// <summary>
///
/// </summary>
void Start()
{
// SIMPLE EXAMPLE ON USING Compute Buffer
tempTexture = new Texture2D(512, 512);
// Buffer is with length of 512 x 512
int kernel = 0;
int totalElements = 512 * 512;
colors = new Color[totalElements];
outColorBuffer = new Vector4[totalElements];
// Init elements - As i have read somewhere, initializing elements before set data to buffer
// is important for Metal ( not sure about that ) !?
for (int i = 0; i < totalElements; i++)
{
outColorBuffer[i] = new Vector4();
colors[i] = new Color();
}
// Create the compute buffer
colorBuffer = new ComputeBuffer(totalElements, 16);
colorBuffer.SetData(outColorBuffer);
shader.SetBuffer(kernel, "colorBuffer", colorBuffer);
// Dispatching kernel
shader.Dispatch(kernel, totalElements / 32, 1, 1);
// Read the data from the buffer back to array
colorBuffer.GetData(outColorBuffer);
for (int i = 0; i < totalElements; i++)
{
Vector4 c = outColorBuffer[i];
colors[i] = new Color(c.x, c.y, c.z, c.w);
}
// The texture is not red on MAC but it is red on Windwos !
tempTexture.SetPixels(colors);
tempTexture.Apply();
}
private void OnDisable()
{
if (colorBuffer != null)
colorBuffer.Release();
}
}
And the simple shader
#pragma kernel FillBuffer
RWStructuredBuffer<float4> colorBuffer : register(u0);
[numthreads(32,1,1)]
void FillBuffer (uint3 DTid : SV_DispatchThreadID)
{
uint elementID = DTid.x;
colorBuffer[elementID] = float4(1.0, 0.0, 0.0, 1.0);
}