ARB_Superbuffers - all the gory details

It turns out ATI have released their presentations/whitepapers from SIGGRAPH 2003 at their developer site. Among them is a rundown of the upcoming superbuffers/überbuffers proposal. Take a look over here . Interesting…

Some good stuff. Some bad stuff.

Why is the binding of a memory object syntax so different from VBO syntax? The entry points already exist. It’d be nice if both of them worked the same way.

nice nice…

still waiting till its available from the arb…

ugly.

Originally posted by Korval:
Why is the binding of a memory object syntax so different from VBO syntax? The entry points already exist. It’d be nice if both of them worked the same way.
Same feeling. Now, when VBO has been included into core just a while ago, it’s kind of schizofrenia…

Apart from the VBO issue, UB looks good to me.

The functionality is definitely needed. Syntax issues are less important, though if anyone have a problem (as it seems) don’t hesitate to shoot of a mail to James Percy (whose address is at the front page in that presentation) or to Rob Mace.

Couple of comments to Framebuffer Object (page 21) :

– Memory objects attached to a framebuffer object must have the same dimensions and dimensionality
DX9 is less restrictive: (from SetRenderTarget() description) “The size of depth stencil surface must be greater than or equal to the size of the render target”. Since HW supports it (wouldn’t be in DX otherwise), then why not have this exposed in GL too?

Example: In a game level some objects/surfaces are assigned effects using RTT. Let’s say color data of these RTTs is cachable or fully dynamic, but depth-stencil data is only temporary (becomes useless after RTT color data is ready, so depth buffer can be reused for another RTT effect). And let’s say different instances of these effects may use RTT of different resolution. In this circumstances I’d be forced to create depth & stencil buffers for every possible RTT resolution found in the level, rather than reuse one large for all (possibly the main, screen-sized)

– Memory objects attached to color targets (GL_FRONT, GL_BACK, GL_AUXi, etc.) must have the same format
This could be limiting usage of multiple-render-targets (DX9 is less restrictive here too).

Example: in deferred rendering I’d like to output reflection-vector in 16|32bit float per channel format, but normal-vector in standard 8bit per channel format. Despite having MRT, I’d be forced to do it with multipass.

I can’t say I’m terribly familiar with DirectX, but the way I understand it, hardware vendors are allowed to not have certain functionality avalaible in their Hardware Abstraction Layer. The user can tell, via caps-flags, whether or not a particular piece of functionality is avalible.

Therefore, just because D3D 9 allows for the possibility of a driver exposing render targets with differing resolutions or different formats, it doesn’t actually require that HAL’s implement them. Right?

It would be nice, of course, if we did have the DX9 functionality.

I’m not expert in DXn either, I stopped using it in DX6/7 times. Since then I only download their SDKs, and main reason for this is to read the documentation.

Regarding the first issue, there is no related cap (looks like every HW supports it, or DX emulates it ?). Regarding the second one (MRT), we have:

If the D3DpMISCCAPS_MRTINDEPENDENTBITDEPTHS cap is set, the device can support all mixed formats regardless of format type or bit depth. If the D3DpMISCCAPS_MRTINDEPENDENTBITDEPTHS cap is not set, the device can support mixed types for surfaces containing the same bit depth above 16 bits. The mixing of different format types for 16-bit depth is undefined
plus, of course, a cap saying whether MRT is supported at all.

from the flexible and easy to use VBO to this strange extension… Since this redefines the vertex attachement, and also disallows interleaved arrays, I can only see that we are going to get 2 totally different objects for vertexdata, one for predefined or cpu created data, and one other for gpu generated data… Same for textures, one interface for loaded textures and one for generated data…

I want to test this out befor i complain, but when i compare SB against VBO i say that VBO was a improvement of an old technique, and this (sb) totally redefines a lot of stuff, that i think could be done in an easiser way… but i still want to try it out.

Same for textures, one interface for loaded textures and one for generated data…

