How to use RaycastCommand when command count is based on job result?

Got a query of N entities, and DynamicBuffer of data that is required for raycasting.
Data is processed inside job and commands are added to the commands NativeList.

Problem is that commands and results arrays are arrays allocated on main thread, and passed to the RaycastCommand.ScheduleBatch job.

Technically, I can figure out total entity count by the query, then iterate on main thread, include lenth of each DynamicBuffer and allocate array afterwards. But that seems kind of counterproductive.

So it boils down to figuring out sum of DynamicBuffer.Length from the entity query.

Any suggestions / maybe some clever hack to figure it out ?

I am not sure if I understand clearly, what are the commands and results arrays typed as? If it is NativeList and you initialize it in the main thread, you could resize it in the job to whatever the size(not for parallel though).

Those are RaycastCommand and RaycastHit respectively.
And since they’re passed to the RaycastCommand.ScheduleBatch don’t think they can be resized.

Because internally it looks like this (RaycastCommand.cs):

    public static unsafe JobHandle ScheduleBatch(
      NativeArray<RaycastCommand> commands,
      NativeArray<RaycastHit> results,
      int minCommandsPerJob,
      JobHandle dependsOn = default (JobHandle))
    {
      BatchQueryJob<RaycastCommand, RaycastHit> output = new BatchQueryJob<RaycastCommand, RaycastHit>(commands, results);
      JobsUtility.JobScheduleParameters parameters = new JobsUtility.JobScheduleParameters(UnsafeUtility.AddressOf<BatchQueryJob<RaycastCommand, RaycastHit>>(ref output), BatchQueryJobStruct<BatchQueryJob<RaycastCommand, RaycastHit>>.Initialize(), dependsOn, ScheduleMode.Batched);
      return RaycastCommand.ScheduleRaycastBatch(ref parameters, NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks<RaycastCommand>(commands), commands.Length, NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks<RaycastHit>(results), results.Length, minCommandsPerJob);
    }

Total size of both are taken at the schedule time.

Now I’ve got a deja vu, like I’ve already asked this question. (Probably did, and forgot)

Edit:

Definitely did, now I remember that its not possible.
Guess I’ll just iterate on main thread, shouldn’t take that much time just to figure out total count in my case.

Anyways, if anyone has other suggestions - I’m all ears.

In the example here, Unity - Scripting API: RaycastCommand, the job takes a Temp, which could means the array can be reallocated to somewhere else. However, the example also expects one result. I ma not sure about the behavior here, have you try to pass just new NaitveArray(1, Allocator.Temp) as the result array?

That won’t work, since internally they use command.Length and results.Length at schedule time for some reason. (Probably poorly written API)

Main thread option works by the way (iterating over and getting total count from dynamic buffers):

         Entities.ForEach((in DynamicBuffer<DetectionHit> hits) => totalCount += hits.Length)
                 ...
                 .Run();

then allocating required arrays.

But it causes a sync points based on dependencies I’d like to avoid syncing from (since they could be heavy’ish in theory).

Alternative I was thinking on was to allocate large buffers prematurely. Or to allocate specific size DynamicBuffers.
(to just compute size as N_EntityCount * ConstSize).
First solution will cause major issues if there’s too many hits and buffers overflow, so its a bad one.
Second one is potentially possible (manually limiting max length in systems).
So most-likely that will be my go to solution.
Edit: Technically won’t work as well, since those extra structs / commands would be performed, which is bad.