10/01/2015 Translations in C++ using tables with zero-based enums

Few months ago, I got annoy that we had some code that translate API independent enumerations to OpenGL enumerations, back and forth, with basically no consideration at what happens when we add a new enumeration value in the API independent enumerations and no consideration of how this translation would perform within the rendering loop, where performance is critical and it's typically going to be called. Considering the high number of translations per frame, probably it starts to matter.

Well, we know how things rise... It turns out as this 27 pages article that I called Robust and efficient translations in C++ using tables with zero-based enumerations which is nothing revolutionnary but maybe somewhat useful.

It's pretty common to read some stipulations about how the compilers are supposed to optimize the code. On cross-compiler environments, the following charts from the article are wishing us good luck with such ideas! The four implementation methods are described in the full article.

X: number values per enumeration ; Y: ms.

Four enumeration translation methods performance with Clang 3.6-trunk.
Four enumeration translation methods performance with Clang 3.6-trunk.
Four enumeration translation methods performance with GCC 4.8.1.
Four enumeration translation methods performance with GCC 4.8.1.
Four enumeration translation methods performance with ICC 2015.
Four enumeration translation methods performance with ICC 2015.
Four enumeration translation methods performance with VC 2013.
Four enumeration translation methods performance with VC 2013.

For the once who doesn't want to go through the 27 pages, here is the base solution we propose for enumeration translations.

Translation using a table and zero-based enumemation:
  • enum stage
  • {
  • STAGE_VERTEX = 0,
  • STAGE_TESS_CONTROL,
  • STAGE_TESS_EVALUATION,
  • STAGE_GEOMETRY,
  • STAGE_FRAGMENT,
  • STAGE_LAST = STAGE_FRAGMENT
  • };
  • GLenum translate(stage Stage)
  • {
  • // One weakness in the design: Don't change the order of the enum values
  • static GLenum const Table[] = // Implicitly sized
  • {
  • GL_VERTEX_SHADER, // STAGE_VERTEX
  • GL_TESS_CONTROL_SHADER, // STAGE_TESS_CONTROL
  • GL_TESS_EVALUATION_SHADER, // STAGE_TESS_EVALUATION
  • GL_GEOMETRY_SHADER, // STAGE_GEOMETRY
  • GL_FRAGMENT_SHADER // STAGE_FRAGMENT
  • };
  • // The compiler will generate an error each time we add a new value to the zero-based enum
  • static_assert(
  • sizeof(Table) / sizeof(GLenum) == STAGE_LAST + 1,
  • "OPENGL ERROR: The translation table for 'stage' needs to be updated.");
  • return Table[Stage];
  • };

This template can be extended in many ways to better fit the need of the scenarios where it used as described in the full article.

Enjoy!

Thanks to Stephanie Hurlburt for the review.

January 2015 C++ Compilers Status >
< January 2015 OpenGL hardware matrix
Copyright Christophe Riccio 2002-2016 all rights reserved
Designed for Chrome 9, Firefox 4, Opera 11 and Safari 5