That is a good idea… for textures. After all, any super-buffers extension is going to be cumbersome to work with. At least, moreso than just calling glBindTexture and glTexImagenD, if nothing more than the explicit allocation of memory. We still want the old method to work, because very few textures will be render targets. So, we don’t need the code overhead to handle this.

Not if you could bind a texture as a color/depth/stencil target to a framebuffer.
And just load data into a memory area. That would be one call more, just to allocate the memory via opengl instead of an os dependent call.

glGenObject(1,texture);
glGetMem(texture, size, format);
//load the texture
glBindAsTexture(texture, edgeformat and stuff);
// draw with that texture.

and you could just as easy attach it as a rendertarget with the glAttachMem(fb,GL_COLOR_BUFFER, texture); to render to it.

and also disallows interleaved arrays

I was looking at the .pdf, but I didn’t see anything that disallows interleving. If you use glVertexArrayMem() with the same memory object, but with different offsets and strides, you can achieve interleving, just like you can with regular vertex arrays.

Granted, I do agree that the memory binding should have used (and may yet still use, as the spec isn’t done) VBO syntax. But I think that’s been said enough.

Not if you could bind a texture as a color/depth/stencil target to a framebuffer.

Superbuffers is about more than merely render-to-texture. It’s about creating free-standing memory objects that can be used in a multitude of places. Vertex arrays, render targets, textures, and potentially others. This API is useful enough to cover lots of circumstances, while simultaneously not providing too much in the way of overhead.

I must have missed the interleave part if that call… ( still cant see it)

and i dont see how my approach for textures in any way makes it impossible to bind it as a VBO instead.

I must have missed the interleave part if that call… ( still cant see it)

The vertex pointe commands have a stride and an offset. That’s all you need to have interleved arrays.

and i dont see how my approach for textures in any way makes it impossible to bind it as a VBO instead

Easy. A texture has mipmaps. Which mip are you wanting to bind and use as a vertex array? Certainly the VBO glBindBuffer command has no field for specifying mipmap level. And how do you handle slices of 3D textures?

Also, texture objects and buffer objects don’t come out of the same pool. Therefore, texture object 1 and buffer object 1 could be in use at the same time. How does an implementation know which one you’re refering to? Granted, this explains why they don’t use VBO binding syntax (or, at least, why they don’t use glBindBuffer. They could have created a glBindMemBuffer to use a mem buffer using VBO syntax).

Here’s one question I have: how does 2D image data map to a 1D data type like vertex arrays? Things like this could be what lead to the limiting of resolutions for a render target to all be the same. That way, you can’t possibly only render to a part of a buffer, but then expect only that part to be used as a vertex array.

Do you use the pointer commands for drawing?

I only see:
glVertexArrayMem(GL_VERTEX_ARRAY, 4, vmem, 0);
glVertexArrayMem(GL_COLOR_ARRAY, 4, cmem, 0);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);

and if you still used the Pointer commands, why should you specify color and vertex in those commands?

(i think the ‘4’ is a miss, i think they meant to write ‘3’ there, since they allocated the memory with 3)

And i think oyu overcomplicate things in the bindings, you cannot bind an vertexarray to a mipmap level ( not that i can see) and not to a specific slice in a 3d texture. You can bind a slice to a framebuffer, but thats also functionally in my approach (the ‘stuff’ part)

If i havent missunderstod something in the presentation then i think we have an overcomlicated api, atleast for the functionallity we have now, especially since the words ’ for future extencabillity’ was in the VBO aswell… but im not here just to try to convice you, i just stated mu point and hoped for one of the persons that voted for it, or atleast was part of the workgroup to explain the whole new path since VBO api pretty much was designed for ‘buffers’ and vertexbuffers was just the first path of it as i understand.

I was under the impression that the super buffer extension would be more like the VBO extension:

glBindBuffer(GL_MEMORY, foo)
foo_addr=glMapBuffer(GL_MEMORY, GL_READ_ONLY)
glBindTexture(GL_TEXTURE_2D, bar)
glTexImage2D(GL_TEXTURE_2D, …, foo_addr)
glUnmapBuffer(GL_MEMORY)

