Tag Archives: C++11

Stop using bool in C++ for function parameters !

Introduction

This article deals with the use of bool in C++. Should we use it or not? That is the question we will try to answer here. However, this is more of an open discussion than a coding rule.

First of all, what is the bool type? A boolean variable is a variable that can be set to false or true.

Imagine you have a simple function to decide whether or not to buy an house, you may design it like this

Problems arrived!

Then, when you want to use it, you can do it like this:

There is no problem here, however the reader may not understand at first glance if the false means no pools, or if it means no energy saving lights.

So, you will try to change the function call like this:

Now you are happy, the reader knows exactly what bool means. Are you sure? A very thorough reader may notice that there is a reversal of the parameters.

How to solve the problem?

There is different ways to solve this type of problem. The first is to use a strong_type. There are many libraries that offer this kind of thing, however, a simple enum class can do the trick.

Not only will the reader know which argument corresponds to which parameter, but also, in the case of a parameter inversion, the compiler will not let the error pass

Let’s rewrite the function declaration:

Conclusion

I would encourage people not to use the bool type for function parameters. What do you think? Do you use bool everywhere?

Thanks for reading !

Indirect Rendering : “A way to a million draw calls”

Hello !
This time I am going to talk about the Multi Draw Indirect (MDI) rendering. This feature allows you to enjoy both the purpose of multiDraw and indirect drawing.

Where does the overhead comes from?

Issuing a lot of commands

Issue a drawcall in GPU based rendering is a really heavy operation for the CPU. Knowing this, drawing a lot of models could be really expensive.  A naive draw loop could be seemed like that:

The problem is solved using glMultiDraw.
The new code is:

Unknown data

Now, admit you want to use culling to improve performance. You know that if you perform it on the GPU side, you will be more efficient than if you use the CPU, but you don’t know how to use the result without passing data from the GPU to the CPU…  This is where indirect drawing is efficient.

Your old code is

Using MDI, you could have something like that

And you don’t have to get the result from the CPU.

ARB (MULTI) DRAW INDIRECT

Data and functions

This extension provides two structures to perform a drawCall. One for glDrawArrays and one for glDrawElements.

count specifies the number of elements (vertices) to be rendered
primcount specifies the number of instances to be rendered (in our cases, it will be 0 or 1)
first specifies the position of the first vertex
firstIndex specifies the position of the first index
baseVertex specifies the position of the first vertex
baseInstance specifies the first instance to be rendered (a bit tricky, but I am going to explain that later).

How to Use it

These structures should be put into an OpenGL Buffer Object using the target GL_DRAW_INDIRECT_BUFFER.
Admit you have a big scene with, for 5000 distinct objects and 100 000 meshes. You must have:

  1. 5 000 matrices in a SSBO
  2. 5 000” materials (not really true, but you understand the idea) in a SSBO
  3. 100 000 commands in your indirect buffer
  4. A SSBO which contains bounding boxes data by meshes (to perform culling for each meshes).

Now, what you want is RENDER all the scene. The steps to do that are :

  1. Fill matrices / materials / bouding boxes / indirect buffer
  2. make a dispatch using a compute shader to perform culling
  3. Issue a memory barrier
  4. render

The first step is straightforward.
The second is easy, you use the indirect buffer as a SSBO in the compute shader and set the primCount value to 0 if the mesh is not visible or 1 instead
You are intending to issue an indirect command…
render.

Beautiful ! But how do I know which data I have to use?

  1. The first way is to use gl_DrawIDARB which is pretty explicit.
  2. The way we are going to see and the one I am advising, is to use the baseInstance from structures seen prior.

Why gl_DrawIDARB is not convenient? Simply because it is slower than the second way on most implementations, and because we will not be able to use ARB INDIRECT PARAMETERS with it.

So, for the second way, we must add one or several buffers to the prior list (two in our cases,  one for indexing the matrix buffer, and one for indexing the material buffer). These buffers will contain integer values (the index of the matrix / material in their SSBO). Because they will be used through baseInstance, you understand that these buffers will be vertex buffers using a divisor through glVertexBindingDivisor.

A Caveat?

As you noticed, when you remove a command setting primCount to 0, the command is not really removed… Here is coming the extension ARB INDIRECT PARAMETERS. Instead of settings the primCount to 0, you let it to one, but if the mesh is not visible, you don’t add to the really used buffer command, using an atomic counter, you know exactly how many meshes should be rendered.
You have to bind the atomic buffer to GL_PARAMETER_BUFFER_ARB and use the functions

References

Indirect Parameters
Multi Draw Indirect
Surviving without drawID