Search Unity

cpu-present time, presentRenderbuffer problem

Discussion in 'iOS and tvOS' started by leon_smerc, Dec 2, 2009.

  1. leon_smerc

    leon_smerc

    Joined:
    Sep 9, 2009
    Posts:
    15
    I'm not incredibly familiar with OpengGLES and don't exactly understand what cpu-present time is. As defined in the docs "cpu-present: Stands for amount of time spent executing presentRenderbuffer command in OpenGLES"


    This number was always 1-2 ms and so I mostly ignored it, but all of a sudden I've reached a limit where at a certain point it goes from 1-2 ms to 15-20.

    What affects this time? How can it be lowered? Even the most basic information would be helpful. Thanks!
     
  2. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    how many drawcalls and textures do you have?
     
  3. leon_smerc

    leon_smerc

    Joined:
    Sep 9, 2009
    Posts:
    15
    The short answer is, this happens with as few as 11 draw calls and 18 batched,but with large textures.

    Here is a frame in which it's low, and up to this point has stayed below 2.1 ms

    cpu-player> min: 7.4 max: 320.0 avg: 29.1
    cpu-ogles-drv> min: 2.7 max: 6.9 avg: 4.3
    cpu-present> min: 1.3 max: 3.2 avg: 1.6
    frametime> min: 31.9 max: 328.2 avg: 48.5
    draw-call #> min: 11 max: 13 avg: 12 | batched: 16
    tris #> min: 2689 max: 2741 avg: 2721 | batched: 84
    verts #> min: 4921 max: 5017 avg: 4985 | batched: 64
    player-detail> physx: 0.7 animation: 0.0 culling 0.8 skinning: 0.0 batching: 0.2 render: 6.9 fixed-update-count: 1 .. 10
    mono-scripts> update: 19.0 fixedUpdate: 0.0 coroutines: 0.1
    mono-memory> used heap: 3018752 allocated heap: 5054464 max number of collections: 2 collection total duration: 89.5



    Then the next two outputs have huge garbage dumps:
    cpu-player> min: 7.8 max: 403.8 avg: 26.1
    cpu-ogles-drv> min: 2.7 max: 5.7 avg: 4.1
    cpu-present> min: 0.8 max: 32.4 avg: 10.1
    frametime> min: 31.3 max: 412.8 avg: 52.8
    draw-call #> min: 11 max: 12 avg: 11 | batched: 17
    tris #> min: 2741 max: 2787 avg: 2777 | batched: 90
    verts #> min: 5017 max: 5109 avg: 5090 | batched: 68
    player-detail> physx: 0.6 animation: 0.0 culling 0.6 skinning: 0.0 batching: 0.1 render: 6.9 fixed-update-count: 0 .. 10
    mono-scripts> update: 18.2 fixedUpdate: 0.0 coroutines: 0.1
    mono-memory> used heap: 2498560 allocated heap: 5054464 max number of collections: 4 collection total duration: 181.0



    cpu-player> min: 7.0 max: 406.1 avg: 30.0
    cpu-ogles-drv> min: 2.7 max: 6.2 avg: 4.3
    cpu-present> min: 1.3 max: 24.0 avg: 5.3
    frametime> min: 31.8 max: 415.4 avg: 51.7
    draw-call #> min: 11 max: 12 avg: 11 | batched: 17
    tris #> min: 2787 max: 2841 avg: 2819 | batched: 95
    verts #> min: 5109 max: 5209 avg: 5167 | batched: 71
    player-detail> physx: 0.6 animation: 0.0 culling 0.6 skinning: 0.0 batching: 0.1 render: 7.0 fixed-update-count: 1 .. 10
    mono-scripts> update: 21.1 fixedUpdate: 0.0 coroutines: 0.1
    mono-memory> used heap: 2555904 allocated heap: 5054464 max number of collections: 4 collection total duration: 183.4




    And then after that it remains high (here's the next frame):

    iPhone Unity internal profiler stats:
    cpu-player> min: 7.4 max: 12.5 avg: 10.4
    cpu-ogles-drv> min: 3.5 max: 6.0 avg: 4.2
    cpu-present> min: 1.5 max: 32.0 avg: 16.4
    frametime> min: 31.0 max: 51.6 avg: 37.2
    draw-call #> min: 11 max: 11 avg: 11 | batched: 18
    tris #> min: 2841 max: 2841 avg: 2841 | batched: 96
    verts #> min: 5209 max: 5209 avg: 5209 | batched: 72
    player-detail> physx: 0.6 animation: 0.0 culling 0.6 skinning: 0.0 batching: 0.1 render: 6.5 fixed-update-count: 1 .. 2
    mono-scripts> update: 2.1 fixedUpdate: 0.0 coroutines: 0.0
    mono-memory> used heap: 2555904 allocated heap: 5054464 max number of collections: 0 collection total duration: 0.0



    So as you can see I have 11 draw calls with 18 batched. There are a lot of textures tho, this game uses large spritesheets but I'd previously had 70ish batched sprite animations using more textures and never seen this number jump.
     
  4. leon_smerc

    leon_smerc

    Joined:
    Sep 9, 2009
    Posts:
    15
    I've been experimenting a lot trying to uncover what causes the problem and am still largely clueless, except what's strange is, it's a semi-2d game allowing pinch zoom and if I zoom OUT (which shows more draw/batches) the extra render time goes away.

    Any help would be awesome!
     
  5. ReJ

    ReJ

    Unity Technologies

    Joined:
    Nov 1, 2008
    Posts:
    378
    If you see large numbers coming from cpu-present, then most probably you're GPU bound - OpenGLES driver is waiting on a GPU to finish its job before flipping front and back buffers ("presenting" in terms of OpenGLES).
     
  6. leon_smerc

    leon_smerc

    Joined:
    Sep 9, 2009
    Posts:
    15
    Ok I get it now. So what things contribut to gpu-binding given low verts, draw calls and render time? Alpha-testing? Render queues? uv animating?

    Thanks for any help!
     
  7. rozgo

    rozgo

    Joined:
    Feb 7, 2008
    Posts:
    158
    I've had this happen to me whenever the final texel is way bigger than the pixel. Ironically, I fixed this by increasing the size of the tetxure to better match the final size. In texture minification mipmap fixes this, but not for magnification. I believe texture filtering probably works more to compensate.
     
  8. leon_smerc

    leon_smerc

    Joined:
    Sep 9, 2009
    Posts:
    15
    I'm using a part of a large texture (uv animation).. for magnification you'd say larger cell sizes could maybe help?
     
  9. rozgo

    rozgo

    Joined:
    Feb 7, 2008
    Posts:
    158
    You can do several things... change uv size, texture size, camera FOV, or camera distance; whatever makes the texture on screen not stretch too much, as to create texture pixels bigger than screen pixels.

    This is unavoidable, and normally not a problem, but with some billboards, sprites or other flat facing objects it can be a problem since it can add to your fillrate.

    From wikipedia:
    It's this texture magnification that I have found can make the cpu-present time jump to unacceptable numbers.

    This is the behavior I observed, and can't guaranty it was the sole reason.
     
  10. rozgo

    rozgo

    Joined:
    Feb 7, 2008
    Posts:
    158
    Basically, your texture size will determine how close you can get before texture filtering has to do too much work.

    You can either clamp the amount of zoom, or make your texture even bigger so it can handle closeups. Also make sure there is enough geometry to allow the engine to cull more efficiently.
     
  11. leon_smerc

    leon_smerc

    Joined:
    Sep 9, 2009
    Posts:
    15
    This is a case of flat planes directly facing the camera with uv-animated spritesheets. I suppose this theory makes a lot of sense considering what I posted about certain zoom levels performing better.
     
  12. goodhustle

    goodhustle

    Joined:
    Jun 4, 2009
    Posts:
    310
    This might be off-base, but are you using an alpha test shader on your sprites? If you have an alpha test sprite covering a good portion of the screen, my understanding is that the cpu-present spikes may correspond to fillrate issues.
     
  13. leon_smerc

    leon_smerc

    Joined:
    Sep 9, 2009
    Posts:
    15
    That's not off-base at all.. The many transparent sprites' shader has Alphatest Greater 0.5 but they are small relative to the screensize. There is however one large alpha-tested plane that doesn't need to be there covering the entire screen.
     
  14. ReJ

    ReJ

    Unity Technologies

    Joined:
    Nov 1, 2008
    Posts:
    378
    What texture sampling (filtering) mode do you use in that case? I saw that you use point sampling quite extensively... Does it give you performance troubles in case of magnification too?

    Alpha-testing is more expensive than alpa-blending on iPhone, try reducing it usage as much as possible (use alpha-blending if you can or remove that plane altogether ;) )

    Even if you have low vertex counts, you can have a lot of overdraw if alpha-blending/alpha-testing is involved. Overdraw means drawing things on top of each other multiple times. That could significantly increase work for GPU.

    UV animation on other hand does not really take any additional GPU resources.
     
  15. leon_smerc

    leon_smerc

    Joined:
    Sep 9, 2009
    Posts:
    15
    Thanks so much for your guys' help. Surprisingly, I moved a big transparent overlay and all my problems went away (at least for now!)

    So since I have so many intelligent people involved, I'll also post an overview of my character drawings just in case you guys have any more efficiency tips.

    So in the beginning I used transparent/vertex lit and everything looked ok, but some of my guys wouldn't batch. In fact the more things I added, the less batching I got (despite many things being the same material with only 4 verts). I discovered transparent/cutout/vertexlit did not share this problem, so I used it. After awhile, I discovered shader writing isn't so tough and made my own that goes like this:


    Shader "CharacterShader" {
    Properties {
    _Color ("Main Color", Color) = (1,1,1,1)
    _MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
    }

    Category{
    SubShader {
    Pass {
    ZWrite On
    Alphatest Greater .3
    //Blend SrcAlpha OneMinusSrcAlpha
    Lighting Off
    SeparateSpecular Off

    SetTexture [_MainTex] {
    constantColor [_Color]
    Combine texture * constant DOUBLE, texture * constant
    }
    }
    }
    }
    }




    So, the three important lines (for me) are:

    ZWrite On
    Alphatest Greater .3
    Blend SrcAlpha OneMinusSrcAlpha


    So, If I drop the alphatest and leave ZWrite on and alpha blending, Sprites are hidden behind the transparent areas of the ones in front of them.

    If I then turn the ZWrite off, no sprite is blocked by the transparent area BUT certain materials are always written on top of others, regardless of proper order. I don't really get why.

    So, in the end ZWrite is on (as is default) and I have to have the alpha test.. the alpha blending then is optional. I'm attaching some photos to describe it better.

    If anyone has any better suggestions please let me know!
     

    Attached Files: