I just spend my entire day trying to figure out why a ComputeShader was crashing my project and I now can finally reproduce it consistently.
I declare a groupshared memory buffer and dispatch a single thread group to fill it with numbers. Works perfectly (also on device, in this case Meta Quest2). I introduce a constant buffer read, and the Editor crashes with the log message:
Assertion failed on expression: ‘cbStateIndex < m_ConstantBufferStates.size()’
The crash only happens on OpenGLES3 (Android). I can’t make Vulcan work with groupshared at all. It works fine on DirectX11, but that defeats the purpose since I’m developing for Quest2.
EDIT:
I have now tested the same setup in 2020.3.31f1 and that works. However, that does not help me because other dependencies in my project prevents me from downgrading.
EDIT2:
I realised I used a SetFloat() that should have been a SetInt() … see post below.
```csharp
*using UnityEngine;
public class Test : MonoBehaviour
{
void Start()
{
Debug.Log( "Groupshared memory working: " + AssertGroupSharedMemory() );
}
bool AssertGroupSharedMemory()
{
const int count = 10;
var computeShader = Instantiate( Resources.Load( “Test” ) );
int kernel = computeShader.FindKernel( “Execute” );
// Create, fill and set a buffer of numbers.
var buffer = new ComputeBuffer( count, sizeof( int) );
int[] numbers = new int[ count ];
for( int i = 0; i < count; i++ ) numbers[ i ] = i;
buffer.SetData( numbers );
computeShader.SetBuffer( kernel, "_Buffer", buffer );
// Upload a value to a Unity managed constant buffer.
const int constantValue = 1;
computeShader.SetInt( "_ConstantValue", constantValue );
// Compute the result on the CPU.
int correctResult = 0;
for( int i = 0; i < numbers.Length; i++ ){
correctResult += numbers[ i ] + constantValue;
}
// Dispatch a single thread group (thread group size == groupshared buffer size).
computeShader.Dispatch( kernel, 1, 1, 1 );
// Readback the data.
int[] data = new int[ count ];
buffer.GetData( data );
// Check whether CPU and GPU agrees.
bool success = data[ 0 ] == correctResult;
// Clean up after the party.
buffer.Release();
Destroy( computeShader );
return success;
}
}*
```
And the ComputeShader “Test.compute” located in a Resources folder:
```csharp
*#pragma kernel Execute
#define COUNT 10
RWStructuredBuffer _Buffer;
int _ConstantValue;
groupshared int sharedNumbers[ COUNT ];
[numthreads(COUNT,1,1)]
void Execute(
uint gi : SV_GroupIndex // Local index within group
){
// Read number and store it in shared memory.
sharedNumbers[ gi ] = _Buffer[ gi ];
// Wait until all threads in this group reach this line.
GroupMemoryBarrierWithGroupSync();
// First thread (in group) does the rest of the work.
if( gi > 0 ) return;
int sum = 0;
for( int i = 0; i < COUNT; i++ ){
sum += sharedNumbers[ i ];
sum += _ConstantValue; //CRASH!! This line triggers the crash.
}
// Store for later readback (at index 0).
_Buffer[ gi ] = sum;
}*
```
Is this a bug, or am I missing something?