Archived

This topic is now archived and is closed to further replies.

DJSnow

what's all about this GL_EXT_compiled_vertex_array stuff ?

Recommended Posts

DJSnow    100
hi. as the topic let''s assume: i''m interested in opinions about using this extension; i haven''t used it until today; perhaps i may understand this wrong: it''s nearly the same as display lists; but without the state changes - it''s also "compiled". is there a speed improvement when using this extension with normal VA''s ? DJSnow --- this post is manually created and therefore legally valid without a signature

Share this post


Link to post
Share on other sites
DJSnow    100
@ingenu:

>>Nothing we use ARB_vertex_buffer_object instead anyway.

hehe, yes; but we have massive problems with VBO on main target platform, which is GF2MX (there is also a thread on gl.org of me, relating this problem) - and, as you can guess: standard VA's could need a little speed up in our application, and this "compiled vertex array thingy" seems to be a very cheap performance tweak ?!?! i'm not sure about it's usefulness ?!

we have a codepath for VBO's, but it won't work on all our GF2MX's correctly; so i'm heading for a small improvement, if it's possible (and cheap).

DJSnow
---
this post is manually created and therefore legally valid without a signature

[edited by - DJSnow on January 24, 2004 3:15:23 PM]

Share this post


Link to post
Share on other sites
Myopic Rhino    2317
CVAs simply allow you to tell the OpenGL driver that you won''t be modifying your VA data until you unlock the arrays, which may allow it to cache vertex data in video memory. In my experience, the performance improvement is rather small (5-10%) but it''s easy to use them, so I think it''s worth adding support for them if VBOs aren''t available.

Share this post


Link to post
Share on other sites
DJSnow    100
@Myophic...:

>>may allow it to cache vertex data in video memory
mmmh....but: VBO''s also in video memory; so there should me more improvement, or not ?!
(aren''t display lists doing the same thing, too?)

>>so I think it''s worth adding support for them if VBOs aren''t
>>available.
apart from that, VBO implementations seems not very consistent above all cards from TNT to GF4

DJSnow
---
this post is manually created and therefore legally valid without a signature

Share this post


Link to post
Share on other sites
Myopic Rhino    2317
quote:
Original post by DJSnow
>>may allow it to cache vertex data in video memory
mmmh....but: VBO's also in video memory; so there should me more improvement, or not ?!

