4
$\begingroup$

In my program, I use a additional frame buffer to render something into a texture(only a glClear), which I will reference it's handle in next draw command. And draw the texture back to the default frame buffer. My program almost run like this:

frame buffer create and attached by a GL_TEXTURE_2D texture and other setup
glGetTextureHandle
glMakeHandleResident

bind this frame buffer
glclear(1.0f, 0.0f, 0.0f, 1.0f)

glBindFramebuffer to 0(back to default frame buffer)
ShaderUse//nothing but return texture's color
glUniformHandleui64(location, textureHandle)//witch is the texture above
//if I use normal bind texture, the result will be correct
glDraw*//just draw a quad

Here I got a strange issue, The 2nd glDraw cmd gives an empty result(Back Buffer is an black image). And I also checked the first frame buffer's render texture witch is a pure red image, and it's a correct result. And my GPU is AMD R7 200. But when I change bindless texture to normal bind texture style, and everything is ok finally.Also I checked in NV GPU-GTX650 with same program, and the result is also ok.

I am sure there is no opengl error occurred in my program, and I also checked GL_ARB_bindless_texture extension is supported by my devices.

So I wonder, am I missing some memory sync or coherent?

I also looked up to the document and I found this:

(4) Can texture or sampler objects be modified while they are used by a texture or image handle?

  RESOLVED:  No.  If such changes were permitted, each modification to the
  texture object would require potential synchronization with one or more
  texture/image handles extracted from the texture.  This seems like a lot
  of bookkeeping with little benefit.  One exception to this rule is that
  individual texels of such texture objects may still be updated with APIs
  such as TexSubImage* and by rendering to a framebuffer object to which
  the texture is attached.

One exception to this rule is that individual texels of such texture objects may still be updated with APIs such as TexSubImage* and by rendering to a framebuffer object to which the texture is attached.

Does glClear belong to this exception?

$\endgroup$
1
$\begingroup$

This is clearly a bug in AMD's driver, though it's a very understandable one.

What is probably happening is that the driver does not correctly detect that there is a dependency between the framebuffer operation and the use of the texture. It's easy for an API to tell that you've bound a texture that was the subject of an outstanding render target command, since the API sees exactly what texture you're going to use. It can simply keep track of the texture objects recently used in an FBO, and if it sees you render with one of them bound, it issues whatever dependencies are needed to ensure that the operation is complete before the rendering operation.

It's much harder when you're not binding the texture; you're just passing an arbitrary number to the shader. The API has no idea if that number represents a render target.

To verify that this is the problem, insert a glFinish() between the clear command and the draw command that uses the texture. Odds are good that it will go away (or at least be partially mitigated). A glTextureBarrier() call might also fix it. If you're getting the texture handle after attaching the texture to the FBO, you might also want to get the handle first. Just in case that shakes something loose.

Note that you shouldn't have to do any of these; the specification requires that things work exactly as you expect.

What AMDs driver needs to do is to realize that you're using bindless texturing and emit the appropriate dependency operations when you change framebuffer render targets. That is, it has to assume that any glBindFramebuffer or any calls that modify the FBO that's currently bound will result in any subsequent rendering command reading from previously written textures. Therefore, it must issue a synchronization at the first rendering command that involves a bindless texture operation (if the texture used by the FBO is made resident).

Either that, or it somehow has to figure out which arbitrary integers represent which textures. This is very difficult, since you can pass those handles in a variety of ways. UBOs, for example; you don't want implementations combing through images.

$\endgroup$
  • $\begingroup$ I have tried glFinish or glTextureBarrier, but still can't fix my problem.I think I should post this into AMD's community. Anyway, Thanks.@Nicol Bolas $\endgroup$ – Francis Jul 8 '17 at 1:15

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.