Search Unity

DrawMeshInstanced has bad perfomance on some Android devices

Discussion in 'General Graphics' started by Sagrell, Feb 2, 2021.

  1. Sagrell

    Sagrell

    Joined:
    Feb 22, 2018
    Posts:
    5
    I tried 2 different method:
    1. Spawn 5k same units with MeshRenderer and same material that support gpu instancing.
    2. Draw 5k same units with the same material with DrawMeshInstanced.

    Results on modern android devices (Adreno 630 (OpenGL ES 3.2) and Snapdragon 845), pc and editor:
    1. 60fps
    2. 180fps (3 times faster)

    Results on device with Adreno 506 (OpenGL ES 3.2) and Snapdragon 625
    1. 15fps
    2. 14fps (Slower! Why?)

    I have no idea what cause it. Fps drops, when it should be 3 times faster. Profiler says only that in first case it spends all the time on Camera.Render. And in the second case on GFx.WaitForPresent. Vsync is turned off.
    Logically first method has huge overhead, cause MeshRenderer has a lot of work to do, to be rendered, but on some devices it magically better that simple DrawMeshInstanced. Any idea?)
     
  2. joelv

    joelv

    Unity Technologies

    Joined:
    Mar 20, 2015
    Posts:
    203
    WaitForPresent taking time means that you are GPU bound. For some reason the instancing way of rendering takes much longer time for the GPU in your case. Do you have a custom shader or is it a unity provided shader? It might just be that you hit a really slow path on that specific GPU model for some reason.
     
  3. Sagrell

    Sagrell

    Joined:
    Feb 22, 2018
    Posts:
    5
    Thanks for answer) Yeah, I know that WaitForPresent means i'm gpu bounds. But the problem is in both cases I use the same shader, material and mesh. The only differens is that in first case it just 5k gameobjects with MeshRenderer and Unity renders it in normal way. And in the second case I render it via script with DrawMeshInstanced. Everything else is the same.
    If problem is in GPU perfomance, I still should have better results with DrawMeshInstanced, cause gpu renders the same stuff, but it don't need to handle all gameobjects stuff etc.

    Shader is custom. I tried to simplify it. But result is the same. Also I tried different unity versions, with no profit.
    It's not only on 1 device also problem occurs on device with Snapdragon 435 and Adreno 505 (OpenGL ES 3.2)
     
    Last edited: Feb 2, 2021
  4. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    3,023
    Are those 5k objects the only thing being rendered?
    Any postprocessing enabled, by chance?
     
  5. Sagrell

    Sagrell

    Joined:
    Feb 22, 2018
    Posts:
    5
    Yes, scene doesn't even have plane. No postprocessing.
    I'm making mobile game with DOTS, and I need to render with DrawMeshInstanced, but I mention that on some devices my game has low perfomance, after research I realized that problem is unexpectedly in DrawMeshInstanced. So I created new empty scene and make 2 test cases which I described. And they show, that it's true. But I have no idea why

    My version is that maby there is a problem with some sync between CPU and GPU when using DrawMeshInstanced on some devices and that cause long waiting time. But it's just a guess, because I don't know what under the hood. Hope this can be fixed:(

    Also, I tried to use CommandBuffer for my Camera with CommandBufferPool, no effect

    P.S. Test is correct, I'm using buffers of matrices to render with DrawMeshInstanced, and there is no.
    additional allocation. So, it's just clear DrawMeshInstanced vs GameObject + MeshRenderer.
     
    Last edited: Feb 3, 2021
  6. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    3,023
    It would be great if you could submit a bug report so that we can investigate this internally. Thanks!
     
  7. Sagrell

    Sagrell

    Joined:
    Feb 22, 2018
    Posts:
    5
    Okay, Thanks!