CVAs aren't intended to be used with VBOs because, as you pointed out, VBOs are already in video memory, so it would be pointless. CVAs were kind of an intermediate step between regular vertex arrays and VBOs. You're still creating your vertex arrays in client memory; locking the arrays simply gives to the driver the option (it's not a guarantee; it may only place part of the arrays, or ignore the lock completely) of placing them in video memory.

So in your VBO path, you shouldn't be using CVAs. In your non-VBO path, you might as well use CVAs if they are supported.

Share this post


Link to post
Share on other sites
DJSnow    100
@myophic...:

>>CVAs aren''t intended to be used with VBOs because, as you
>>pointed out, VBOs are already in video memory, so it would be
>>pointless
no, you understand me wrong - i meant "there should be more gain than 5 - 10%, if CVa''s are also located in video memory"; because VBO gains widely more than 5 - 10%.

ok, i think i will give it a try...

DJSnow
---
this post is manually created and therefore legally valid without a signature

Share this post


Link to post
Share on other sites
DJSnow    100
@myophic...:
to harass you one more time (~post) - i have looked at the source of the GLbook; in the terrain example you are using this extension.
but the code confuses me a little bit, in the initialization function it looks like:

.
.
.
// if the compiled arrays extension is available, lock the arrays
if (glLockArraysEXT) glLockArraysEXT(0, MAP_X * MAP_Z);
.
.


i'm not sure about the behvaiour of this extension - i mean, why do you call it while the initializatin function ?! what would the call look like if i have multiple vertex arrays... ?
specifies the "0" as parameter of glLockArraysExt() in your code the number of the vertexarray or something like this ?!

or means this call of glLockArrays only the trying of the driver "to figure out on his own, which array (bound to an arbitrary point of time) to place on the card's videomem." ?


DJSnow
---
this post is manually created and therefore legally valid without a signature

[edited by - DJSnow on January 24, 2004 7:46:05 PM]

[edited by - DJSnow on January 24, 2004 8:00:58 PM]

Share this post


Link to post
Share on other sites
Promit    13246
This is actually set to be reformatted somewhat and published officially on GDNet (re: new column) but what the hell.
----------------------------------------------------------------
Extension Information:
Name: GL_EXT_compiled_vertex_array
Not part of the OpenGL Standard, as of version 1.5
Availability: Almost every graphics card in existence today, along with most software OpenGL implementations.

Associated Functions:
void glLockArraysEXT( GLint first, GLsizei count );
void glUnlockArraysEXT( void );

Description:
A call to glLockArraysEXT indicates to OpenGL that the arrays specified by glVertexPointer and related functions are not going to change until glUnlockArraysEXT is called. This allows the driver to perform vertex calculations and cache the results.

glLockArraysEXT: Locks the arrays specified starting from first up to the number of elements specified by count.
glUnlockArraysEXT: Unlock the arrays specified by the previous call to glLockArraysEXT.

Explanation:
Before version 1.5, OpenGL contained no built in functionality for vertex buffers or vertex caching. GL_EXT_compiled_vertex_arrays was one of the earliest extensions added for this purpose. Basically, when glLockArraysEXT is called, the driver assumes that you will not be editing any of the arrays you have set for use with glDrawArrays and glDrawElements. This allows it to transform these vertices ahead of time and cache the results in video memory, thus saving bus traffic. It also allows your program to perform other calculations while the GPU does its work, thereby resulting in more efficiency, since you don’t have to wait for the AGP bus or the GPU. Lastly, it allows multiple calls to glDrawElements to use the same set of pre-transformed vertices, instead of reprocessing those vertices on every glDrawElements call. The behavior is undefined if you actually modify the arrays after a glLockArraysEXT call but before a glUnlockArraysEXT call.

Sample Usage:

void Render()
{
glEnableClientState( GL_VERTEX_ARRAY );
//buffer is an array of floats containing vertex data

glVertexPointer( 3, GL_FLOAT, sizeof(float) * 3, Buffer );

//NumVerts is an integer containing the number of

//vertices in Buffer

glLockArraysEXT( 0, NumVerts );

glDrawArrays( GL_TRIANGLES, 0, NumVerts );
//more calls to glDrawArrays/glDrawElements ?


glUnlockArraysEXT();
}


[edited by - Promit on January 24, 2004 8:23:19 PM]

Share this post


Link to post
Share on other sites
DJSnow    100
@promit:

and is it valid to lock and keep locked for the whole runtime of the application ? i mean, if lock-unlock-lock-unlock-lock... the whole time, i think that it won't give anything - because the driver has not the chance to cache it/upload it to videoram, because it must assume that you modify the data; so, i would keep the data locked the whole time ?! (for static data, of course)



DJSnow
---
this post is manually created and therefore legally valid without a signature

[edited by - DJSnow on January 24, 2004 8:39:12 PM]

Share this post


Link to post
Share on other sites
Promit    13246
quote:
Original post by DJSnow
@promit:

and is it valid to lock and keep locked for the whole runtime of the application ? i mean, if lock-unlock-lock-unlock-lock... the whole time, i think that it won''t give anything - because the driver has not the chance to cache it/upload it to videoram, because it must assume that you modify the data; so, i would keep the data locked the whole time ?! (for static data, of course)



It''s fine to keep it locked over frames, just remember that
1) You can''t modify it while it''s locked (undefined behavior)
2) Not unlocking before you exit will be similar to a memory leak, so unlock it eventually!

Share this post


