Hi guys,
I can’t help but feel like i missed something extremely fundamental about how compute is supposed to work or something.
I’ve been asking all sorts of questions on stack exchange in the chat rooms, on the game dev site and on unity answers and don’t appear to be getting anything finite so I figured i might try here with a very specific example of my problem so here goes …
Lets assume we havea brand new project in unity with literally no changes and im setup for windows builds and unity is using DX11 mode …
As per the question heading im trying to use compute to do various large scale parallel computing tasks, as a basic test I thought I would try some simple code to get started so I wrote the following compute shader …
#pragma kernel CSMain1D
#pragma kernel CSMain2D
#pragma kernel CSMain3D
RWStructuredBuffer result1d;
RWTexture2D result2d;
RWTexture3D result3d;
[numthreads(2,1,1)]
void CSMain1D (int3 id : SV_DispatchThreadID)
{
result1d[id.x] = 1;
}
[numthreads(2,2,1)]
void CSMain2D (int3 id : SV_DispatchThreadID)
{
result2d[id.xy] = 1;
}
[numthreads(2,2,2)]
void CSMain3D (int3 id : SV_DispatchThreadID)
{
result3d[id.xyz] = 1;
}
I then add the follow CPU code to call my compute shader …
using System.Collections;
using System.IO;
using UnityEngine;
public class Test : MonoBehaviour {
public ComputeShader compute;
// Use this for initialization
void Start () {
Dispatch1d();
Dispatch2d();
Dispatch3d();
}
void Dispatch1d()
{
using (var testBuffer = new ComputeBuffer(2, sizeof(int)))
{
var kernel = compute.FindKernel(“CSMain1D”);
compute.SetBuffer(kernel, “result1d”, testBuffer);
compute.Dispatch(kernel, 1, 1, 1);
var result = new int[2];
testBuffer.GetData(result);
DumpToFile(“1D Results”, result);
testBuffer.Release();
}
}
void Dispatch2d()
{
using (var testBuffer = new ComputeBuffer(4, sizeof(int)))
{
var kernel = compute.FindKernel(“CSMain2D”);
compute.SetBuffer(kernel, “result2d”, testBuffer);
compute.Dispatch(kernel, 1, 1, 1);
var result = new int[2,2];
testBuffer.GetData(result);
DumpToFile(“2D Results”, result);
testBuffer.Release();
}
}
void Dispatch3d()
{
using (var testBuffer = new ComputeBuffer(8, sizeof(int)))
{
var kernel = compute.FindKernel(“CSMain3D”);
compute.SetBuffer(kernel, “result3d”, testBuffer);
compute.Dispatch(kernel, 1, 1, 1);
var result = new int[2,2,2];
testBuffer.GetData(result);
DumpToFile(“3D Results”, result);
testBuffer.Release();
}
}
void DumpToFile(string heading, IEnumerable data)
{
using (var writer = new StreamWriter(File.OpenWrite(@“D:\Logs\Debug.log”)))
{
writer.BaseStream.Position = writer.BaseStream.Length;
writer.WriteLine(heading);
foreach (var i in data)
writer.WriteLine(i.ToString());
writer.WriteLine(string.Empty);
}
}
}
…
Ok thats the code sorted, so i then add a new game object to the default scene unity has been kind enough to create for us and to that game object i add the behavior defined above and set the compute property by dropping the compute file on it.
When I run this I don’t expect it to render anything but instead simply spit out a file with the results of each of the compute calls made and this is the content of the file i get …
1D Results
1
1
2D Results
1
0
0
0
3D Results
1
0
0
0
0
0
0
0
…
The plot thickens …
Before doing this I set out to generate voxels on the gpu using compute, having already built a CPU based implementation i figured “how hard could it be” so as a first phase I wrote a simple test voxel chunk generator and took the results and passed them to my cpu based mesh generator.
It worked perfectly, but the odd thing is … if i log out the results in my voxel buffer to a file in the same way I am doing above it tells me the buffer is full of all 0’s like I haven’t put anything in it at all.
This can’t be true else how would I get mesh generated from it?
So I have several questions really …
- Does the above example make sense / work as people here would expect?
- Why does VS + the file + Debug.Log() in unity all report that all those arrays are empty?
General debugging of compute shaders:
I noticed that microsoft suggests hooking up the graphics debugger which doesn’t seem to be possible with unity projects for some reason.
If I do “DEbug > Graphics > Start Diagnostics” i get a popup that reads “The graphics Diagnostics feature is not available for this target” … have I missed something / not set something up or are unity projects not possible to debug with Microsofts tooling?
-
How do I correctly see either the content of the buffer on the gpu or the downloaded result of populating an array on the cpu side from visual studio?
-
Is this something I did wrong or a bug in the tool chain somewhere?
I’m inclined to say its my code at fault but don’t know where to start getting to the bottom of all this so any advice would be really appreciated.
EDIT: I have uploaded a zip with the scene, compute, and MonoBehavior files in it for others to try out in case it helps
2505007–173186–Test.zip (5.07 KB)