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

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).


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:

//replace every Graphics.Blit()
void GraphicsBlitWrapper(
Texture input, RenderTexture target, Material mat, int passNum
)
{
    //switch render target
    RenderTexture.active = target;

    //clear
    GL.Clear(true, true, Color.green);
 
    JustDrawFullScreenQuadAtCurrentRenderTarget(input, mat, passNum);
}
//draw full screenQuad without render target switch
void JustDrawFullScreenQuadAtCurrentRenderTarget(
Texture input, Material mat, int passNum
)
{
    //must set texture before SetPass,SetPass update render state once,
    //then later ignore the material after.
    mat.mainTexture = input;
    mat.SetPass(passNum);

    GL.PushMatrix();

    GL.LoadOrtho();

    //draw full screen quad
    GL.Begin(GL.QUADS);
    GL.TexCoord2(0, 0);
    GL.Vertex3(0.0F, 0.0F, 0);
    GL.TexCoord2(0, 1);
    GL.Vertex3(0.0F, 1.0F, 0);
    GL.TexCoord2(1, 1);
    GL.Vertex3(1.0F, 1.0F, 0);
    GL.TexCoord2(1, 0);
    GL.Vertex3(1.0F, 0.0F, 0);

    GL.End();

    GL.PopMatrix();
}

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?

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)

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.