11
Brian Paul (brian.paul 'at' tungstengraphics.com)
15
XXX - Not complete yet!!!
19
Last Modified Date: July 20, 2003
28
OpenGL 1.4 is required
29
The extension is written against the OpenGL 1.4 specification.
30
ARB_vertex_program or ARB_fragment_program or NV_vertex_program
31
or NV_fragment_program is required.
35
The extension provides facilities for implementing debuggers for
36
vertex and fragment programs.
38
The concept is that vertex and fragment program debuggers will be
39
implemented outside of the GL as a utility package. This extension
40
only provides the minimal hooks required to implement a debugger.
42
There are facilities to do the following:
43
1. Have the GL call a user-specified function prior to executing
44
each vertex or fragment instruction.
45
2. Query the current program string's execution position.
46
3. Query the current values of intermediate program values.
48
The main feature is the ProgramCallbackMESA function. It allows the
49
user to register a callback function with the GL. The callback will
50
be called prior to executing each vertex or fragment program instruction.
52
From within the callback, the user may issue Get* commands to
53
query current GL state. The GetProgramRegisterfvMESA function allows
54
current program values to be queried (such as temporaries, input
55
attributes, and result registers).
57
There are flags for enabling/disabling the program callbacks.
59
The current execution position (as an offset from the start of the
60
program string) can be queried with
61
GetIntegerv(GL_FRAGMENT_PROGRAM_POSITION_MESA, &pos) or
62
GetIntegerv(GL_VERTEX_PROGRAM_POSITION_MESA, &pos).
71
1. Is this the right model for a debugger?
73
It seems prudent to minimize the scope of this extension and leave
74
it up to the developer (or developer community) to write debuggers
75
that layer on top of this extension.
77
If the debugger were fully implemented within the GL it's not
78
clear how terminal and GUI-based interfaces would work, for
81
2. There aren't any other extensions that register callbacks with
82
the GL. Isn't there another solution?
84
If we want to be able to single-step through vertex/fragment
85
programs I don't see another way to do it.
87
3. How do we prevent the user from doing something crazy in the
88
callback function, like trying to call glBegin (leading to
91
The rule is that the callback function can only issue glGet*()
92
functions and no other GL commands. It could be difficult to
93
enforce this, however. Therefore, calling any non-get GL
94
command from within the callback will result in undefined
97
4. Is this extension amenable to hardware implementation?
99
Hopefully, but if not, the GL implementation will have to fall
100
back to a software path when debugging. This may be acceptable
103
5. What's the <data> parameter to ProgramCallbackMESA for?
105
It's a common programming practice to associate a user-supplied
106
value with callback functions.
108
6. Debuggers often allow one to modify intermediate program values,
109
then continue. Does this extension support that?
114
New Procedures and Functions (and datatypes)
116
typedef void (*programcallbackMESA)(enum target, void *data)
118
void ProgramCallbackMESA(enum target, programcallbackMESA callback,
121
void GetProgramRegisterfvMESA(enum target, sizei len,
122
const ubyte *registerName, float *v)
126
Accepted by the <cap> parameter of Enable, Disable, IsEnabled,
127
GetBooleanv, GetDoublev, GetFloatv and GetIntegerv:
129
FRAGMENT_PROGRAM_CALLBACK_MESA 0x8bb1
130
VERTEX_PROGRAM_CALLBACK_MESA 0x8bb4
132
Accepted by the <pname> parameter GetBooleanv, GetDoublev,
133
GetFloatv and GetIntegerv:
135
FRAGMENT_PROGRAM_POSITION_MESA 0x8bb0
136
VERTEX_PROGRAM_POSITION_MESA 0x8bb4
138
Accepted by the <pname> parameter of GetPointerv:
140
FRAGMENT_PROGRAM_CALLBACK_FUNC_MESA 0x8bb2
141
FRAGMENT_PROGRAM_CALLBACK_DATA_MESA 0x8bb3
142
VERTEX_PROGRAM_CALLBACK_FUNC_MESA 0x8bb6
143
VERTEX_PROGRAM_CALLBACK_DATA_MESA 0x8bb7
145
Additions to Chapter 2 of the OpenGL 1.4 Specification (OpenGL Operation)
149
Additions to Chapter 3 of the OpenGL 1.4 Specification (Rasterization)
153
Additions to Chapter 4 of the OpenGL 1.4 Specification (Per-Fragment
154
Operations and the Frame Buffer)
158
Additions to Chapter 5 of the OpenGL 1.4 Specification (Special Functions)
160
In section 5.4 "Display Lists", page 202, add the following command
161
to the list of those that are not compiled into display lists:
166
Add a new section 5.7 "Callback Functions"
170
void ProgramCallbackMESA(enum target, programcallbackMESA callback,
173
registers a user-defined callback function with the GL. <target>
174
may be FRAGMENT_PROGRAM_ARB or VERTEX_PROGRAM_ARB. The enabled
175
callback functions registered with these targets will be called
176
prior to executing each instruction in the current fragment or
177
vertex program, respectively. The callbacks are enabled and
178
disabled by calling Enable or Disable with <cap>
179
FRAGMENT_PROGRAM_ARB or VERTEX_PROGRAM_ARB.
181
The callback function's signature must match the typedef
183
typedef void (*programcallbackMESA)(enum target, void *data)
185
When the callback function is called, <target> will either be
186
FRAGMENT_PROGRAM_ARB or VERTEX_PROGRAM_ARB to indicate which
187
program is currently executing and <data> will be the value
188
specified when ProgramCallbackMESA was called.
190
From within the callback function, only the following GL commands
197
GetProgramLocalParameter
198
GetProgramEnvParameter
199
GetProgramRegisterfvMESA
204
Calling any other command from within the callback results in
208
Additions to Chapter 6 of the OpenGL 1.4 Specification (State and
211
Add a new section 6.1.3 "Program Value Queries":
215
void GetProgramRegisterfvMESA(enum target, sizei len,
216
const ubyte *registerName,
219
Is used to query the value of program variables and registers
220
during program execution. GetProgramRegisterfvMESA may only be
221
called from within a callback function registered with
224
<registerName> and <len> specify the name a variable, input
225
attribute, temporary, or result register in the program string.
226
The current value of the named variable is returned as four
227
values in <v>. If <name> doesn't exist in the program string,
228
the error INVALID_OPERATION is generated.
230
Additions to Appendix A of the OpenGL 1.4 Specification (Invariance)
234
Additions to the AGL/GLX/WGL Specifications
242
Dependencies on NV_vertex_program and NV_fragment_program
244
If NV_vertex_program and/or NV_fragment_program are supported,
245
vertex and/or fragment programs defined by those extensions may
246
be debugged as well. Register queries will use the syntax used
247
by those extensions (i.e. "v[X]" to query vertex attributes,
248
"o[X]" for vertex outputs, etc.)
252
INVALID_OPERATION is generated if ProgramCallbackMESA is called
253
between Begin and End.
255
INVALID_ENUM is generated by ProgramCallbackMESA if <target> is not
256
a supported vertex or fragment program type.
258
Note: INVALID_OPERAION IS NOT generated by GetProgramRegisterfvMESA,
259
GetBooleanv, GetDoublev, GetFloatv, or GetIntegerv if called between
260
Begin and End when a vertex or fragment program is currently executing.
262
INVALID_ENUM is generated by ProgramCallbackMESA,
263
GetProgramRegisterfvMESA if <target> is not a program target supported
264
by ARB_vertex_program, ARB_fragment_program (or NV_vertex_program or
265
NV_fragment_program).
267
INVALID_VALUE is generated by GetProgramRegisterfvMESA if <registerName>
268
does not name a known program register or variable.
270
INVALID_OPERATION is generated by GetProgramRegisterfvMESA when a
271
register query is attempted for a program target that's not currently
281
Get Value Type Get Command Value Description Sec. Attribute
282
--------- ---- ----------- ----- ----------- ---- ---------
283
FRAGMENT_PROGRAM_CALLBACK_MESA B IsEnabled FALSE XXX XXX enable
284
VERTEX_PROGRAM_CALLBACK_MESA B IsEnabled FALSE XXX XXX enable
285
FRAGMENT_PROGRAM_POSITION_MESA Z+ GetIntegerv -1 XXX XXX -
286
VERTEX_PROGRAM_POSITION_MESA Z+ GetIntegerv -1 XXX XXX -
287
FRAGMENT_PROGRAM_CALLBACK_FUNC_MESA P GetPointerv NULL XXX XXX -
288
VERTEX_PROGRAM_CALLBACK_FUNC_MESA P GetPointerv NULL XXX XXX -
289
FRAGMENT_PROGRAM_CALLBACK_DATA_MESA P GetPointerv NULL XXX XXX -
290
VERTEX_PROGRAM_CALLBACK_DATA_MESA P GetPointerv NULL XXX XXX -
294
New Implementation Dependent State
301
Initial draft. (Brian Paul)
303
Second draft. (Brian Paul)
305
Third draft. Lots of fundamental changes. (Brian Paul)
307
Added chapter 5 and 6 spec language. (Brian Paul)
311
The following is a very simple example of how this extension may
312
be used to print the values of R0, R1, R2 and R3 while executing
316
/* This is called by the GL when the vertex program is executing.
317
* We can only make glGet* calls from within this function!
319
void DebugCallback(GLenum target, GLvoid *data)
324
/* Get PC and current instruction string */
325
glGetIntegerv(GL_VERTEX_PROGRAM_POSITION_ARB, &pos);
327
printf("Current position: %d\n", pos);
329
printf("Current temporary registers:\n");
330
for (i = 0; i < 4; i++) {
333
sprintf(s, "R%d", i);
334
glGetProgramRegisterfvMESA(GL_VERTEX_PROGRAM_ARB, strlen(s), s, v);
335
printf("R%d = %g, %g, %g, %g\n", i, v[0], v[1], v[2], v[3]);
344
/* Register our debugger callback function */
345
glProgramCallbackMESA(GL_VERTEX_PROGRAM_ARB, DebugCallback, NULL);
346
glEnable(GL_VERTEX_PROGRAM_CALLBACK_MESA);
348
/* define/bind a vertex program */
350
glEnable(GL_VERTEX_PROGRAM);
352
/* render something */