PDA

View Full Version : using glMultiDrawArraysIndirect with instancing problems



pettersson
03-04-2015, 11:35 PM
Hi,

I am rendering a rather huge dataset using mainly indirect draw calls. Now I am implementing Instancing and stumbled upon a problem. I set up three buffers: draw commands (GL_DRAW_INDIRECT_BUFFER), vertices (GL_ARRAY_BUFFER) and a buffer for the instanced matrices (GL_ARRAY_BUFFER). To check wether my matrices and meshes are correct I rendered all my stuff without instancing, resulting in a huge vertex buffer and a huge list of draw commands. Drawing works this way :) Now, using instancing I set up up the draw commands as follows:



draw_cmd.count = n_mesh_vertices
draw_cmd.instance_count = n_instances
draw_cmd.first = offset_to_first_vertex_inside_vertex_buffer
draw_cmd.base_instance = offset_to_first_required_instanced_matrix


and one draw command per mesh. If I render these three buffers, nothing gets displayed. I also get no error messages (using the GL debug context extension) whatsoever.

Maybe the base_instance is wrong or I misunderstood some concept? I am setting the base_instance to the first matrix to be used for instancing this one mesh for this draw command.
Or maybe my setup for the matrix buffer is wrong. Command buffer and vertex buffer are ok, since rendering them without instancing (settings instance_count to 1 and base_instance to 0).

For the matrix buffer I set 4 consecutive attributes (for the 4 vec4 'elements') with a stride of 64 bytes and 0,16,32,48 as offset. I am using glm for all my math calculations and storing of vectors and matrices. For every attribute I set the glAttribDivisor to 1.

And here's the part of the vertex shader:



layout(location=0) in vec3 position;
layout(location=1) in vec3 normal;
layout(location=2) in mat4 instanced_mat4;


Is there anything I am missing or maybe I am doing something completely wrong? Any help is appreciated

thanks in advance
pettersson

Alfonse Reinheart
03-05-2015, 05:39 AM
It's rather difficult to know where your problem is, since you didn't really post any code. It could be the way you issue the rendering command, the data you're storing into your buffer, the way you're uploading data to the buffer, etc.


I set up three buffers: draw commands (GL_DRAW_INDIRECT_BUFFER), vertices (GL_ARRAY_BUFFER) and a buffer for the instanced matrices (GL_ARRAY_BUFFER).

Just a thing to note. Buffer objects (https://www.opengl.org/wiki/Buffer_Object) are not like texture objects (https://www.opengl.org/wiki/Texture). Where you bind them is not fixed. With your code, you could use the same buffer (obviously larger to fit your data), and simply use different parts for the different needs.

You don't have to of course; I just wanted to make sure that you knew that.

pettersson
03-05-2015, 11:01 PM
Hi,

thanks a lot for your answer. Although you couldn't point directly at my error, mentioning Buffer Object <=> Texture Objects made me recheck my buffers once more and I could find the error :) It was my VAO setup which was wrong and Instancing works now. I use multiple buffers for clarity, this way it's easier for me to keep track of what I am doing. But isn' it mandatory to bind the draw command data to GL_DRAW_INDIRECT_BUFFER so that glMultiDrawIndirect takes it's data from there? One thing I noticed after updating my NVidia drivers (OpenSUSE): at first I was not using a buffer for the glMultiDrawIndirect call, instead I directly used the array of commands as stated in the documentation. With the newer driver it only works when I actually bind a buffer to GL_DRAW_INDIRECT_BUFFER. The 'old' way produces an error message.

thanks again :D
pettersson

GClements
03-07-2015, 07:00 AM
But isn' it mandatory to bind the draw command data to GL_DRAW_INDIRECT_BUFFER so that glMultiDrawIndirect takes it's data from there?
Core profile requires a buffer to be bound to GL_DRAW_INDIRECT_BUFFER. Compatibility profile allows the data to be sourced from client memory.

The core profile specification doesn't make this particularly clear, saying that the data "may" be sourced from the buffer. But the compatibility profile specification has the sentence


If zero is bound to DRAW_INDIRECT_BUFFER, the corresponding *Draw*Indirect commands instead source their arguments directly from the indirect pointer in client memory.

in red, indicating that it only applies to the compatibility profile.