Or something like that, and the point was that you would still “upload” data with the standard GL functions, but the memory would be on the video card itself and a copy wouldn’t occur (like with glCopyTex[Sub]Image).

And you could allocate memory with the glBufferData function, and the super buffer extension would add whatever is needed for framebuffer binding (or find some way to do that with existing GL calls, like glRead/DrawPixels).

and if you still used the Pointer commands, why should you specify color and vertex in those commands?

What does using gl*Pointer have to do with interleving? The concept of interleved arrays exists outside of a particular API.

Unless you’re refering to explicitly interleved array formats, which was a bad idea when it was written into the vertex array spec, and goes unused in any real application.

you cannot bind an vertexarray to a mipmap level ( not that i can see) and not to a specific slice in a 3d texture

Sure you can. All you do is get the sub-memory object for that mip level and call glVertexArrayMem() using that sub-memory object.

If i havent missunderstod something in the presentation then i think we have an overcomlicated api, atleast for the functionallity we have now, especially since the words ’ for future extencabillity’ was in the VBO aswell…

VBO was a very simple case, compared to what buffer objects have to provide. After all, supplanting client-side memory with server-side memory is not hard from a design point of view. Contrast that with taking an existing API for textures and adding the capacity for creating free-standing memory objects that can be used for textures, framebuffer pieces, vertex arrays, and potentially other things.

a copy wouldn’t occur (like with glCopyTex[Sub]Image).

It still accomplishes the goal of preventing memory copies.

And you could allocate memory with the glBufferData function, and the super buffer extension would add whatever is needed for framebuffer binding (or find some way to do that with existing GL calls, like glRead/DrawPixels).

Oh no. That was never the intent. Even the first inklings of super-buffers, back at GDC, didn’t have the actual allocation of memory being the same as VBO (which had just released around that time).

Now, as we’ve stated before, it would be nice if they used the same entrypoints for binding to

Just please give me an example of interleaved data, and how you bind it with the new array commands in the SB presentation, since i cant find a stride in that call, the size seems to refer to the number of elements (3 for vertex and normal, 2 for UV coords and so on) and then you only have an offset.

and for the rest, ok, i can have missed that in the presentation, But you could just as easily just added the getSubbuffer commands to get the new memorypointers and just used those pointers in VBO.

This way we end up with 2 completely different way to make, and use, buffers for loaded or generated data.

[This message has been edited by Mazy (edited 08-16-2003).]

Originally posted by Mazy:
[b]Just please give me an example of interleaved data, and how you bind it with the new array commands in the SB presentation, since i cant find a stride in that call, the size seems to refer to the number of elements (3 for vertex and normal, 2 for UV coords and so on) and then you only have an offset.
There is no stride, and I see no facility to emulate it.
You’ll need to use different memory objects for each vertex attribute, as far as I understood the presentation.

If that’s true, it sucks. It greatly hinders transition from system memory vertex arrays and VBOs (apps will need ‘regular’ arrays for fallback, VBOs are much easier to implement there; interleaving array data was a good thing last time I checked).

and for the rest, ok, i can have missed that in the presentation, But you could just as easily just added the getSubbuffer commands to get the new memorypointers and just used those pointers in VBO.
Not sure. It makes sense to divide namespaces. Mem objects may be conceivably used in place of VBOs, but the opposite just isn’t possible.
For starters, VBOs never defined hierarchical structure and can’t start doing so now. It may be ‘surprising’ for apps when, say, id 1000 joins the pool of defined VBOs as soon as id 1 is created.

This might have been avoided by further delaying the VBO specification and ironing out the interaction first. I hope we can agree that this wouldn’t have been a good idea.

This way we end up with 2 completely different way to make, and use, buffers for loaded or generated data.
True. You’ll have to chose one of the two ways. If you don’t need the functionality, you needn’t be concerned with this and can keep using VBOs.
Mixed usage may get a bit complicated