e9eaa82d8973e2a1c7c2d62c74e3e9ec99ac7c50
[mesa.git] / docs / MESA_program_debug.spec
1 Name
2
3 MESA_program_debug
4
5 Name Strings
6
7 GL_MESA_program_debug
8
9 Contact
10
11 Brian Paul (brian @ tungstengraphics.com)
12
13 Status
14
15 XXX - Not complete yet!!!
16
17 Version
18
19 Last Modified Date: July 20, 2003
20 Author Revision: 1.0
21 $Date: 2003/07/23 15:45:25 $ $Revision: 1.2 $
22
23 Number
24
25 TBD
26
27 Dependencies
28
29 OpenGL 1.4 is required
30 The extension is written against the OpenGL 1.4 specification.
31 ARB_vertex_program or ARB_fragment_program or NV_vertex_program
32 or NV_fragment_program is required.
33
34 Overview
35
36 The extension provides facilities for implementing debuggers for
37 vertex and fragment programs.
38
39 The concept is that vertex and fragment program debuggers will be
40 implemented outside of the GL as a utility package. This extension
41 only provides the minimal hooks required to implement a debugger.
42
43 There are facilities to do the following:
44 1. Have the GL call a user-specified function prior to executing
45 each vertex or fragment instruction.
46 2. Query the current program string's execution position.
47 3. Query the current values of intermediate program values.
48
49 The main feature is the ProgramCallbackMESA function. It allows the
50 user to register a callback function with the GL. The callback will
51 be called prior to executing each vertex or fragment program instruction.
52
53 From within the callback, the user may issue glGet* commands to
54 query current GL state. The GetProgramRegisterfvMESA function allows
55 current program values to be queried (such as temporaries, input
56 attributes, and result registers).
57
58 There are flags for enabling/disabling the program callbacks.
59
60 The current execution position (as an offset from the start of the
61 program string) can be queried with
62 GetIntegerv(GL_FRAGMENT_PROGRAM_POSITION_MESA, &pos) or
63 GetIntegerv(GL_VERTEX_PROGRAM_POSITION_MESA, &pos).
64
65
66 IP Status
67
68 None
69
70 Issues
71
72 1. Is this the right model for a debugger?
73
74 It seems prudent to minimize the scope of this extension and leave
75 it up to the developer (or developer community) to write (a)
76 debugger(s) that layer on top of this extension.
77
78 If the debugger were fully implemented within the GL it's not
79 clear how terminal and GUI-based interfaces would work, for
80 example.
81
82 2. There aren't any other extensions that register callbacks with
83 the GL. Isn't there another solution?
84
85 If we want to be able to single-step through vertex/fragment
86 programs I don't see another way to do it.
87
88 3. How do we prevent the user from doing something crazy in the
89 callback function, like trying to call glBegin (leading to
90 recursion)?
91
92 The rule is that the callback function can only issue glGet*()
93 functions and no other GL commands. It could be difficult to
94 enforce this, however. Therefore, calling any non-get GL
95 command from within the callback will result in undefined
96 results.
97
98 4. Is this extension amenable to hardware implementation?
99
100 Hopefully, but if not, the GL implementation will have to fall
101 back to a software path when debugging. This may be acceptable
102 for debugging.
103
104 5. What's the <data> parameter to ProgramCallbackMESA for?
105
106 It's a common programming practice to associate a user-supplied
107 value with callback functions.
108
109 6. Debuggers often allow one to modify intermediate program values,
110 then continue. Does this extension support that?
111
112 No.
113
114
115 New Procedures and Functions (and datatypes)
116
117 typedef void (*programcallbackMESA)(enum target, void *data)
118
119 void ProgramCallbackMESA(enum target, programcallbackMESA callback,
120 void *data)
121
122 void GetProgramRegisterfvMESA(enum target, sizei len,
123 const ubyte *registerName, float *v)
124
125 New Tokens
126
127 Accepted by the <cap> parameter of Enable, Disable, IsEnabled,
128 GetBooleanv, GetDoublev, GetFloatv and GetIntegerv:
129
130 FRAGMENT_PROGRAM_CALLBACK_MESA 0x????
131 VERTEX_PROGRAM_CALLBACK_MESA 0x????
132
133 Accepted by the <pname> parameter GetBooleanv, GetDoublev,
134 GetFloatv and GetIntegerv:
135
136 FRAGMENT_PROGRAM_POSITION_MESA 0x????
137 VERTEX_PROGRAM_POSITION_MESA 0x????
138
139 Accepted by the <pname> parameter of GetPointerv:
140
141 FRAGMENT_PROGRAM_CALLBACK_FUNC_MESA 0x????
142 FRAGMENT_PROGRAM_CALLBACK_DATA_MESA 0x????
143 VERTEX_PROGRAM_CALLBACK_FUNC_MESA 0x????
144 VERTEX_PROGRAM_CALLBACK_DATA_MESA 0x????
145
146 Additions to Chapter 2 of the OpenGL 1.4 Specification (OpenGL Operation)
147
148 None.
149
150 Additions to Chapter 3 of the OpenGL 1.4 Specification (Rasterization)
151
152 None.
153
154 Additions to Chapter 4 of the OpenGL 1.4 Specification (Per-Fragment
155 Operations and the Frame Buffer)
156
157 None.
158
159 Additions to Chapter 5 of the OpenGL 1.4 Specification (Special Functions)
160
161 In section 5.4 "Display Lists", page 202, add the following command
162 to the list of those that are not compiled into display lists:
163 ProgramCallbackMESA.
164
165
166 Add a new section 5.7 "Callback Functions"
167
168 The function
169
170 void ProgramCallbackMESA(enum target, programcallbackMESA callback,
171 void *data)
172
173 registers a user-defined callback function with the GL. <target> may
174 be FRAGMENT_PROGRAM_ARB or VERTEX_PROGRAM_ARB. Callbacks registered
175 with these targets will be called prior to executing each instruction
176 in the current fragment or vertex program, respectively. The callbacks
177 are enabled and disabled by calling Enable or Disable with <cap>
178 FRAGMENT_PROGRAM_ARB or VERTEX_PROGRAM_ARB.
179
180 The callback function's signature must match the typedef
181
182 typedef void (*programcallbackMESA)(enum target, void *data)
183
184 When the callback function is called, <target> will either be
185 FRAGMENT_PROGRAM_ARB or VERTEX_PROGRAM_ARB to indicate which
186 program is currently executing and <data> will be the value
187 specified when ProgramCallbackMESA was called.
188
189 From within the callback function, only the following GL commands
190 may be called:
191
192 GetBooleanv
193 GetDoublev
194 GetFloatv
195 GetIntegerv
196 GetProgramLocalParameter
197 GetProgramEnvParameter
198 GetProgramRegisterfvMESA
199 GetProgramivARB
200 GetProgramStringARB
201 GetError
202
203 Calling any other command from within the callback results in
204 undefined behaviour.
205
206
207 Additions to Chapter 6 of the OpenGL 1.4 Specification (State and
208 State Requests)
209
210 Add a new section 6.1.3 "Program Value Queries":
211
212 The command
213
214 void GetProgramRegisterfvMESA(enum target, sizei len,
215 const ubyte *registerName,
216 float *v)
217
218 Is used to query the value of program variables and registers
219 during program execution. GetProgramRegisterMESA may only be
220 called from within a callback function registered with
221 ProgramCallbackMESA.
222
223 <registerName> and <len> specify the string name of a program
224 register (such as "R3"), input attribute (such as "vertex.color"),
225 an output attribute (such as "result.texcoord[0]") or a user-
226 defined identifier. The current value of that variable is
227 returned as four floats in <v>.
228
229
230 Additions to Appendix A of the OpenGL 1.4 Specification (Invariance)
231
232 None.
233
234 Additions to the AGL/GLX/WGL Specifications
235
236 None.
237
238 GLX Protocol
239
240 XXX TBD
241
242 Dependencies on NV_vertex_program and NV_fragment_program
243
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.)
249
250 Errors
251
252 INVALID_OPERATION is generated if ProgramCallbackMESA is called
253 between Begin and End.
254
255 INVALID_ENUM is generated by ProgramCallbackMESA if <target> is not
256 a supported vertex or fragment program type.
257
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.
261
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).
266
267 INVALID_VALUE is generated by GetProgramRegisterfvMESA if <registerName>
268 does not name a known program register or variable.
269
270 INVALID_OPERATION is generated by GetProgramRegisterfvMESA when a
271 register query is attempted for a program target that's not currently
272 being executed.
273
274
275 New State
276
277 XXX finish
278
279 (table 6.N, p. ###)
280 Initial
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 -
291
292 XXX more?
293
294 New Implementation Dependent State
295
296 None.
297
298 Revision History
299
300 8 July 2003
301 Initial draft. (Brian Paul)
302 11 July 2003
303 Second draft. (Brian Paul)
304 20 July 2003
305 Third draft. Lots of fundamental changes. (Brian Paul)
306 23 July 2003
307 Added chapter 5 and 6 spec language. (Brian Paul)
308
309 Example Usage
310
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
313 vertex programs.
314
315
316 /* This is called by the GL when the vertex program is executing.
317 * We can only make glGet* calls from within this function!
318 */
319 void DebugCallback(GLenum target, GLvoid *data)
320 {
321 GLint pos;
322 GLuint i;
323
324 /* Get PC and current instruction string */
325 glGetIntegerv(GL_VERTEX_PROGRAM_POSITION_ARB, &pos);
326
327 printf("Current position: %d\n", pos);
328
329 printf("Current temporary registers:\n");
330 for (i = 0; i < 4; i++) {
331 GLfloat v[4];
332 char s[10];
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]);
336 }
337 }
338
339
340 /*
341 * elsewhere...
342 */
343
344 /* Register our debugger callback function */
345 glProgramCallbackMESA(GL_VERTEX_PROGRAM_ARB, DebugCallback, NULL);
346 glEnable(GL_VERTEX_PROGRAM_CALLBACK_MESA);
347
348 /* define/bind a vertex program */
349
350 glEnable(GL_VERTEX_PROGRAM);
351
352 /* render something */
353 glBegin(GL_POINTS);
354 glVertex2f(0, 0);
355 glEnd();
356