PDA

View Full Version : Fancy glGetError



kRogue
10-19-2011, 05:19 AM
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.
*/

Groovounet
10-19-2011, 05:26 AM
Erm... GL_ARB_debug_output. This extension is giving a new life to OpenGL debugging.

Why would you need to still use glGetError?

kRogue
10-19-2011, 05:30 AM
Hmmm.. to get what I want out of debug output I'd need to:
Insert the Line/File marker before each call Query and clear the message log after each GL call
OR Use the call back mechanism and make sure that DEBUG_OUTPUT_SYNCHRONOUS_ARB is enabled.

I guess that would work too. Though, it seems like so much more work :whistle:

Groovounet
10-19-2011, 05:39 AM
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.

kRogue
10-19-2011, 06:17 AM
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 :D

Groovounet
10-19-2011, 09:00 AM
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. :p

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!)

kRogue
10-19-2011, 01:12 PM
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 :)

arekkusu
10-19-2011, 04:49 PM
Or use a debugger, click the "break on error" button?

kRogue
10-20-2011, 12:04 AM
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.

Dan Bartlett
10-20-2011, 03:11 AM
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.

kRogue
10-21-2011, 12:53 AM
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.

Alfonse Reinheart
10-21-2011, 02:04 AM
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.

sqrt[-1]
10-21-2011, 03:30 AM
Yes - just another plug for GLIntercept :) - 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.