Is there a method to create an OpenGL object that always stays in GPU memory (texture or buffer)? OpenGL can unload objects to RAM memory. But my purpose is to fill GPU memory. For example: I have 1 GB GPU memory and my app needs to fill 512 MB of GPU memory.
Is there a method to create OpenGL object, what stay in GPU memory always
No.
But my purpose is fill GPU memory.
In other words you try to Denial-of-Service the GPU. Doesn't work. The OS/driver will decide to make space for other stuff, that needs to be drawn there and now. Many OSs these days rely on the GPUs 3D acceleration to draw their userinterfaces. The GPU always must be responsive.
Also modern GPUs have MMUs and can fetch only subsets of data in a larger object.
Related
My question is: If you have consumed all the available video ram, and attempt to create a new texture (SDL), will normal ram be used automatically instead of video ram? Or, will you have to attempt to use a surface (SDL), which uses normal ram? In the event you are unable to free the video ram for use for whatever reason.
Driver dependent, software renderer uses system memory obviously. GL based implementations use video memory, what happens when OpenGL runs out of memory is up to the driver, most likely it will end up in system memory.
Technically, you have no guarantee that there even is such a thing as video memory, OpenGL is just supposed to store it in the "most practical location", definition of that depends on the hardware (think hybrid memory, there is no difference in that case).
TL;DR; Yes, textures will be stored where there is space for them.
I can use glTexImage2D or glBufferData to send some data to the gpu memory. Let's assume that I request driver to send more data to the gpu but the gpu memory is already full. I probably get GL_OUT_OF_MEMORY. What might happen with a rendering thread ? What are possible scenarios ? Is it possible that a rendering thread will be terminated ?
It depends on the actual OpenGL implementation. But the most likely scenario is, that you'll just encounter a serious performance drop, but things will just keep working.
OpenGL uses an abstract memory model, for which actual implementation threat the GPU's own memory as a cache. In fact for most OpenGL implementation when you load texture data it doesn't even go directly to the GPU at first. Only when it's actually required for rendering it gets loaded into the GPU RAM. If there are more textures in use than fit into GPU RAM, textures are swapped in and out from GPU RAM as needed to complete the rendering.
Older GPU generations required for a texture to completely fit into their RAM. The GPUs that came out after 2012 actually can access texture subsets from host memory as required thereby lifting that limit. In fact you're sooner running into maximum texture dimension limits, rather than memory limits (BT;DT).
Of course other, less well developed OpenGL implementations may bail out with an out of memory error. But at least for AMD and NVidia that's not an issue.
I'm making a 2D game with OpenGL. Something I'm concerned with is texture memory consumption. 2D games use a few orders of magnitude more texture memory than 3D games, most of that coming from animation frames and backgrounds.
Obviously there's a limit to how much texture memory a program can allocate, but what determines that limit? Does the limit come from available general memory to the program, or is it limited by how much video memory is available on the GPU? Can it use swap space at all? What happens when video memory is exhausted?
OpenGL's memory model is very abstract. Up to version including 2.1 there were two kinds of memory fast "server" memory and slow "client" memory. But there are no limits that could be queried in any way. When a OpenGL implementation runs out of "server" (=GPU) memory it may start swapping or just report "out of memory" errors.
OpenGL-3 did away (mostly, OpenGL-4 finished that job) with the two different kinds of memory. There's just "memory" and the limits are quite arbitrary and depend on the OpenGL implementation (= GPU + driver) the program is running on. All OpenGL implementations are perfectly capable of swapping out textures not used in a while. So the only situation where you would run into a out of memory situation would be the attempt to create a very large texture. The more recent GPUs are in fact capable of swapping in and out parts of textures on a as-needed base. Things will get slow, but keep working.
Obviously there's a limit to how much texture memory a program can allocate, but what determines that limit?
The details of the OpenGL implementation of the system and depending on that the amount of memory installed in that system.
I am working on a linux-based c++ OpenGL application, utilizing the Nvidia 290.10 64bit drivers. I am trying to reduce its memory footprint as it makes use of quite a lot of live data.
I've been using valgrind/massif to analyze heap usage, and while it helped me optimize various things, by now the largest chunk of heap memory used is allocated by libGL. No matter how I set the threshold, massif doesn't let me see in detail where those allocations come from, just that it's libGL. At peak times, I see about 250MB allocated by libGL (out of 900MB total heap usage). I hold a similar amount of memory on the graphics card, as VBOs and Textures (mostly one big 4096*4096 texture).
So it appears as if a similar amount of memory as what I upload to GPU memory is allocated on the heap by libGL. The libGL allocations also peak when the volume of VBOs peaks. Is that normal? I thought one of the benefits of having a lot of GPU memory is that it keeps the RAM free?
What you experience is perfectly normal, because a OpenGL implementation must keep a copy of the data in system memory for various reasons.
In OpenGL there's no exclusive access to the GPU, so depending on its use, it may become neccessary to swap out data (or just release some objects from GPU memory). Also GPUs may crash and drivers then just silently reset them without the user noticing. This too requires a full copy of all the buffer data.
And don't forget that there's a major difference between address space allocation (the value reported by Valgrind) and actual memory utilization.
I am working on a project that uses a combination of OpenGL drawing techniques as well as CUDA to perform analysis. I would like to use CUDA to generate a renderbuffer and then perform analysis on it with OpenGL. Because of the number of buffers, I need for the memory to be free from CUDA after the renderbuffer is complete but for the buffer to be available for OpenGL still.
More specifically, I create the buffers with
glGenRenderbuffersEXT
glBindRenderbufferEXT
glRenderbuferStorageEXT
I then register them in CUDA with cudaGraphicsGLRegisterImage, which uses memory from CUDA. However, when I go to unregister the renderbuffers with cudaGraphicsUnregisterResource the memory is not freed. I do not want to destroy the buffer with glDeleteBuffers because I still need them for computation but also need to use CUDA to work on other buffers. Is there some other CUDA call I can perform to free this memory without destroying the buffer?
You say, cudaGraphicsRegisterImage "uses memory from CUDA," but have you measured how much? Registering the buffer with CUDA does just that - it just notifies the OpenGL driver that CUDA also wants to see the buffer. The memory cost should be very modest.
I think you should do the reverse. Create the frame buffer in cuda and register them in OpenGL.
The memory between opengl and CUDA is the same, changes only the owner (cuda driver or opengl driver).
Another ,slow, solution would be to download the memory into RAM and do the processing step by step
switching between cuda and opengl.
Third solution is to buy a card with more memory.