View Full Version : ARB_instanced_arrays + ARB_vertex_array_object

07-19-2012, 07:17 AM
is glVertexAttribDivisor() part of a vertex array objects state? can't seem to find confirmation in the spec, although it seems to be true on this nvidia driver.

I'm just checking because I'm trying to diagnose a very strange flickering bug when using this combination, not in the instanced geometry but in other non-instanced geometry. Interestingly all other geometry drawn with VBO's but *not* using vertex array objects (or rather, using the default 0 VAO) flicker, alternating between being drawn in one frame and not drawn in the next frame. In fact, it might not be related to the instanced arrays/vao combination itself, but maybe just the fact the instance render is the only scene object using VAO's.

here's my VAO setup code.

glGenVertexArrays(1, &m_model.m_vao);
glBindBuffer(GL_ARRAY_BUFFER, m_model.m_mesh.m_vbo);
glVertexAttribPointer(SLOT_POS, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex,m_pos));
glVertexAttribPointer(SLOT_NRM, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex,m_nrm));
glVertexAttribPointer(SLOT_UV, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex,m_uv));
glBindBuffer(GL_ARRAY_BUFFER, m_model.m_instance.m_vbo);
glVertexAttribPointer(SLOT_ROW1, 4, GL_FLOAT, GL_FALSE, sizeof(Mat4x3), (void*)(offsetof(Mat4x3,m_row1)));
glVertexAttribPointer(SLOT_ROW2, 4, GL_FLOAT, GL_FALSE, sizeof(Mat4x3), (void*)(offsetof(Mat4x3,m_row2)));
glVertexAttribPointer(SLOT_ROW3, 4, GL_FLOAT, GL_FALSE, sizeof(Mat4x3), (void*)(offsetof(Mat4x3,m_row3)));
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_model.m_mesh.m_ibo);
glVertexAttribDivisor(SLOT_ROW1, 1);
glVertexAttribDivisor(SLOT_ROW2, 1);
glVertexAttribDivisor(SLOT_ROW3, 1);

as a side note, the display list scene objects don't flicker - just those drawn with plain old VBO's, and even immediate mode.

07-19-2012, 07:59 AM
Yes it is. If you're ever in doubt, you can check the GL state tables in the GL specification where that feature became core. In this case, it's on page 418 of the 3.3 compatibility profile spec (section 6.2).

Dark Photon
07-19-2012, 07:05 PM
Have you tried on the 300 series beta drivers? They seem to resolve one issue that occurs with instanced arrays (and bindless). Maybe another?

Might check that you don't have some stale lazy state that's being fooled by VAO binds, and also ensure you don't have some code that's messing up the state of VAO #0. Do some queries to verify its state is what you think it is.

07-20-2012, 02:09 PM
Thanks guys but its a genuine nvidia driver bug, stretching back to at least February last year. Basically a simple test case using glDrawElementsInstanced and then drawing an immediate mode quad results in the quad not drawing at all. This is with the base 3d app profile selected in display properties. Selecting the visual simulation profile makes the bug go away and the quad draws fine. These profiles are a quadro only feature, supposedly to give the driver a hint for optimisations, but in practice I've found them a pain in the arse, introducing weird bugs all over the place, like this.
So to reiterate, nothing to do with vao's, just a profile-sensitive bug in the quadros implementation of instanced arrays. I'll try to report it but my devrel login doesn't work anymore.

07-20-2012, 02:51 PM
Ouch. I guess mixing the new with the old doesn't make for a happy driver.

As for the Nvidia dev login, that might be because of this: http://www.anandtech.com/show/6092/nvidia-forums-dev-zone-breached-up-to-400k-password-hashes-taken.

07-21-2012, 07:25 AM
Not an issue of new and old, the immediate mode quad in my example was just for clarity, ironically. The problem's there whatever the non-instanced geometry submission path is (vao/vbo) except display lists which draw fine.

07-21-2012, 07:35 AM
The default profile too....a customer support nightmare. No problem on the 5 times less expensive geforce.

07-21-2012, 07:40 AM
As you can probably tell I'm rather stressed by this, invested a lot of time in this instance renderer, all hinges on gldrawelementsinstanced

07-21-2012, 08:44 PM
Have you tried hacking a workaround, such as resetting all the vertex divisors to 0 after the instanced VAO is unbound? I've had to do some crazy things to avoid driver bugs in the past, usually conditional on vendor & driver version.

07-22-2012, 02:55 PM
Oh my god mate I've tried everything. Push/pop server and client attribs, setting all client states to default including divisors, flush, finish, drawing quads outside view port, the list goes on. Nothing made a difference. The problem goes away if run under gedebugger, so its possible its a context setup state maybe, god knows.