PDA

View Full Version : glIsTextureComplete



skynet
08-21-2010, 04:50 PM
Yesterday I was chasing a bug were I could not get to see a certain texture. I just got black.
The texture was created correctly (non-mipmapped filtering). Afterwards the texture got changed every frame by glCopyTexSubImage2D(). Finally, a certain shader would use the shader to implement some "heat haze" effect.
But instead, I just got a black output and no GL error.

After hours of debugging I found out that another code part set the filtering to a mipmapped filter. What happened? The texture got "incomplete" (because I just provided level 0) and sampling the texture just returned black.

Unfortunately, there is no simple call to GL that would tell me if a texture is considered complete or not :-(

ARB_debug_output did not warn me, either.

I suggest a new function that can determine the completeness of a texture:
GLenum status=glIsTextureComplete(GLenum target).

Sampler objects must be considered separately. Their ability to successfully sample a texture depends on their own state _and_ the state of the texture that is currently bound to the same texture unit.
GLenum status=glIsSamplerComplete(GLuint sampler).

Both functions would be a useful debugging tool. This would also help beginners who regularly wonder why their textures don't work as expected.

Chris Lux
08-23-2010, 01:57 AM
i would say that ARB_debug_output currently is not reporting every problem. my tests on nvidias drivers only reported the errors that glGetError() also reports.

i think we have to wait until the support for ARB_debug_output gets more complete... and warnings get generated in cases where incomplete textures are used.

Groovounet
08-23-2010, 03:44 AM
Agreed with you Chris! This is another thing that debug output should be able to handle by itself.

♥ ARB_debug_output ♥

skynet
08-23-2010, 06:52 AM
and warnings get generated in cases where incomplete textures are used.

How would such a message look like? Accessing an incomplete texture can happen while rendering (glDrawElements etc., even conditional in a shader!), while attaching texture levels to FBOs or while copying images. And I certainly did not cover all cases yet.
So, its quite "fuzzy" when/if/how I get a warning on texture completeness.

I'd like to write code like that:


assert(glIsTextureComplete(GL_TEXTURE_2D)==GL_TEXT URE_COMPLETE); //assuming the texture should be ok now


Just like I already do for FBOs at some "strategic" points in my code.

PS: still, debug output should give me a detailed message, _why_ a texture is not complete :-)

Alfonse Reinheart
08-23-2010, 03:09 PM
So, its quite "fuzzy" when/if/how I get a warning on texture completeness.

No it isn't. All it has to say is what texture is incomplete when you attempt to use it and why it is incomplete. OpenGL is already required to give a GL error whenever you attempt to use one, so using debug output to beef up the error message is entirely appropriate.

skynet
08-23-2010, 03:55 PM
OpenGL is already required to give a GL error whenever you attempt to use one

Which error would that be? All the specs say is, when a texture or sampler is considered "not complete" and that accessing such a texture is either undefined or results in vec4(0,0,0,0).
And that is the whole point of my request. You'll never know that a texture is incomplete. You just get weird rendering, but no GL error.

The rules for texture completeness are described in section 3.8.14 of the GL4.1 specs. If an implementation needs to analyse the state of the texture according to these rules at some point, why not expose this check and let the user ask for the completeness state as well? This is in no way different to how glCheckFramebufferStatus() works.

arekkusu
08-30-2010, 10:35 AM
Isn't "glIsTextureComplete()" entirely implementable in user code, using glGetTexLevelParameter and iterating over all faces/levels? You'll need to switch on the target, and apply the appropriate completeness rules.

Alfonse Reinheart
08-30-2010, 10:39 AM
Isn't "glIsTextureComplete()" entirely implementable in user code, using glGetTexLevelParameter and iterating over all faces/levels?

By that logic, so is glFramebufferStatus (except for GL_UNSUPPORTED). That doesn't mean it's a good idea.

kRogue
08-30-2010, 11:48 AM
GLenum status=glIsSamplerComplete(GLuint sampler).

Likely you'd really want: glIsSamplerComplete(GLuint sampler, GLenum texture_target), where texture_target is one of GL_TEXTURE_2D, GL_TEXTURE_1D, etc...

Though a potentially better thing is this, but definitely a different name:

GLBoolean glAllTextureUnitsHappy(void)

which returns true if all texture units won't give undefined results on the currently active GLSL program (or pipeline). If there is an issue (like mipmap jazz) then something to get the message:

glGetAllTextureUnitsHappyMessage(args)

the usage being the same as glValidateProgram and glGetProgramInfoLog.

Just a thought though.

Dan Bartlett
08-30-2010, 02:38 PM
If they were to be added, then it maybe better to use glCheckXXXXXStatus + glCheckNamedXXXXXStatus names (see http://www.opengl.org/registry/specs/EXT/direct_state_access.txt for glCheckNamedFramebufferStatusEXT precedent)


GLenum glCheckFramebufferStatus(GLenum target);
GLenum glCheckNamedFramebufferStatusEXT(GLuint framebuffer, GLenum target);

// possible functions?
GLenum glCheckTextureStatus(GLenum target);
GLenum glCheckNamedTextureStatus(GLuint texture, GLenum target);
// or include texture unit too in these?
//GLenum glCheckTextureStatus(GLuint unit, GLenum target);
//GLenum glCheckNamedTextureStatus(GLuint texture, GLuint unit, GLenum target);

GLenum glCheckSamplerStatus(GLuint unit);
GLenum glCheckNamedSamplerStatus(GLuint sampler, GLuint unit);



GLenum status = glCheckFrameBufferStatus(GL_FRAMEBUFFER);
GLenum status = glCheckNamedFrameBufferStatusEXT(fboID, GL_FRAMEBUFFER);

glActiveTexture(GL_TEXTURE0);
GLenum status = glCheckTextureStatus(GL_TEXTURE_2D);
GLenum status = glCheckNamedTextureStatus(textureID, GL_TEXTURE_2D);
//GLenum status = glCheckTextureStatus(0, GL_TEXTURE_2D);
//GLenum status = glCheckNamedTextureStatus(textureID, 0, GL_TEXTURE_2D);

GLenum status = glCheckSamplerStatus(0);
GLenum status = glCheckNamedSamplerStatus(samplerID, 0);

skynet
08-30-2010, 03:29 PM
Isn't "glIsTextureComplete()" entirely implementable in user code, using glGetTexLevelParameter and iterating over all faces/levels? You'll need to switch on the target, and apply the appropriate completeness rules.
The texture completeness rules are really extensive and include all kinds of things you probably never used or even heard of (like GL_TEXTURE_MIN/MAX/BASE_LEVEL) and special rules for certain texture targets (think of cube maps, rectangle textures, texture buffer objects and so on). Also, these rules might get changed or extended by new texture targets or other extensions. I'd really appreciate not to have to implement that all by myself ;-)

If they were to be added, then it maybe better to use glCheckXXXXXStatus + glCheckNamedXXXXXStatus names
Yeah, this would fit into established language.
I don't know how important the "target" parameter to texture selection really is today. AFAIR, in former days (when glEnable(texture_target) had to be used) you could bind multiple textures to the same texture unit... each at a different target(?). Don't know if this still matters today... probably yes in compatibility contexts...