Does Burst not work with NativeQueue?
D:\UnityDevelopment\MapGenerator\Library\PackageCache\com.unity.collections@0.1.1-preview\Unity.Collections\NativeQueue.cs(97,17): error: The managed class type `Unity.Collections.NativeQueueBlockPoolData*` is not supported. Loading from a non-readonly static field `Unity.Collections.NativeQueueBlockPool.data` is not supported by burst
at Unity.Collections.NativeQueueBlockPool.get_QueueBlockPool() (at D:\UnityDevelopment\MapGenerator\Library\PackageCache\com.unity.collections@0.1.1-preview\Unity.Collections\NativeQueue.cs:97)
at Unity.Collections.NativeQueue`1<System.Int32>..ctor(Unity.Collections.NativeQueue`1<int>* this, Unity.Collections.Allocator label) (at D:\UnityDevelopment\MapGenerator\Library\PackageCache\com.unity.collections@0.1.1-preview\Unity.Collections\NativeQueue.cs:306)
at ContinentDetection.Execute(ContinentDetection* this) (at D:\UnityDevelopment\MapGenerator\Assets\Scripts\InitializationData\ContinentDetection.cs:156)
at Unity.Jobs.IJobExtensions.JobStruct`1<ContinentDetection>.Execute(ref ContinentDetection data, System.IntPtr additionalPtr, System.IntPtr bufferRangePatchData, ref Unity.Jobs.LowLevel.Unsafe.JobRanges ranges, int jobIndex) (at C:\buildslave\unity\build\Runtime\Jobs\Managed\IJob.cs:30)
While compiling job: System.Void Unity.Jobs.IJobExtensions/JobStruct`1<ContinentDetection>::Execute(T&,System.IntPtr,System.IntPtr,Unity.Jobs.LowLevel.Unsafe.JobRanges&,System.Int32)
Allocation NativeQueue inside Burst - no. You only can pass NativeQueue in to job as field allocated outside.
1 Like
I just tried to do the same thing and got the same error message and read this post. So I made my own queue for use in bursted jobs. I’ve only lightly tested it so far. Please let me know if you try it and discover any bugs so I can fix them for my own projects too.
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
using Unity.Jobs;
public struct Queue<T> where T : unmanaged
{
UnsafeList<T> list;
int front;
int back;
public int Count => list.Length;
public int Capacity => list.Capacity;
public bool IsCreated => list.IsCreated;
public bool IsEmpty => list.Length <= 0;
public bool IsFull => list.Length >= list.Capacity;
public Queue(Allocator alloc, int initialCapacity = 1)
{
list = new UnsafeList<T>(initialCapacity, alloc);
front = 0;
back = -1;
}
public void Enqueue(in T value)
{
if (IsFull)
{
DoubleCapacityAndCopyValues();
}
back = (back + 1) % Capacity;
list[back] = value;
list.Length++;
}
public bool TryDequeue(out T value)
{
if (IsEmpty)
{
value = default;
return false;
}
int index = front;
front = (front + 1) % Capacity;
list.Length--;
value = list[index];
return true;
}
public bool TryPeek(out T value)
{
if (IsEmpty)
{
value = default;
return false;
}
value = list[front];
return true;
}
void DoubleCapacityAndCopyValues()
{
int oldCapacity = Capacity;
list.SetCapacity(oldCapacity + 1);
for (int i = 0; i < front; i++)
{
list[oldCapacity + i] = list[i];
}
back = front + oldCapacity - 1;
}
public void Dispose()
{
list.Dispose();
}
public JobHandle Dispose(JobHandle jobHandle)
{
return list.Dispose(jobHandle);
}
}