Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: RenderTexture and GL_OUT_OF_MEMORY  (Read 4540 times)

0 Members and 2 Guests are viewing this topic.

eigenbom

  • Full Member
  • ***
  • Posts: 228
    • View Profile
RenderTexture and GL_OUT_OF_MEMORY
« on: June 11, 2015, 02:08:29 am »
Hi! So I'm greedily creating RenderTextures at the maximum texture size, the calls are failing, and then the create(w,h) function returns false. That's all fine, however the error printed is:

"Impossible to create render texture (failed to link the target texture to the framebuffer)".

Running in DEBUG shows more precisely that the problem is actually a GL_OUT_OF_MEMORY error, caused when creating the internal Texture.

I think it'd be nice if the Texture::create function fails and returns false if it can't create the texture because of memory. This would then also let RenderTexture report the true error, that resides with the texture creation.

(In my case I just call RenderTexture::create() with halving sizes until it succeeds, so my system works fine.)

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: RenderTexture and GL_OUT_OF_MEMORY
« Reply #1 on: June 11, 2015, 03:18:20 am »
greedily creating RenderTextures at the maximum texture size
This is the root of the problem.

Your approach of "trial and error" creation might work, but to be honest, it's kind of sloppy. No graphics/game/OpenGL developer would even consider pushing the GL until it returns errors just to find out what it can/can't do. This is simply the wrong approach. GL errors are errors, not warnings or information. They aren't supposed to happen in well-behaved applications and if they do, they should be fixed if the software is to be considered well-written.

The other issue is that the GL_OUT_OF_MEMORY error can be slightly misleading. One might think at first that the error means that GPU memory has been exhausted, since the general assumption is that all SFML OpenGL resources reside in GPU memory. This isn't always true. You have to think of GPU memory just like your system RAM.

Many people might not know, but if your task/process manager reports that you only have 200MiB of RAM left unallocated, you can still open up a program that uses 500MiB of RAM and expect it to work properly. Where does this extra space come from? Something people tend to forget about called a pagefile.

Just like the host system, the GPU also uses virtual memory. You might be able to (depending on implementation) allocate 4GiB of textures even if your GPU only has 2GiB of memory, 2GiB will end up in unpaged memory somewhere in your system RAM. In your case, this is probably already happening, and you are significantly reducing the performance of your application because of this.

Checking the residency of GL textures used to be done in the legacy API using glAreTexturesResident, however that function has been deprecated and removed from the core profile simply because applications should be designed not to have to care about residency in the first place.

The driver often knows better than you do how to handle virtual memory, so if you are getting GL_OUT_OF_MEMORY errors, you know you are doing something really really bad.

What SFML can provide you (and it has already been up for discussion in the past) is a unified/simplified way of querying the hardware for capability data. Remember, this data should only be used as hints. This way you know how much graphics RAM you have available and can estimate how much data you can actually end up fitting in it before it might get paged out. It isn't exactly rocket science if you know the data formats SFML uses, you just need to add a bit of overhead leeway on top of that as well.

TL;DR: You also don't do things like "greedily creating std::vectors at the maximum std::vector size" until std::bad_alloc is thrown. The same applies to graphics memory.
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

eigenbom

  • Full Member
  • ***
  • Posts: 228
    • View Profile
Re: RenderTexture and GL_OUT_OF_MEMORY
« Reply #2 on: June 11, 2015, 05:27:57 am »
Thanks for the info, but that's really beside the point of what my thread was about.

My only concern is just that Texture::create() returns true if it fails to create a texture, despite what the documentation says. You're saying that it's a problem with the caller, and that the caller should know if it will succeed or not.

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: RenderTexture and GL_OUT_OF_MEMORY
« Reply #3 on: June 11, 2015, 10:37:50 am »
What difference would it make if the RenderTexture creation failed at some other point than the one now? That is the nature of OpenGL errors, you can't pin them down to one point. You can cause a situation that would have caused GL_OUT_OF_MEMORY somewhere way before the texture is actually created and the GL could still only complain at the point it does now. I've had times when GL_OUT_OF_MEMORY was triggered even when not even causing any memory allocations (some other bug of mine). Like I said, the best SFML can do is tell you that something went wrong, which is also typical in OpenGL development. The accuracy of the error messages isn't something SFML has any influence over. If you want to track down the "bug" in your code faster then you will either end up just running SFML in debug and watching the console and trying to make sense of what it tells you, or just use an OpenGL debugger which would end up telling you the exact same thing anyway (without the file name and line number). Debug builds exist for a reason... debugging code.

Errors are bad. If RenderTexture::create() returns false, it is bad. You shouldn't care why it returns false, just that you need to stop it from returning false. And if you already have a gut feeling why it might return false (and even expect it to do so at some point) then there is even less purpose behind a meaningful error message anyway.
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: RenderTexture and GL_OUT_OF_MEMORY
« Reply #4 on: June 11, 2015, 09:10:29 pm »
Eigenbom, just for clarification on your question, I think it would be wise to confirm that you're saying that RenderTexture returns false on failure but Texture returns true on failure. If that's not what you were stating, your question is extremely misleading.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

eigenbom

  • Full Member
  • ***
  • Posts: 228
    • View Profile
Re: RenderTexture and GL_OUT_OF_MEMORY
« Reply #5 on: June 12, 2015, 02:31:23 am »
Eigenbom, just for clarification on your question, I think it would be wise to confirm that you're saying that RenderTexture returns false on failure but Texture returns true on failure. If that's not what you were stating, your question is extremely misleading.

Yep, that's what I'm saying. RenderTexture thinks that its internal Texture->create() succeeded, when actually OpenGL had already reported a GL_OUT_OF_MEMORY error. It would be nice if SFML was a bit more robust in this area .. sure you'll never have 100% valid error checking because memory errors can be weird or reported late etc, but you can start to check some of them after certain allocations. Checking for GL_OUT_OF_MEMORY after glTexImage2D seems like a reasonable candidate.

Unfortunately I've got to get back work now, the Moonman beckons.

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: RenderTexture and GL_OUT_OF_MEMORY
« Reply #6 on: June 12, 2015, 03:49:05 am »
Like I said above, you can't check for GL_OUT_OF_MEMORY and know exactly what caused it. Almost everything in OpenGL is asynchronous. Something you did 3 frames ago might cause the GL_OUT_OF_MEMORY you are getting now. If you want to talk about robustness, then consider what would happen if something unrelated to sf::Texture caused the error to be raised in one of it's GL functions. The texture creation and allocation would have succeeded, but you still return false because something that happened 2 frames ago went bad? That sounds even worse than it is now, if you can even consider the current situation as bad.

If you still don't get it: There is no clean way to recover from OpenGL errors, short of destroying all contexts and recreating them again. If they happen, you need to fix what you think is the most likely cause. The cause might not even be related to the error in any way, that's just how OpenGL works. If one adheres to good practice, any errors resulting from programmer error should be easy to track down anyway, and exhausting memory just because you can is not good practice. I'm still curious as to why you even need to do this...

Go ahead and search the internet for GL_OUT_OF_MEMORY. You will find that it gets triggered in the most unusual situations, mostly as a result of some unrelated programmer error. If it were up to me, I would rename it to GL_UNSPECIFIC_ERROR, since that wouldn't mislead people such as yourself into thinking it is caused solely by allocation functions.
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).