Link to post
Share on other sites
Myopic Rhino    2317
quote:
Original post by DJSnow
no, you understand me wrong - i meant "there should be more gain than 5 - 10%, if CVa's are also located in video memory"; because VBO gains widely more than 5 - 10%.

Reread what I said earlier. CVAs aren't guaranteed to cache your entire transformed vertex arrays in video memory. The driver may ignore CVAs completely, or only cache some vertices. You can probably think of it as hint. You're basically saying "Until I tell you otherwise, I'm not going to change this data, so do whatever you can to optimize it."
quote:
Original post by DJSnow
i'm not sure about the behvaiour of this extension - i mean, why do you call it while the initializatin function ?! what would the call look like if i have multiple vertex arrays... ?
specifies the "0" as parameter of glLockArraysExt() in your code the number of the vertexarray or something like this ?!

I think Promit probably helped with some of your confusion, but let me respond to this anyway. In that demo, I'm only using one set of vertex arrays. Since I'm never changing them, I can lock them immediately after enabling them and passing them to gl*Pointer(). If you're using multiple sets of arrays, then using CVAs isn't going to buy you anything, unless you're using multipass techniques. The driver may cache them, but you'll be unlocking and replacing the arrays before it has a chance to use the cached data.

Btw, the parameters passed to glLockArraysEXT() are similar to the start and count parameters in glDrawArrays(). The first param is the first vertex to lock, and the second is how many vertices to lock.

Share this post


Link to post
Share on other sites
Trienco    2555
hm, before i rewrite everything to try that: are cva as picky about the kind of data you use? situation:
i have a kind of large terrain (2049² just to beat far cry''s 1024) and storing the vertices as 3 floats is far too much. in fact, 3 bytes would already suffice and its working well with vertex arrays. vbo however just seems to hate everything except floats and so performance is totally killed if i dont use them. trying to pass it as color and doing some stuff in the vertex program failed (obviously without any pointer to position or attrib[0] it wont do a thing).

if cva are a little less restrictive they might be an alternative, so i already have a hard time seeing why the data type would make any difference between va and vbo.

Share this post


Link to post
Share on other sites
DJSnow    100
@trienco:
>>in fact, 3 bytes would
it''s impossible to pass GL_BYTE to glVertexPointer says my MSDN ??!?

DJSnow
---
this post is manually created and therefore legally valid without a signature

Share this post


Link to post
Share on other sites
Trienco    2555
quote:
Original post by DJSnow
@trienco:
>>in fact, 3 bytes would
it''s impossible to pass GL_BYTE to glVertexPointer says my MSDN ??!?

DJSnow



it is, but passing data as glAttribPointer doesnt care about the type. sending 3 bytes from a normal va is working well, but vbo is kicking in my face the moment i use anything else but float (just tried it for color and even that will work with 1200fps as float but drop to 48 as byte). slighty frustrating if youre forced to waste 34mb when 12mb would be enough.

maybe cva isnt that annoying *g*

Share this post


Link to post
Share on other sites
DJSnow    100
ok,
i tried it; with an easy mesh, 32k tri's, there is a nice gain of 7 - 10fps; rising the fps from ~63 to ~71.
but: it seems that there is a bug, if i want to use more than one vertex arrays - each time i'm using it with a complex scene, i got an invalid operation; is there any limitation on this extension that i can only use/have locked one array at the same time ?!

but, apart from that for beeing as easy to implement as this, it's not bad


DJSnow
---
this post is manually created and therefore legally valid without a signature

[edited by - DJSnow on January 25, 2004 6:32:16 PM]

Share this post


Link to post
Share on other sites
Promit    13246
Well, yes, you can only have one locked array at a time, because to changing which array you''re using is essentially the same as changing the array. You have to unlock before calling any of the gl*Pointer functions.

The primary use of CVAs is probably when you have a single array of vertices and you have to draw many index buffers using those vertices.

Share this post


Link to post
Share on other sites