Fancy glGetError

Hunting down GL errors is… painful. Worse the return values from glGetError() are at times not very informative.

Here is an idea: an error object:



/* 
  new tokens
*/
#define GL_SUCCEED 0xXXXX 
#define GL_FAIL 0xXXXX

#define GL_ERROR_MESSAGE 0xXXXX
#define GL_ERROR_CODE 0xXXXX

/*
  if there is an error, returns a non-zero integer 
giving the name of an error object. If there is no 
GL-error then returns 0.
*/
GLuint glGetErrorObject(void);

/*
  Deletes an error object as returned by glGetErrorObject.
  If an invalid object is passed, returns GL_FAIL, otherwise
  delete the passed error object and returns GL_SUCCEED.
*/
GLenum glDeleteErrorObject(GLuint);


/*
  query a property of an error object. If the property name, pname,
  is valid, write the value of the property to v and return GL_SUCCEED.
  If the property does not exist, return GL_FAIL and the contents of v are
  unaffected, otherwise. 
*/
GLenum glQueryErrorObject[][](GLuint error_object, GLenum pname, GLtype *v);

/*
  query a string property of the error object. 
  Returns GL_SUCCEED is property exists and is a string,
  otherwise returns GL_FAIL and does not affect the contents
  pointed to by errorMessage or length.

  \param errorMessage buffer to which to write the string 
  \param bufSize size of buffer pointed to by errorMessage
  \param length, if NON-null write to length the size 
                 of the string being queried
  \param error_object Error object to query
  \param pname property string to query
*/
GLenum glQueryErrorObjectString(GLuint error_object, GLenum pname, 
                               GLsizei bufSize, GLsizei *length, 
                               GLchar *errorMessage);


/*
   1) How do glGetErrorObject and glGetError interact? 
    Answer: calling glGetErrorObject removes the error 
            from GL as does glGetError.
  
   2) Why not use the debug ARB extension?
    Answer: a number of systems use macros to query GL errors 
immediately after a GL call to get line and file information of 
the GL error. The ARB debug extension does not expose a simple 
direct method for a C program to get the line and file of the
 offending GL calls.     

  3) Why do the functions return a success code?
    Answer: it is bad taste to generate an error while querying an error.

  4) What are the base properties proposed?
    Answer: For now atleast:
         GL_ERROR_CODE is the error code ala glGetError
         GL_ERROR_MESSAGE is an implementation dependent string to articulate the error
    This proposal is written so that other error information 
can be added, even warning messages.   
*/


Erm… GL_ARB_debug_output. This extension is giving a new life to OpenGL debugging.

Why would you need to still use glGetError?

Hmmm… to get what I want out of debug output I’d need to:
[ul][li] Insert the Line/File marker before each call[*] Query and clear the message log after each GL call[/li]OR[li] Use the call back mechanism and make sure that DEBUG_OUTPUT_SYNCHRONOUS_ARB is enabled.[/ul][/li]
I guess that would work too. Though, it seems like so much more work :whistle:

Put a break point in your callback function and in the call stack you can get back to the exact OpenGL that through the error and hence see all the states you want.

Make sure to call glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
Even if currently no drivers support async debut output.

the spec says that if GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB is on, the function gets called before the GL call returns… and according to the spec one will see the call stack… but… it make me nervous to debug into a call which is called from GL… I suppose the GL implementation is expected to make sure that the call stack has that the GL call from the application is the direct caller of the call back? The spec mentions “good to see the call stack”, but not as specific.

hmm… I guess I will need to try the extension out more carefully… but I just feel nervous about giving call backs… not entirely rational I admit especially with GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB enabled… but… paranoia is usually a good thing.

As a side note, sometimes I don’t want to break into the debugger on the first GL error (or now here GL warning)… and sometimes I want to log the calls, etc… it is all doable with essentially inserting the message into the debug stream I guess… ehh… maybe I made my suggestion the way i did because I already have a nice macro system working with glGetError (but I think it is not big work to get it to work with the debug extension).

I am lazy though at times :smiley:

GL_ARB_debug_output has totally change my way of programming with OpenGL, making it so much faster and nicer.

Consequently, I have decided to spank everyone who would still use glGetError because there are obviously masochists. :stuck_out_tongue:

AMD implementation is pretty incredible as it gives you a clear description of the error. NVIDIA has started to move on with performance hints in Forceware 285 but I expect much more in 290.

There are probably way to make it better, but glGetError should die in a hell of all the pain it gave to all the OpenGL programmers until now. (Pretty horrible way to die in my opinion!)

You have convinced that GL_ARB_debug_output is the bomb. I guess I was just so used to glGetError() that I just lived with it and around it via macros. Now, with GL_ARB_debug_output the need for ick macros drops significantly as one does not need to query all the freaking time… what a difference a day makes :slight_smile:

Or use a debugger, click the “break on error” button?

The GL debuggers are very, very fragile. I have crashed and murdered all of them. Typically comes down to that if one uses an extension the debugger does not understand/know, bad things can happen.

If the debuggers allowed you to specify new objects to group state together then it might help their reliability without needing to be constantly updated. Eg. If your debugger doesn’t know about VAOs, and you call glBindVertexArray(vao1), then it’s unlikely to understand what’s happened to all the vertexarray information (unless it queries every piece of state on each call).

If you could specify what state belongs to the context, or to different objects when new extensions are added that it doesn’t understand, then it might help.

I’d imagine a feature like this would consist of a list of objects and an OpenGL state table, where you would click a button to create a new object type, specify the selector function(s), then drag the state that now belongs to an object from the context state into the object state.

You would also need to specify what GL functions generation the new object type (is it glGen style or does it return the object like glCreateShader), what function is used to query it, the arguments for the query… etc.

last time I tried gDebugger with bindless it just gave up and crashed every time. The awful truth for GL debuggers is that underneath somewhat as a hack because they need to inspect GL data from another process. There is almost nothing in GL that allows one to share data across process boundaries. Hence, if you application process did something bad, the debugger process cannot query the application process for the GL data (it is too late!). I’d imagine the way to do it is to have another thread in the application process that makes a GL context that is in the same share group and the debugger sends a message to that thread to get the GL data… or the debugger can try to fetch data it thinks it has changed at glFinish/swap_buffers. But it is all hacky and very fragile.

The real solution for debugging GL is that one needs to be able to create a context that shares GL data across process boundaries so that the debugger can inspect the data. The understanding is that data is just bytes (be it in VRAM, wherever) and the remote process can inspect those bytes… just like a debugger would.

I don’t know; whenever I have problems with GL, I just use GL Intercept. It’s not a debugger, per se, but it works well enough for my needs.

Yes - just another plug for GLIntercept :slight_smile: - it functions with all OpenGL extensions (even ones not yet written) - and is very rarely known to crash. (especially if just using the error debug functionality)

You can set it to break into the debugger on OpenGL errors (and you get a call stack), and get the error logged to the debugger output window.

In extreme situations where a OpenGL call is causing a crash in you application, you can force flush the log file after each OpenGL call.