Search Unity

Command buffers in 2019.3 vs 2019.2

Discussion in 'Data Oriented Technology Stack' started by RBogdy, Oct 11, 2019.

  1. RBogdy

    RBogdy

    Joined:
    Mar 6, 2019
    Posts:
    38
    I observed that when using Entity Command Buffers in Unity 2019.3.0b6, doing any operations with the Command Buffer (add, remove, modify components) to an entity requires removing the [ReadOnly] tag from the CommandBuffer declaration inside a job.

    My use case is similar to the MousePick from the Physics Sample, in that I use a job to cast a ray from the screen to the Camera far Plane, check if it hits an object I want, and if it does I mark that object with a Selected tag component.
    Then in another job I apply an impulse to the object and I try to remove the Selected component, however here in the 2nd job I get an error saying that the CommandBuffer should be marked as [ReadOnly]. When I do mark it, I get an error saying that I should remove the [ReadOnly] tag as I execute modifications.

    This behavior is not visible in 2019.2.8f1 and the buffer works as expected with the [ReadOnly] tag in place

    Is this some sort of bug?
     
    Opeth001 likes this.
  2. Preslavb

    Preslavb

    Joined:
    Jul 1, 2014
    Posts:
    3
    Hey, just making sure, are you using the Concurrent version of your command buffer within the job? You cannot pass a normal CommandBuffer to a parallel job, you need to use CommandBuffer.Concurrent
     
  3. RBogdy

    RBogdy

    Joined:
    Mar 6, 2019
    Posts:
    38
    No, I don't use concurrent version. However why is it working in 2019.2 without concurrent?
     
  4. Preslavb

    Preslavb

    Joined:
    Jul 1, 2014
    Posts:
    3
    Difficult to say, might be that someone forgot to put the [ReadOnly] requirement in the package? No idea really. Do try using the Concurrent API though, that one is threadsafe and so works in parallel jobs by passing in an index. Without it, you would have no way of knowing where its okay to push a new command into the command buffer, as another thread might also be writing to the same index at the same time, and you end up getting jumbled memory. To get the concurrent version of your (existing) command buffer, you go commandBuffer.ToConcurrent(). Alternatively, you can create your own command buffer, schedule you job with handle = job.Schedule, then wait for handle.Complete(), and the do commandBuffer.Playback()
     
  5. RBogdy

    RBogdy

    Joined:
    Mar 6, 2019
    Posts:
    38
    I don't use Parallel Jobs as well. Just IJob and IJobForEachWithEntity
     
  6. Creepgin

    Creepgin

    Joined:
    Dec 14, 2010
    Posts:
    297
    IJobForEachWithEntity
    by default runs parallel. You need to use
    ScheduleSingle
    to schedule the job for single thread.

    If you are sure of the safety and want to run it parallel, you can use
    [NativeDisableParallelForRestriction]
    on the EntityCommandBuffer. In most cases though, you should use
    EntityCommandBuffer.Concurrent
    .

    The safety system was not really enforcing this rule before entities-0.1.0.
     
    Last edited: Oct 11, 2019
  7. RBogdy

    RBogdy

    Joined:
    Mar 6, 2019
    Posts:
    38
    Using ScheduleSingle works well in 2019.3, without the [ReadOnly] tag. Still a mystery why with the same package versions in 2019.2 works different