I’m testing running IJobParallelFor jobs that hold a DynamicBuffer. This is related to my previous post , but now I found another error. Here’s the test code:
[AlwaysUpdateSystem]
public class DynamicBufferInIJobParallelFor : JobComponentSystem {
// Just a tag for filtering
private struct Filter : IComponentData {
}
private const int ENTITY_COUNT = 100;
private EntityQuery query;
private ArchetypeChunkBufferType<Int2BufferElement> bufferType;
protected override void OnCreate() {
// Create entities
for (int i = 0; i < ENTITY_COUNT; ++i) {
this.EntityManager.CreateEntity(typeof(Filter), typeof(Int2BufferElement));
}
this.query = GetEntityQuery(typeof(Filter), typeof(Int2BufferElement));
}
protected override JobHandle OnUpdate(JobHandle inputDeps) {
this.bufferType = GetArchetypeChunkBufferType<Int2BufferElement>();
JobHandle handle = inputDeps;
NativeArray<ArchetypeChunk> chunks = this.query.CreateArchetypeChunkArray(Allocator.TempJob);
for (int i = 0; i < chunks.Length; ++i) {
handle = ProcessParallelFor(chunks[i], handle);
}
chunks.Dispose();
return handle;
}
private JobHandle ProcessParallelFor(ArchetypeChunk chunk, JobHandle inputDeps) {
BufferAccessor<Int2BufferElement> accessor = chunk.GetBufferAccessor(this.bufferType);
JobParallelFor job = new JobParallelFor() {
accessor = accessor
};
return job.Schedule(chunk.Count, 64, inputDeps);
}
[BurstCompile]
private struct JobParallelFor : IJobParallelFor {
[NativeDisableContainerSafetyRestriction]
public BufferAccessor<Int2BufferElement> accessor;
public void Execute(int index) {
DynamicBuffer<Int2BufferElement> buffer = this.accessor[index];
buffer.Clear();
for (int i = 0; i < 1000; ++i) {
buffer.Add(new Int2BufferElement() {
value = new int2(i, i)
});
}
}
}
}
Put this code into your project and run an empty scene. This system will still run. It will run fine without problems. Now change ENTITY_COUNT from 100 to 300. It produces the following error:
InvalidOperationException: The previously scheduled job DynamicBufferInIJobParallelFor:JobParallelFor writes to the NativeArray JobParallelFor.accessor. You must call JobHandle.Complete() on the job DynamicBufferInIJobParallelFor:JobParallelFor, before you can read from the NativeArray safely.
I think the error happens when there are more than one chunk. But each chunk is processed one by one by JobHandle chaining. How can this be fixed?