Naming resources for debugging

When you’re debugging, and have a lot of separate resources, eg. textures 0 - 600, buffer objects 0 - 200, it is hard to find the right resource in OpenGL debuggers. If the objects could be “named” in some way, this would be much easier.

<waffle mode>
There’s many ways this could be done, including:

  1. New entry points for each object type to allow setting string parameters.
glTexParameterString(GL_TEXTURE_2D, GL_NAME, "green_grass");
glTextureParameterEXT(texture_id, GL_TEXTURE_2D, GL_NAME, "green_grass");
glSamplerParameterString(sampler_id, GL_NAME, sampler_name);

However, I find separate entry points to set parameters a bit annoying though, and only as new parameters are added to objects are the entry points that are needed to access the property added, which leads to wondering what extension requirements different glXXXParameterYYY functions have.

  1. Adding new entry points that act on any type of object:
glObjectParameterString(texture_id, GL_TEXTURE_2D, GL_NAME, "green_grass");
glObjectParameterString(sampler_id, GL_SAMPLER, GL_NAME, "sampler1");
glObjectParameteri(texture_id, GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 4);

Like direct state access entry points or recent OpenGL entry points, it contains a reference to the object id in the parameter call, but also like all other parameter calls, this also suffers from the different enum values used being spread out, so that either a slow “switch” statement would be used to choose the right code path, or a perhaps a table with HIGHEST_ENUM_USED - LOWEST_ENUM_USED entries.

  1. Adding new entry points that act on any type of object, but only accept new enums starting from 0 for each object’s set of accepted parameters.

// object types
GL_OBJECT_TEXTURE = 0,
GL_OBJECT_SAMPLER = 1,
GL_OBJECT_BUFFER_OBJECT = 2
// querying GL_NUM_OBJECT_TYPES returns 3

// texture object params (or might want per texture type)
GL_TEXTURE_BASE_LEVEL = 0,
GL_TEXTURE_MAX_LEVEL = 1,
GL_TEXTURE_NAME = 2,
// querying GL_NUM_TEXTURE_PARAMS returns 3

// sampler object params
GL_SAMPLER_PARAM_BORDER_COLOR = 0,
GL_SAMPLER_MIN_FILTER = 1,
GL_SAMPLER_MAG_FILTER = 2,
GL_SAMPLER_PARAM_MIN_LOD = 3,
GL_SAMPLER_PARAM_MIN_LOD = 4,
// querying GL_NUM_SAMPLER_PARAMS returns 5

// setting a couple of params individually
glObjectParameterString(texture_id, GL_OBJECT_TEXTURE_2D, GL_TEXTURE_2D_NAME, "green_grass");
glObjectParameterString(sampler_id, GL_OBJECT_SAMPLER, GL_SAMPLER_NAME, "sampler1");

// setting a batch of params
params[0] = GL_SAMPLER_PARAM_BORDER_COLOR;
values[0] = &color;
params[1] = GL_SAMPLER_PARAM_MIN_FILTER;
values[1] = &min_filter;
params[2] = GL_SAMPLER_PARAM_MAG_FILTER;
values[2] = &mag_filter;
params[3] = 0;
values[3] = 0;
glObjectParameters(sampler_id, GL_OBJECT_SAMPLER, params, values);

While I’m at it, I might as well suggest some form of template objects for creating objects too:

sampler_template = glCreateObjectTemplate(GL_SAMPLER);
glObjectParameteri(sampler_template, GL_OBJECT_SAMPLER, GL_SAMPLER_MIN_FILTER, GL_LINEAR);
glObjectParameteri(sampler_template, GL_OBJECT_SAMPLER, GL_SAMPLER_MAG_FILTER, GL_LINEAR);
glObjectParameteri(sampler_template, GL_OBJECT_SAMPLER, GL_SAMPLER_IMMUTABLE, GL_TRUE);

sampler1 = glCreateObjectFromTemplate(sampler_template);
sampler2 = glCreateObjectFromTemplate(sampler_template);

texture_template = glCreateObjectTemplate(GL_TEXTURE);
glObjectParameteri(texture_template, GL_OBJECT_TEXTURE, 
GL_MAX_LEVEL, 4);
***some way of defining texture levels - needs some thought, perhaps texture level templates/objects too***
glObjectParameteri(texture_template, GL_OBJECT_TEXTURE, GL_TEXTURE_IMMUTABLE_STRUCTURE, GL_TRUE);
glObjectParameteri(texture_template, GL_OBJECT_TEXTURE, GL_TEXTURE_IMMUTABLE_CONTENT, GL_FALSE);


</waffle mode>

While I’m at it, I might as well suggest some form of template objects for creating objects too:

It’s almost like you read the old Longs Peak API documents. Odds are good that they won’t be trying that again.

This is an excellent idea Dam to extend the debug output extension!

why don’t you use a hashmap from GLuint to std::string in your application?

I want to access the name in external debuggers (eg. gDEBugger), and unless there was a common way to access the resource name, you would have to rely on some specific method for providing the information to each debugger, such as calling glStringMarkerGREMEDY to provide the extra information.

You can call glStringMarkerGREMEDY on each bind call to provide information about what texture is being bound, but this doesn’t really help when it comes to a list of 600+ resources, unless it also parsed those strings in some way + put the name with the resource. If you then start using a different debugger, you would probably need to start emitting different information to get names to be associated with resources.

void BindTexture(GLenum target, GLuint tex)
{  
  #ifdef DEBUG_EMIT_GL_RESOURCE_NAMES
  glStringMarkerGREMEDY(0, lookup_texture_name(tex));
  #endif
  glBindTexture(target, tex);
}

Like this, you mean?

http://www.khronos.org/registry/gles/extensions/EXT/EXT_debug_label.txt

Yeah, that extension would be useful for OpenGL too.