PDA

View Full Version : OpenGL Code impact Question



Savvy_Fox42
01-11-2015, 10:04 AM
What I am wondering is how much impact the following code would make on speed if i called it more than once a frame to bind different vectors of floats for different models.



glBindVertexArray(VAOid);

GLuint vertexbuffer;
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, verts.size() * sizeof(float), &verts[0], GL_STATIC_DRAW);

GLuint uvbuffer;
glGenBuffers(1, &uvbuffer);
glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
glBufferData(GL_ARRAY_BUFFER, texs.size() * sizeof(float), &texs[0], GL_STATIC_DRAW);

glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);


My current setup uses a single, large vector, but this has many bugs that are hard to track.

Will this code cause any if at all speed detriments to use it to bind many different vectors from different models.

Also, any suggestions on different render methods are allowed.

Dark Photon
01-11-2015, 07:26 PM
Try it and benchmark it. Binding buffers is expensive. VAOs help. Bindless helps more. Packing multiple batches into the same buffers can reduce binds and increase performance. Lots of info in the archives on this.

Savvy_Fox42
01-12-2015, 06:50 AM
Follow up question: How costly are matrix operations.

mhagain
01-12-2015, 06:56 AM
Depends on what kind of matrix operation you mean...

Savvy_Fox42
01-12-2015, 07:49 AM
Sending a new Matrix to the program with glUniformMatrix4fv();

Alfonse Reinheart
01-12-2015, 08:25 AM
You're talking about things that are very difficult to quantify, and which will be at least somewhat implementation-dependent.

Is updating a matrix via a uniform faster than updating a matrix stored in a uniform buffer (https://www.opengl.org/wiki/Uniform_Buffer_Object)? It may be, it may not. For example, on most ATI hardware, uniforms in shaders (except for opaque types (https://www.opengl.org/wiki/Data_Type_%28GLSL%29#Opaque_types)) always use an internal uniform buffer. So a single glUniformMatrix call will probably not be much slower than updating a single matrix yourself on ATI hardware. However, NVIDIA hardware may have a more optimized way of storing uniforms, in which case, the call may be faster. Or the call may be slower, but accessing the matrix in the shader is faster.

By contrast, uniform buffers allow you the ability to update multiple matrices in a scene all at once, potentially using advanced streaming techniques (https://www.opengl.org/wiki/Buffer_Object_Streaming) to do so. They can also update other per-instance data. Which is faster? It depends. Do you need to change UBO bindings for each object, or are you able to simply pass an instance index to tell the shader where its data is? How do you pass this instance index? And so forth.

The answer is that it's complicated. Performance always is.

Savvy_Fox42
01-12-2015, 08:48 AM
I guess this a case of try it and see what works best.

mhagain
01-12-2015, 09:11 AM
I guess this a case of try it and see what works best.

Performance is always like this too.

As well as the items Alfonse mentions, which are absolutely correct, it's also the case that everybody's code is different, and everybody's code stresses different parts of the pipeline differently. So what's faster with my program may be slower with yours, and vice-versa. The best advice that can be given tends to be along the lines of more generic guidelines, i.e fewer large updates are preferred to many small updates, minimize state changes between draw calls, these API entry points are more likely to be optimized by vendors, etc; but in reality you do need to benchmark in your own code, and you also need to evaluate what is sometimes a tradeoff between faster code and cleaner code. If you already run fast enough it may even be perfectly acceptable to leave some of your code on a slower path.