4
$\begingroup$

Problem. I have inherited a large C++ 3D graphics codebase (with some shader code). The program runs for about 1-5 minutes before crashing.

Problem Data. Using system tools, one can see a sharp rise in VRAM memory usage after the program launches, which eclipses into a crash. The same is true for GTT memory usage also (although the spike isn't quite as dramatic as with the VRAM).

Questions.

  1. Does this (probably) mean that there is a memory leak in OpenGL shader code somewhere (as opposed to a leak in regular C++ code)?

  2. Are there well-known tools for tracking down vram/gtt memory leaks (similar to the way that valgrind can be used to track down system memory usage)?

$\endgroup$
3
$\begingroup$
  1. Probably not. Most OpenGL resources (framebuffers, vertex buffer objects, textures &c.) are controlled by host code (i.e. your C++ code), but take up GPU memory. OpenGL doesn't make it very easy to manage these resources, so it's most likely that they're being created but not deleted from your C++ code. For example, it might create a new VBO per frame but never delete the old VBOs.

  2. I've never used it for this purpose, but if you're on Windows I'd suggest RenderDoc as your first stop. It's not specifically designed for debugging source - it intercepts GL and DX calls so you can see how the application is using the library even if you don't have the source - so it won't point you to the offending line of code, but it does show you what resources are being created and when, so it should at least tell you what is being leaked and how often. It might even be that this is enough information is enough for you to guess the rest, or that the easiest way to continue after this is to do something by hand (e.g. printing __FILE__ and __LINE__ every time such a resource is created).

Sorry this is a bit of a half-answer but it's too big for a comment. I hope it gives you a good starting point at least.

$\endgroup$
  • 1
    $\begingroup$ With you can also insert debug messages into the opengl stream with push/pop debug group to get some context. The opengl objects created can also be named with glObjectLabel. $\endgroup$ – ratchet freak Mar 21 '17 at 13:07
3
$\begingroup$

Assuming your code has several locations that can allocate/release GPU memory, but you don't know which one leaks. Maybe you can try to add a GPU memory monitor to that code.

When GPU memory is allocated in code, insert the buffer handle that was returned, the buffer size, the function/file name (or even better, stack trace) in a globally defined array. When GPU memory is released, remove the handle of the buffer that was released from that array. Run the application a while and exit before it crashes. Output the contents of the array before leaving. It shows information about the GPU memory that was not released. You might see some patterns leading you to understand how to fix the "leak".

$\endgroup$
  • 1
    $\begingroup$ The problem is that there are hundreds of OpenGL calls in my codebase. Is there a list of OpenGL calls which have as side effect the allocation/deallocation of memory? $\endgroup$ – George Mar 24 '17 at 20:18
  • 1
    $\begingroup$ Regarding my prior comment, I'm assuming glBindBuffer is the key function call to look out for? $\endgroup$ – George Mar 24 '17 at 20:23
  • 1
    $\begingroup$ It depends on which flavor of OpenGL your program uses, I would suggest to monitor glGenBuffers / glDeleteBuffers, (see the OpenGL wiki's Buffer Object page ). Also glCreateProgram / glDeleteProgram, glGenSamplers / glDeleteSamplers, etc $\endgroup$ – wip Mar 25 '17 at 13:26
  • $\begingroup$ In my code, there are 20 calls to glGenBuffers, and only one call to glDeleteBuffers. Does that automatically identify a problem, in that these calls should be 1 for 1 with each other? $\endgroup$ – George Mar 25 '17 at 13:28
  • 1
    $\begingroup$ A good-practice for multi-platform graphics application (rendering engines, etc) is to wrap the graphics API specific functions under a generic layer (for example, your program has a structure/class MyAppBuffer from which are derived MyAppOpenGLBuffer, MyAppDirectXBuffer, etc. It has the benefit of having all the graphics API functions in a single place, making it easier to monitor. You could try to refactor your code in a similar way. $\endgroup$ – wip Mar 25 '17 at 13:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.