Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

[tiled base mobile rendering]Is Clear render target the only way to prevent "slow framebuffer load"?

Discussion in 'Image Effects' started by colin299, Aug 22, 2017.

  1. colin299

    colin299

    Joined:
    Sep 2, 2013
    Posts:
    181
    When doing GPU frame capture in XCode(iPhone5,GLES2), XCode shows a warning saying that my separable blur image effect cause "Slow framebuffer load" (it means GPU is getting the frame color data back from external slow ram, which is not needed in my case, because I will always render every pixel by a Graphics.Blit() call).
    20882931_10154952678965897_8203937589824258345_n.jpg
    It seems that I didn't clear the render target before my first draw call(actually, the only draw call is a blit() when pingpong), which makes the warning appear.

    I thought calling RenderTexture.DiscardContents() before unity's Graphics.Blit() is enough to hint the GPU to NOT restoring any data back from external slow ram, and Unity's doc said that it is best practice to discardContents using RenderTexture.GetTemporary() & RenderTexture.ReleaseTemporary() asap.
    But seems that Clearing the render target is the ONLY way to stop GPU restoring frame data, accroding to my XCode debugger.

    In order to remove this "Slow framebuffer load" warning...... after all render target switchs, I must clear the render target before my first draw call.
    But my code relied on unity's Graphics.Blit() to do the following for me.
    (1)Switch render target
    (2)draw full screen quad

    which unity's Graphics.Blit() will not clear the render target between (1) & (2), so if I use Graphics.Blit(), that "Slow framebuffer load" warning will always appear.
    ---------------------------------------------------------------------
    So I ended up replacing every Unity's Graphics.Blit() into a custom GraphicsBlit, which is the following method:
    Code (CSharp):
    1.  
    2. //replace every Graphics.Blit()
    3. void GraphicsBlitWrapper(
    4. Texture input, RenderTexture target, Material mat, int passNum
    5. )
    6. {
    7.     //switch render target
    8.     RenderTexture.active = target;
    9.  
    10.     //clear
    11.     GL.Clear(true, true, Color.green);
    12.  
    13.     JustDrawFullScreenQuadAtCurrentRenderTarget(input, mat, passNum);
    14. }
    Code (CSharp):
    1.  
    2. //draw full screenQuad without render target switch
    3. void JustDrawFullScreenQuadAtCurrentRenderTarget(
    4. Texture input, Material mat, int passNum
    5. )
    6. {
    7.     //must set texture before SetPass,SetPass update render state once,
    8.     //then later ignore the material after.
    9.     mat.mainTexture = input;
    10.     mat.SetPass(passNum);
    11.  
    12.     GL.PushMatrix();
    13.  
    14.     GL.LoadOrtho();
    15.  
    16.     //draw full screen quad
    17.     GL.Begin(GL.QUADS);
    18.     GL.TexCoord2(0, 0);
    19.     GL.Vertex3(0.0F, 0.0F, 0);
    20.     GL.TexCoord2(0, 1);
    21.     GL.Vertex3(0.0F, 1.0F, 0);
    22.     GL.TexCoord2(1, 1);
    23.     GL.Vertex3(1.0F, 1.0F, 0);
    24.     GL.TexCoord2(1, 0);
    25.     GL.Vertex3(1.0F, 0.0F, 0);
    26.  
    27.     GL.End();
    28.  
    29.     GL.PopMatrix();
    30. }
    -----------------------------------------------------
    Now my game's custom Graphics.Blit calls will always Clear the render target, it means more extra Clear calls than before, but the "Slow framebuffer load" warnings are finally gone now.

    Still, there is no noticeable performance increase, only the warning is gone.
    maybe I have done something unnecessary, just to remove a warning that didn't even affect performance at all? anyone have seen the same warning? and is it good or bad to remove it this way?
     
    Last edited: Aug 22, 2017
  2. sandm4n

    sandm4n

    Joined:
    Aug 22, 2017
    Posts:
    3
    I can confirm this.
    Tried just doing a simple "cam.targetTexture = renderTexture;" in onPreRender() and then a Graphics.blit(renderTexture, null, material) in onPostRender() yields a fps of around 48-50. After doing the same with the wrapper above yields a fps 58-60. For the original Graphics.blit() I even put in a renderTexture.DiscardContents(); still to no use.

    By using the above wrapper in my bloom shader i easily gain about 10 more fps.

    All this tested on a Samsung Galaxy Note 4 (Exynos)
     
  3. sandm4n

    sandm4n

    Joined:
    Aug 22, 2017
    Posts:
    3
    Update: I fixed my fps drop.

    1. Stopped using GrabPass{}
    2. Switched to mobile unlit shaders instead Standard.

    Now the game runs smooth at 60fps with the inbuilt Graphics.blit() call.