PDA

View Full Version : Resizing a TBO, problem with AMD drivers?



fred_em
06-18-2011, 01:28 AM
Hi,

Am I allowed to resize a TBO after the fact? That is, am I allowed to provide a buffer (with glBufferData and the DYNAMIC_DRAW flag) which size is different than the previous one?

With my nvidia setup, things work correctly when I do it.

With my AMD setup, buffer uploading with glBufferData works correctly. However, the data I try to read with texelFetch() in GLSL at a given location seems to be wrong, if this location is beyond the size of the original buffer, .

Thanks,
Fred

aqnuep
06-20-2011, 03:38 AM
In case you use glBufferData you don't just respecify the buffer size or attributes, you redefine the whole buffer. That means the previous data of the buffer object is no longer accessible, think of glBufferData as a command for purging the old buffer and creating a completely new one.

The fact that in case of NVIDIA the earlier data is still there after a call to glBufferData is just lucky as the specification doesn't guarantee it, actually after calling glBufferData with a data parameter of NULL the data in the buffer object is undefined.

The point is, you should not rely on the presence of the earlier data after calling glBufferData, it is not a reallocation method, at least not one that preserves data.

fred_em
06-20-2011, 04:14 AM
Hi aqnuep and thanks for your reply.

Here is what happens chronologically speaking:

Initialization at application startup
1. glBufferData(non-NULL pointer, 'size1' bytes)

MainLoop:
1. glBufferData(non-NULL pointer, 'size2' bytes)
2. draw call
3. shaders are being called and texelFetch is executed against the buffer data
GOTO MainLoop

On my AMD setup, if size2 > size1, all data after size1 will be bogus. But all data up to size1 IS fine: this IS the new data, but it is trimmed to 'size1' bytes, that's all.

Not sure if I understand you correctly.

Alfonse Reinheart
06-20-2011, 04:32 AM
What happens if you unbind the buffer object from the texture object, then do the glBufferData, then bind it again? If it works, it would be a good workaround for the bug.

Also, if you're going to reallocate a buffer object, it's probably best to just create a new object name and delete the old one. The vast majority of all uses of glBufferData with a previously allocated buffer object will allocate a buffer of exactly the same size.

aqnuep
06-20-2011, 07:11 AM
Sorry, I misunderstood your question, I thought you would like to preserve the previous data of the buffer but if you use glBufferData with non-NULL passed as the data argument then there shouldn't be an issue, except the one that Alfonse mentioned, so you should rebind the buffer object if you don't do it that yet, otherwise there is no guarantee that the new data is used.

Also agree with Alfonse that reusing a buffer object but replace the memory buffer behind it, is simply not a nice thing to do, better off with using a new object name.

fred_em
06-20-2011, 09:00 AM
What happens if you unbind the buffer object from the texture object, then do the glBufferData, then bind it again? If it works, it would be a good workaround for the bug.
Right. Instead of:


glBindBuffer(GL_TEXTURE_BUFFER, bufferId);
glBufferData(GL_TEXTURE_BUFFER, textureDataSize, lpBuffer, GL_DYNAMIC_DRAW);
I tried:


glBindBuffer(GL_TEXTURE_BUFFER, bufferId);

// Temporarily unbind the buffer (note: I hope I do this correctly!)
GLint glint;
glGetIntegerv(GL_TEXTURE_BUFFER_DATA_STORE_BINDING , &glint); // retrieve the currently bound buffer
glTexBufferEXT(GL_TEXTURE_BUFFER_EXT, GL_RGBA32I, 0);

// Send the data
glBufferData(GL_TEXTURE_BUFFER, textureDataSize, lpBuffer, GL_DYNAMIC_DRAW);

// Re-bind the buffer
glTexBufferEXT(GL_TEXTURE_BUFFER_EXT, GL_RGBA32I, glint);
The result I get is different, but it doesn't work either. It seems some part of the buffer is still missing.

Alfonse Reinheart
06-20-2011, 10:07 AM
So what happens if you just create another buffer object?

fred_em
06-21-2011, 02:35 AM
So what happens if you just create another buffer object?
This is a modification that is slightly more difficult to do in my code (the routine I am currently in is burried deep inside my application). I will do it a bit later this week and report back.


so you should rebind the buffer object if you don't do it that yet, otherwise there is no guarantee that the new data is used
Do I *have* to rebind after the call to glBufferData? Is this required as per the OpenGL spec in order to inform the driver that new data is available (and otherwise, texelFetch will continue to point to the old data)? Weird. Are you sure of this?