Setting RenderTexture active to retrieve contents is running slow

Hello! I am rendering into a RenderTexture and after doing so I need to set it as the active RenderTexture to read its data into a Texture2D so I can then use ReadBytes. When I do this bind to active I get a large 8-10ms hickup. I tried delaying the bind by a frame to see if it was blocking since the render was not actually complete however I get the same (or worse) performance when setting it active after waiting for a frame.

The render texture is 512x512 in size which I thought might be the issue since it doesn’t match the screen resolution but I get no such hickup when I render into it to begin with.

At this point I am at a bit of a loss as to what the source of the problem is. I have considered writing a DLL which performs the data move natively and which could hopefully avoid the bind to active but have not researched just how optimized I could make it. I do understand I’ll have to do this per platform and per renderer so I’d really like to avoid it.

Finally, I am doing all of this in FixedUpdate. Is there somewhere else I should be doing it that would help avoid the issue?

Thanks in advance and I apologize if this wanders a bit, it is allergy season and I feel a bit off.

  • Loren

FixedUpdate is a physics update, I think - as such, it happens faster than the actual screen refresh rate. So you might be doing this multiple times per drawn frame for no visual benefit.

LateUpdate is called just before rendering, at the frame-rate of the game, might be an idea to use that?

Thanks for the reply Farfarer!

I tried kicking it over to LateUpdate but the delays stayed approximately the same, perhaps a tiny bit faster? That said, when it enters into there it is processing a work queue of GPU tasks for generating terrain meshes so any entry there isn’t wasted per-se but I’d certainly hate to see the game hitch unexpectedly because it did happen to enter multiple times a frame and so the move from Fixed is now permanent :slight_smile:

Are you sure it’s setting active that causes the hitch, and not the ReadPixels operation? Readback from the GPU is generally really slow, and you should avoid doing it if you can.

This Tweet from Aras might help you.

So I think that the profiler only says that setActive takes a lot of time, because it doesn’t return until all other rendering is done.

if you have exactly RenderTexture.SetActive as your bottleneck there are 2 possibilities:
there was smth regarding dx11 (though you should wait for more desktop-oriented guys in that case).
also - on pvr gpus (ios, some androids) and on mali (androids) there were issues with our current impl - if you see it on android what is your unity version? everything should be fixed in 4.2 btw :wink:
EDIT: first of all there were fixes earlier, no need to worry
EDIT2: what aras said is true - though on mobile devices (in cases i described) you simply get cpu hit due to driver issues.
EDIT3:

this is not entirely true - the issue is if you are heavily gpu-bound (esp. on desktops) any driver call might halt execution waiting gpu to finish. But in “usual”/“normal” case RenderTexture.SetActive do not wait for anything

Thanks everyone for the feedback!

As Daniel suggested the ReadPixels was the cause and the profiler was misappropriating the time to SetActive. It is very strange to me that ReadPixels would be as slow as it is for an 80x80 pixel buffer but so it goes. After discussing it with another developer we have decided to just make the building of these composite textures a part of our build process since it will facilitate faster draws, no GPU fetch, no per platform customization (this approach was being used for mobile vs. vertex extrusion for desktop), and no concerns about driver implementation for Mac and Linux.

Thanks again and if I do learn more or find a different solution I’ll be sure to post.