Created
December 7, 2023 08:20
-
-
Save slipster216/06c4ea4cf6003958f9e602473a8a25b7 to your computer and use it in GitHub Desktop.
Append Buffer Async Readback broken
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
AppendStructuredBuffer<float> Result; | |
[numthreads(256,1,1)] | |
void CSMain (uint3 id : SV_DispatchThreadID) | |
{ | |
if (id.x < 3000) | |
{ | |
Result.Append(1); | |
} | |
} | |
Script: | |
using System; | |
using System.Collections; | |
using System.Collections.Generic; | |
using Unity.Collections; | |
using UnityEngine; | |
using UnityEngine.Rendering; | |
[ExecuteAlways] | |
public class TestAppendBuffer : MonoBehaviour | |
{ | |
public enum Mode | |
{ | |
MonoAllocating, | |
AsyncReadback, | |
AsyncReadbackBlocking | |
} | |
public Mode mode = Mode.MonoAllocating; | |
NativeArray<float> asArray; | |
GraphicsBuffer outputBuf; | |
private void OnEnable() | |
{ | |
int numToDo = 3000; | |
outputBuf = new GraphicsBuffer(GraphicsBuffer.Target.Append, numToDo, 4); | |
outputBuf.SetCounterValue(0); | |
ComputeShader cs = Resources.Load<ComputeShader>("TestAppendBuffer"); | |
int kernel = cs.FindKernel("CSMain"); | |
cs.SetBuffer(kernel, "Result", outputBuf); | |
cs.Dispatch(kernel, Mathf.CeilToInt(numToDo / 256.0f), 1, 1); | |
if (mode == Mode.MonoAllocating) | |
{ | |
var data = new float[3000]; | |
outputBuf.GetData(data, 0, 0, 3000); | |
int valid = 0; | |
int invalid = 0; | |
foreach (var m in data) | |
{ | |
if (m == 0) | |
{ | |
invalid++; | |
} | |
else | |
valid++; | |
} | |
if (valid == 3000) | |
{ | |
Debug.Log("Working Correctly, all 3000 entries processed"); | |
} | |
else | |
{ | |
Debug.Log("Failed, " + valid + " entries processed, " + invalid + " not processed"); | |
} | |
outputBuf.Dispose(); | |
return; | |
} | |
else if (mode == Mode.AsyncReadback) | |
{ | |
asArray = new NativeArray<float>(numToDo, Allocator.Persistent); | |
var req = AsyncGPUReadback.RequestIntoNativeArray(ref asArray, outputBuf, numToDo, 0); | |
req.WaitForCompletion(); | |
int valid = 0; | |
int invalid = 0; | |
foreach (var m in asArray) | |
{ | |
if (m == 0) | |
{ | |
invalid++; | |
} | |
else | |
valid++; | |
} | |
if (valid == 3000) | |
{ | |
Debug.Log("Working Correctly, all 3000 entries processed"); | |
} | |
else | |
{ | |
Debug.Log("Failed, " + valid + " entries processed, " + invalid + " not processed"); | |
} | |
outputBuf.Dispose(); | |
asArray.Dispose(); | |
} | |
else | |
{ | |
asArray = new NativeArray<float>(numToDo, Allocator.Persistent); | |
var req = AsyncGPUReadback.RequestIntoNativeArray(ref asArray, outputBuf, numToDo, 0, callback); | |
} | |
} | |
private void callback(AsyncGPUReadbackRequest request) | |
{ | |
var data = request.GetData<float>(); | |
int valid = 0; | |
int invalid = 0; | |
foreach (var m in data) | |
{ | |
if (m == 0) | |
{ | |
invalid++; | |
} | |
else | |
valid++; | |
} | |
if (valid == 3000) | |
{ | |
Debug.Log("Working Correctly, all 3000 entries processed"); | |
} | |
else | |
{ | |
Debug.Log("Failed, " + valid + " entries processed, " + invalid + " not processed"); | |
} | |
outputBuf.Dispose(); | |
asArray.Dispose(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
To repro: Add the component and put the compute shader in a Resource folder. Toggle enable on/off to test. Change modes to try different modes, all the aync/non-allocating versions are broken.