[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Public WebGL] More driver bugs: Getting FRAMEBUFFER_INCOMPLETE for a texture that is not "texture complete" on some cards.

So we were informed of a new issue.

If you bind a texture to a framebuffer and that texture is not "texture complete" then on some (all?) nvidia drivers it wrongly return FRAMEBUFFER_UNSUPPORED.

In other words, 

   // create a 32x32 texture
   tex = gl.createTexture();
   gl.bindTexture(gl.TEXTURE_2D, tex);
   gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 32, 32, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);

   // attach that texture to a framebuffer
   fbo = gl.createFramebuffer();
   gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
   gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);

   // check that it's complete
   var status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);

This code will wrongly fail on some nvidia drivers.

The issue is apparently that bad nvidia drivers require the textures to either have all their mips or be set to use filtering that does not require mips. 

The workaround is to add this line

   // because the default for a texture is gl.NEAREST_MIPMAP_LINEAR
   // we need to set it to something that doesn't need mips.
   gl.texParameteriv(gl.TEXTURE_2D, TEXTURE_MIN_FILTER, gl.LINEAR);

So, for WebGL what if anything should we do?

1) Ignore the issue

You couldn't render with the texture without setting filtering anyway. Mostly like you just have to re-order your initialization to set the texParameter before setting up your FBO instead of after.

2) Try to fix it inside WebGL implementations

I think you'd basically have to track if a texture is being used as an fbo. When it is (either on bindFramebuffer or framebufferTexture2D) you'd have to set its filtering to LINEAR or NEAREST while resetting any previously bound framebuffer texture back to it's original user specified filters. You'd also have to wrap texParameteriv and getTexParameter so that they shadowed the settings since if the texture is currently being used as a render target you can neither set or query its parameters and expect to get the correct result.

3) Change the WebGL spec to have the same requirements so the failure is consistent

You'd again have track which textures are currently being rendered too. Before each draw call you'd have to see if the texture being rendered to meets the conditions above. If not generate GL_INVALID_FRAMEBUFFER_OPERATION on top of GL_FRAMEBUFFER_INCOMPLETE on checkFramebufferStatus.

4) ?