PDA

View Full Version : SSBO specs



Temtaime
04-25-2015, 04:25 AM
Hi all ! I've already asked Pat from specs contacts but seems there's no reply. Then i try to ask my questions at this board.

I have a question about
https://www.opengl.org/registry/specs/ARB/shader_storage_buffer_object.txt

1) In this spec there's an example of usage ssbo; Quote:

// Generate, bind, and specify the data store to hold fragments. The
// NULL pointer in BufferData says that the intial buffer contents are
// undefined. They will be filled in by the fragment shader code.
glGenBuffers(1, &fragmentBuffer);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, fragmentBuffer);
glBufferData(GL_SHADER_STORAGE_BUFFER, NFRAGMENTS*FRAGMENT_SIZE,
NULL, GL_DYNAMIC_DRAW);

At first, a buffer is created, then it is binded with glBindBufferBase function.
But if i read glBindBufferBase spec at https://www.opengl.org/sdk/docs/man/docbook4/xhtml/glBindBufferBase.xml

There's a list of errors:
GL_INVALID_VALUE is generated if buffer does not have an associated data store, or if the size of that store is zero.

Then why example is incorrect?
If i try to bind empty buffer by myself there's no error neither with amd cards nor nvidia cards - so maybe it's an error with function description and it is possible to bind an empty buffer?
But another strange thing is when i try to bind it with glBindBufferRange - then there's an error because of zero size. I think that inconsistency must be solved.
2) Also i wonder about following from example:
// Keep a uniform with the number of fragments that can be recorded in
// the buffer.
uniform uint maxFragmentCount;

Why another variable is used? SSBOs have .length() property. Why example isn't using it?
Also i wonder that there's no info about in what state will be ssbo if buffer is not binded? It has a length of zero or it is UB? And if it is UB, how i can achive an buffer with zero size?

Alfonse Reinheart
04-25-2015, 07:44 AM
Then why example is incorrect?

Because they wrote it wrong. File a bug report (https://www.khronos.org/bugzilla/) on it.


If i try to bind empty buffer by myself there's no error neither with amd cards nor nvidia cards - so maybe it's an error with function description and it is possible to bind an empty buffer?

No. The spec says what behavior ought to happen. The behavior you're seeing in various OpenGL implementations is therefore a driver bug. You should notify AMD and NVIDIA about it.


Also i wonder that there's no info about in what state will be ssbo if buffer is not binded?

*ahem*:


If any active shader storage block is not backed by a sufficiently large buffer object, the results of shader execution are undefined, and may result in GL interruption or termination.

Note that 4.4/robustness relaxed this a bit, to say that out-of-bounds accesses can result in getting zero values.


how i can achive an buffer with zero size?

GL_BUFFER_DATA_SIZE is the minimum size required for any program resource backed by a buffer object. It's queried through the newer Program Interface Query (https://www.opengl.org/wiki/Program_Introspection#Interface_query) API, which is required for SSBOs. The Program Interface Query functionality explicitly states that the minimum size for SSBOs that use an unbounded array will be computed as though the array had one element.

So the minimum size will never be zero. And therefore, you must bind a buffer range big enough for at least one element.


Why another variable is used? SSBOs have .length() property. Why example isn't using it?

Maybe it was because they want to be able to have a zero-length array ;)

Temtaime
04-25-2015, 08:04 AM
Hi Alfonse !
Thanks very much for your reply.
I have last one question.
For example i have binded a buffer with 1 element.
What will be happen if in future i update that buffer with new data having length > 1 ? Is it necessary to me use glBindBufferBase (maybe that instructs opengl about bounds) again or i can skip it ?

Alfonse Reinheart
04-25-2015, 09:14 AM
What will be happen if in future i update that buffer with new data having length > 1 ?

Well, you shouldn't do that. Unless you're using the same size (and usage parameters), you shouldn't be calling glBufferData on the same buffer more than once. And even then, you should just invalidate the buffer (https://www.opengl.org/wiki/Buffer_Object#Invalidation), since you're already using SSBOs and thus have access to 4.3.

There's a reason why GL 4.4 allows you to make buffer storage immutable.


Is it necessary to me use glBindBufferBase (maybe that instructs opengl about bounds) again

Actually... no. The OpenGL spec says:


BindBufferBase binds the entire buffer, even when the size of the buffer is changed after the binding is established. The starting offset is zero, and the amount of data that can be read from or written to the buffer is determined by the size of the bound buffer at the time the binding is used.

Now granted, I would never rely on this. That's exactly the sort of thing that an implementation is likely to fail to handle correctly (due to being esoteric, involving lots of extra state tracking, and people probably aren't exercising that code).

Temtaime
04-25-2015, 02:58 PM
Thanks you Alfonse very much !
I meant that i want to change the size of the buffer and i was wondering is it necessary to rebind it or not. As you answered seems that i can bind it only one time. Okay, thanks !

But now i have another one question. To get .length property work i need only:
1) Create buffer, upload data.
2) Get binding point, bind it.
And now i can use the buffer in shader and .length() will work ? If it suffice, then seems amd driver bug: .length property gives me random value sometimes.

Alfonse Reinheart
04-25-2015, 03:49 PM
Thanks you Alfonse very much !
I meant that i want to change the size of the buffer and i was wondering is it necessary to rebind it or not. As you answered seems that i can bind it only one time. Okay, thanks !

No, what I said was that the spec allows you to do it. As you yourself have seen, implementations don't always follow the specification. Just don't be too surprised if it doesn't work.


But now i have another one question. To get .length property work i need only:
1) Create buffer, upload data.
2) Get binding point, bind it.
And now i can use the buffer in shader and .length() will work ? If it suffice, then seems amd driver bug: .length property gives me random value sometimes.

It's possible. But without seeing your exact code, it'd be difficult to be sure that you didn't make a mistake somewhere (such as the buffer not being of the correct size).