When is VRAM freed?

Greetings,

I have a situation where the VRAM usage in a program constantly goes up with little dents although buffers and texturess are regularly deleted using glDeleteBuffers and glDeleteTextures.

Can you tell me if the PowerVR Driver frees memory immediately at glDeleteBuffers or if it keeps caches or similar?

Hi desperado,

Many thanks for your message. Could you please specify platform, DDK and operating system?

We’ll look into it and come back to you with an answer shortly.

Best regards,
Alejandro

PowerVR Rogue GX6250
Yocto Linux
DDK 1.10@5187610

As far as I know, many drivers use reference counting on OpenGL objects and only delete the data when the last reference is gone. Is there a way to see reference counts in opengl objects using tracing software etc. ?

Hi desperado,

Many thanks for the information.

We will also look into possible ways to see reference counts for OpenGL, we will come back to you with an answer soon.

Best regards,
Alejandro

Hi Desperado,

Apologies for the delay, I’ve looked into the specification(found here) for GL ES. Navigate to section 5.1.3 for the details on “Deleted Object and Object Name Lifetimes” for more information. I have also spoken to the driver team as well, and there is a list of things to consider.

First and foremost, the DDK does not keep caches of memory, it is freed immediately when it is no longer in use. However there is a reason that you might not immediately see the VRam get returned to the OS, Sometimes the memory is managed, meaning if the driver is expecting to reallocate that memory for something else, it will maintain ownership of the memory, because it is faster to hold onto that memory and reallocate, rather than doing a deallocate then reallocate cycle.

Further, I wanted to address something from another post about how you are gathering Vram usage statistics. inside of /sys/kernel/debug/pvr/driver_stats where you are gathering statistics per PID. These statistics are generated by your vendors implementation of the DDK and can differ from ours, further memory that has been freed, but not released back to the OS might not be reflected in these driver statistics.

The counter MemoryUsageTotal does not correspond to a counter in our base DDK. Most likely MemoryUsageTotal is likely not the current Vram usage, instead it is likely a meta counter representing the driver’s total memory footprint, or some other form of sum; for example it could be a sum of all memory used so far, exactly what it’s purpose is, we cannot say for certain. If you wanted to use the current method for gathering Vram usage, then the counter MemoryUsageAllocGPUMemUMA most likely will give you a better estimate of the current Vram usage, but it will not give you an exact value.

If you are still seeing a memory leak, then this could be a problem with how frequently the statistics in that file are updated, or the buffer might not be being released because it is marked as still in use.

When you call glDeleteBuffers or glDeleteTextures it is not guarenteed that the memory will be released right away, just that the name (that’s the GLuint ID) is immediately invalidated. The underlying object is marked for delete when it is no longer in use, you can see this in the GL ES specification linked above. A buffer or texture is considered in use when it is still referenced in a container object (ie a texture contained in a framebuffer, or a buffer in a VAO), or if that resource is currently bound to any context. Note that when you make a call to a delete function, the object will only be unbound from currently active contexts. So it is possible that you are not releasing all the references to the object that you are trying to delete, and thus the object stays “in use”.

Finally there is one known possibly leaking bug that we have encountered before in DDK 1.10, that some internal memory is being incremented. This occurs when an application repeatedly uses glBindFramebuffer → glClear and then does not use that framebuffer texture. There is a chance your application can be effected by this bug.

If you exhaust all these options than you can send us a ticket with the application binary, and using one of our internal tools we can attempt to track the VRam usage for you.

All the best,
Lawrence

2 Likes

Hello, thanks for your answer I shall study that info. One question in advance nevertheless:

I measure GPU memory consumption by computing the sum of the binary sizes all allocated OpenGL Objects VBOs, Textures, Renderbuffers, Shaders etc. . When I do so, I get a divergence between this sum and the MemoryUsageAllocGPUMemUMA parameter you mentioned which can be 30% and more. Is there another source of heavy VRAM usage in the DDK that is not an OpenGL object?

Does any of your tools allow showing how much VRAM is allocated by which kind of resource? PVRTunes maybe?

Regarding the glBindFramebuffer → glClear bug is this documented somewhere? What do you mean by “not used”? Not bound somewhere or no drawcall on it or what? Can you narrow down in which DDK versions it appears?

I cannot give you the binary but a PVR Trace file if this is enough (I cannot use PVRCarbon because it doesn’t give me an output for some reason I already posted a ticket for that)

Hi Desperado,

Apologies for this, the counters that will represent the GPU memory usage are: MemoryUsageAllocPTMemoryUMA + MemoryUsageAllocGPUMemUMA That will most likely explain your 30% difference.

The feature that allows viewing the Vram usage, is reserved for PVRTuneComplete, which is released to customers under NDA

Regarding “not used”, since the series of events is binding to the framebuffer and then clearing it, the only thing left is not rendering to it. I don’t believe this bug has much documentation as the effect is rather small and also quite niche. As far as we are aware, the bug only effects the 1.10 release branch since the fix wasn’t backported.

1 Like

Thank you.

Can you tell me btw if shader programs have a permanent VRAM footprint during their lifetime and how large that is? I have a scenario with about 150 shaders.

Oh, and knowing the VRAM footprint of an FBO without attachments would also be nice.

Ok, I have PVRTuneComplete now. Can you tell me how to display the VRAM consumption with it? Is it possible to show which kind of object (buffer, renderbuffer, texture etc.) uses how much vram?

Regards

Unfortunately it is impossible to say how large the footprint of a shader will be, since the number of machine code instructions that make up the shader (and thus it’s size in memory) will vary entirely on the shader. PVRShaderEditor will show you the shader as a list of instructions, and you could use that to estimate the size. Although, I imagine it will be quite small.

Once again the implementation can be vendor specific, but the shader source will need to be switched out multiple times per frame, since this process needs to be fast, the GPU will store the shader source code for the lifetime of the program, since a shader program could be executed any frame until it is destroyed.

An FBO is just a container object, the best way I could describe it would be similar to the size of an empty vector; which would be very small.

All the best,
Lawrence

And the PVRTuneComplete question?

Apologies, I had not refreshed the page while I was writing my reply and missed the tune complete question. Using PVRTuneComplete, before starting your recording, you need to enable overriding PVRPerfServerCMD settings, then enable the Host info tag. After that, in the recording you will find a host info section, This will contain a counter called either "Host Graphics Memory Usage" or "Host TotalMemoryUsage". This will be the counter you’re looking for.

Regarding PVRTuneComplete, I’ve sent a you a quick DM to check something.

All the best,
Lawrence.

I started the server with --HostDeviceInfo=1 and --HostInfo=1 then recorded with PVRTunesComplete. I see a host km section in the center but no host info.

Regarding the other thing, I have to talk to our IT.

When you say shader source, you mean the bytecode of the shaders? Will shaders cache anything else in VRAM?