Any way to allocate memory inside bursted jobs ?

Hello everyone,
I’m looking for a way to allocate memory inside bursted jobs and return them to the main thread, using Marshal.AllocHGlobal is prohibited by burst. I tried to discard a function which allocate the memory but there’s no way to return the pointer from it.

any suggestion is appreciated
Thank you!

I might not understand your use case, but why don’t you just use a persistent NativeArray in the system and pass it to the jobs ?

1 Like

hi @Razmot , btw thanks again for your help :slight_smile:
im trying to pass a NativeArray to a frustom culling job. the job will simply collect a float4x4 of all visible entities.
im looking for a way to return a NativeArray per RenderMeshIndex (the index of the RenderMesh SCD in the big SCDs list).

my current working version (but can’t be bursted):
im passing a NativeQueue to the IjobParallelFor and each RenderMeshIndex calculation is running into the same Worker thread. after all the calculation im allocating the result to the memory using Marshal.AllocHGlobal and passing it’s intPtr to the BufferStruct which is added to the NativeQueue. then i reconstruct the arrays from the main thread foreach element in the Queue.
but calling the Marshal.AllocHGlobal is not allowed by Burst.

public struct BufferStruct
{
     public int SharedRenderMeshIndex;
     public int Count;
     public IntPtr VerticesArrayPtr;
 }

NativeStream should match your usage pretty perfectly. This allows sub list by index of any blittable type. So you can return a float4x4 ‘list’ for each entry in your NativeArray.

I didn’t really use it so far, somewhat like this:

protected override JobHandle OnUpdate(JobHandle inputDeps)
{
    var stream = new NativeStream(archetypes.Length, Allocator.TempJob);
    var writeTransforms = new WriteTransforms {writer = stream.AsWriter(), archetypes = archetypes}.Schedule(archetypes.Length, inputDeps);
    var handleResult = new HandleResult {reader = stream.AsReader(), archetypes = archetypes}.Schedule(archetypes.Length, writeTransforms);
    // todo: cleanup stream somewhere
    return handleResult
}

struct WriteTransforms : IJobParallelFor
{
    public NativeStream.Writer writer;
    public NativeArray<EntityArchetype> archetypes;

    public void Execute(int index)
    {
        var archetype = archetypes[index]
        Writer.BeginForEachIndex(index);
        Writer.Write<float4x4>(default);      
        Writer.Write<float4x4>(default);      
        Writer.Write<float4x4>(default);      
        Writer.Write<float4x4>(default);      
        Writer.Write<float4x4>(default);      
        Writer.Write<float4x4>(default);      
        Writer.EndForEachIndex();
    }
}

struct HandleResult : IJobParallelFor
{
    public NativeStream.Reader reader;
    public NativeArray<EntityArchetype> archetypes;

    public void Execute(int index)
    {
        int count = Reader.BeginForEachIndex(index);
        for (int i = 0; i != count; i++)
        {
            var value = Reader.Read<float4x4>();
        }
        Reader.EndForEachIndex();
    }
}
3 Likes

im sorry but i dont see how can i get the multiple Linear Datas from the HandleResult Job.
maybe the only way to do it is reconstructing every NativeArray by index from the main thread.

NativeList can be burstified and it will need a resize at a given point when Add are used, right?

NativeList uses
UnsafeUtility.Malloc(bytesToMalloc, alignOf, Allocator); maybe that Malloc can be used with Burst

2 Likes

that’s really awesome! i just tested it and it works like a charm!
i had tested it before but wasnt working i think waybe i had some issues within my code and was thinking the problem is comming from UnsafeUtility.Malloc.
Thanks a lot !!

1 Like