Hello!
I’m trying to render vertex data that exists in a StructuredBuffer, generated from a compute shader using Graphics.DrawProcedural.
Everything works perfectly on Windows DX11, but on Android (Vulkan) my data isn’t being rendered, and I get the following error in logcat:
Shader requires vertex data and is not compatible with DrawIndexedNullGeometry
I get a value of 72 for SystemInfo.maxComputeBufferInputsVertex, so the GPU definitely seems to support StructuredBuffers. I feel like this should definitely be working, so I’m wondering whether this is perhaps a Unity bug?
I’ve also confirmed that SUPPORT_STRUCTUREDBUFFER is being defined on Vulkan.
Details:
- Unity Version: 2019.4.23f1
- Graphics API: Vulkan
- Phone: Xiaomi Mi 9T Pro
- Android Version: 10 QKQ1.190825.002
Edit: I just tried it on the most recent version of Unity, 2021.1.3f1, and I get an identical error
Has anyone else had success getting Graphics.DrawProcedural to work on Android?
I’ve made a very pared-down example, which still has the error - literally just building a procedural quad on the CPU and sending it to a shader as a ComputeBuffer. Works on PC, fails with the same error on Android.
The example project is attached to the post (31kB unity project)
=====================================================================
Here’s the code:
using UnityEngine;
public class MinimalTest : MonoBehaviour
{
public Material DrawMaterial;
private ComputeBuffer _buffer;
private GraphicsBuffer _indexBuffer;
private Bounds _bounds;
public void Awake()
{
_buffer = new ComputeBuffer(4, sizeof(float) * 4);
_buffer.SetData(new[]
{
new Vector4(-0.5f, 0f, -0.5f, 0.0f),
new Vector4(-0.5f, 0f, 0.5f, 0.3f),
new Vector4( 0.5f, 0f, 0.5f, 0.6f),
new Vector4( 0.5f, 0f, -0.5f, 1.0f),
});
_indexBuffer = new GraphicsBuffer(GraphicsBuffer.Target.Index, 6, sizeof(int));
_indexBuffer.SetData(new[] {0, 1, 2, 2, 3, 0});
_bounds = new Bounds(Vector3.zero, Vector3.one * 10000f);
DrawMaterial.SetBuffer("_VertexBuffer", _buffer);
}
public void Update()
{
Graphics.DrawProcedural(DrawMaterial, _bounds, MeshTopology.Triangles, _indexBuffer, _indexBuffer.count);
}
public void OnDestroy()
{
_buffer.Release();
_indexBuffer.Release();
}
}
And here’s the shader:
Shader "Test/MinimalTest"
{
SubShader
{
Tags { "RenderType"="Opaque" }
CGPROGRAM
#pragma surface surf Standard fullforwardshadows vertex:vert
#pragma target 5.0
#if SHADER_TARGET >= 35 && (defined(SHADER_API_D3D11) || defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE) || defined(SHADER_API_XBOXONE) || defined(SHADER_API_PSSL) || defined(SHADER_API_SWITCH) || defined(SHADER_API_VULKAN) || (defined(SHADER_API_METAL) && defined(UNITY_COMPILER_HLSLCC)))
#define SUPPORT_STRUCTUREDBUFFER
#endif
#ifdef SUPPORT_STRUCTUREDBUFFER
StructuredBuffer<float4> _VertexBuffer;
#endif
struct Input {
float4 color : COLOR;
};
struct appdata
{
float4 vertex : POSITION;
float3 normal : NORMAL;
uint vid : SV_VertexID;
};
void vert(inout appdata v, out Input o)
{
UNITY_INITIALIZE_OUTPUT(Input, o);
#ifdef SUPPORT_STRUCTUREDBUFFER
float4 CurrentVertex = _VertexBuffer[v.vid];
v.vertex.xyz = CurrentVertex;
v.normal = float3(0, 0, 1);
o.color = float4(1, 1, 1, 1);
#endif
}
void surf (Input IN, inout SurfaceOutputStandard o)
{
o.Albedo = float4(1, 1, 1, 1);
}
ENDCG
}
}
7045669–835468–AndroidDrawProcedural_MinimalTest.zip (30.5 KB)