Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice

Unity 5.6.0f1 DrawMeshInstancedIndirect performance problems

Discussion in '5.6 Beta' started by geroppo, Mar 18, 2017.

  1. geroppo

    geroppo

    Joined:
    Dec 24, 2012
    Posts:
    140
    Hi, I just downloaded the latest version of unity 5.6 beta because I wanted to try out the DrawMeshInstancedIndirect method that wasn't available in 5.5. Since this version JUST came out I don't know if it's a bug that wasn't here in previous 5.6 versions, or I'm doing something wrong.
    I'm instancing large amounts of grass, and after a few seconds of playback the fps start to drop down until an out of video memory error pops up and I have to restart my pc.
    Because of that I thought that I was forgetting to release some buffer, but it wasn't the case. Also in the profiler (when it starts to freeze) I noticed in the CPU a few spikes in the "others" category...and I don't know what "others" is. I will attach some screenshots from the profiler, as well as the code that I'm using to initialize everything. The code sample is using DrawInstanced in the update loop, but also tried with a command buffer and the result is the same. And btw using Graphics.DrawMeshInstancedIndirect causes the camera.renderskybox to take like 6ms to render it (4.5 in this screenshot), this doesn't happen when I use a command buffer.

    Code (CSharp):
    1. public PointGenerator point_generator;
    2.     public int matrix_instance_count = 1023;
    3.  
    4.  
    5.     ComputeBuffer grass_render_args;
    6.     ComputeBuffer grass_positions_buffer;
    7.  
    8.  
    9.     public Material grass_instancing_mat;
    10.  
    11.     public Mesh grass_mesh_LOD0;
    12.  
    13.  
    14.  
    15.  
    16.     void Start()
    17.     {
    18.      
    19.         SetupGrassBuffers();
    20.         //SetupCommandBuffer();
    21.     }
    22.  
    23.     void Update()
    24.     {
    25.         Graphics.DrawMeshInstancedIndirect(grass_mesh_LOD0, 0, grass_instancing_mat, new Bounds(Vector3.zero,new Vector3(100,10,100)), grass_render_args);
    26.     }
    27.  
    28.  
    29.     void SetupGrassBuffers()
    30.     {
    31.         List<Vector3> positions = new List<Vector3>();
    32.  
    33.  
    34.         int grass_instance_count = 625;
    35.  
    36.         positions.AddRange(point_generator.GenerateRandomPoints(grass_instance_count, 2f,5f));
    37.         positions.AddRange(point_generator.GenerateRandomPoints(grass_instance_count, 5f,10f));
    38.         positions.AddRange(point_generator.GenerateRandomPoints(grass_instance_count, 10f,15f));
    39.         positions.AddRange(point_generator.GenerateRandomPoints(grass_instance_count, 10f,15f));
    40.         positions.AddRange(point_generator.GenerateRandomPoints(grass_instance_count, 10f,15f));
    41.  
    42.  
    43.         for(int i=5; i< 15; i++)
    44.         {
    45.             positions.AddRange(point_generator.GenerateRandomPoints(grass_instance_count, 2f,5f));
    46.         }
    47.         for(int i=15; i< 20; i++)
    48.         {
    49.             positions.AddRange(point_generator.GenerateRandomPoints(grass_instance_count, 15f,20f));
    50.         }
    51.  
    52.         //######################################
    53.         //######################################
    54.  
    55.         grass_positions_buffer = new ComputeBuffer(positions.Count,sizeof(float)*3);
    56.  
    57.         grass_positions_buffer.SetData(positions.ToArray());
    58.  
    59.         grass_instancing_mat.SetBuffer("positions_buffer", grass_positions_buffer);
    60.  
    61.  
    62.         //######################################
    63.         //######################################
    64.  
    65.         grass_render_args = new ComputeBuffer(1,5 * sizeof(int),ComputeBufferType.IndirectArguments);
    66.         int mesh_index_count = grass_mesh_LOD0.GetIndices(0).Length;
    67.         int instance_count = positions.Count;
    68.         int start_index_location = 0;
    69.         int base_vertex_location = 0;
    70.         int start_instance_location = 0;
    71.         grass_render_args.SetData(new int[]{mesh_index_count, instance_count, start_index_location, base_vertex_location, start_instance_location});
    72.     }
    73.  
    74.  
    75.     void OnDisable()
    76.     {
    77.         grass_positions_buffer.Release();
    78.         grass_render_args.Release();
    79.     }
    Screenshot_1.png Screenshot_2.png
     
    MrEsquire likes this.
  2. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,618
    Using the forum for bug-reporting isn't the best way to report an issue that is important to you, but can be used to give it a little more attention.

    If you found an error in Unity, I recommend to submit a bug-report following the advice in this document. Using the bug-reporter seems to be an important step, because that makes sure the report is in their bug-tracking pipeline and has to be processed at some point.

    It's advantageous to attach a project to the bug-report that Unity can use to reproduce the issue and test their fix against.

    From my experience, Unity prefers to get spoon-fed with a small project that they can use to easily reproduce the issue you're reporting, along with a how-to-reproduce list in baby-steps. I often record a video that shows how to reproduce the issue with the project I submit along with the bug-report, just to make sure to avoid any ambiguity. Depending on the complexity of the issue you're reporting, a video might not be necessary.

    The easier an issue can be reproduced by QA, the more likely it is to get forwarded to a developer, who might or might not work on a bug-fix for that at some point.

    After you submitted the bug-report, you receive a confirmation email with a Case number. Unity often asks us to post the Case number in the forum thread, which allows them to find that bug-report if they look at your post.

    Following these steps will increase the chance that Unity is looking at your issue tremendously.
     
    Last edited: Mar 18, 2017
  3. geroppo

    geroppo

    Joined:
    Dec 24, 2012
    Posts:
    140
    Alright I will submit it as a bug report then. The reason I came here first was because I didn't know if I was doing the initialization right, and didn't want to submit a report for a careless mistake (the skybox thigs does look like a bug tho).
     
    LeonhardP and Peter77 like this.
  4. LeonhardP

    LeonhardP

    Unity Technologies

    Joined:
    Jul 4, 2016
    Posts:
    3,136
    Hi geroppo,
    Thanks for your help. Once you submitted the report and know the case #, please reference it here.
     
  5. geroppo

    geroppo

    Joined:
    Dec 24, 2012
    Posts:
    140
    Sorry it took so long, I just submitted it. (#893184)
    It turned out that the memory crash was unrelated to the DrawMeshInstanced thing. I don't know yet exactly what was that, but it was related to some post processing thing that I was doing in OnRenderImage that was conflicting with Unity's post processing anti aliasing. If I disabled the anti aliasing it was ok ( no memory crash) but I ended up just disabling my post processing effect due to time constraints, I will come back to it if I have the time.

    The skybox tho, as explained in the ticket, seems that Unity was registering the calls to DrawMeshInstanced as camera.renderSkybox, don't know why.