MESA_program_debug.spec revision 2848b55ed5cfa3afc00937baa967fd7765fc5613
1Name
2
3    MESA_program_debug
4
5Name Strings
6
7    GL_MESA_program_debug
8
9Contact
10
11    Brian Paul (brian.paul 'at' tungstengraphics.com)
12
13Status
14
15    XXX - Not complete yet!!!
16
17Version
18
19    Last Modified Date: July 20, 2003
20    Author Revision: 1.0
21    $Date: 2004/03/25 01:42:41 $ $Revision: 1.4 $
22
23Number
24
25    TBD
26
27Dependencies
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
34Overview
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 Get* 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
66IP Status
67
68    None
69
70Issues
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 debuggers
76       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
115New 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
125New Tokens
126
127    Accepted by the <cap> parameter of Enable, Disable, IsEnabled,
128    GetBooleanv, GetDoublev, GetFloatv and GetIntegerv:
129
130        FRAGMENT_PROGRAM_CALLBACK_MESA      0x8bb1
131        VERTEX_PROGRAM_CALLBACK_MESA        0x8bb4
132
133    Accepted by the <pname> parameter GetBooleanv, GetDoublev,
134    GetFloatv and GetIntegerv:
135
136        FRAGMENT_PROGRAM_POSITION_MESA      0x8bb0
137        VERTEX_PROGRAM_POSITION_MESA        0x8bb4
138
139    Accepted by the <pname> parameter of GetPointerv:
140
141        FRAGMENT_PROGRAM_CALLBACK_FUNC_MESA 0x8bb2
142        FRAGMENT_PROGRAM_CALLBACK_DATA_MESA 0x8bb3
143        VERTEX_PROGRAM_CALLBACK_FUNC_MESA   0x8bb6
144        VERTEX_PROGRAM_CALLBACK_DATA_MESA   0x8bb7
145
146Additions to Chapter 2 of the OpenGL 1.4 Specification (OpenGL Operation)
147
148    None.
149
150Additions to Chapter 3 of the OpenGL 1.4 Specification (Rasterization)
151
152    None.
153
154Additions to Chapter 4 of the OpenGL 1.4 Specification (Per-Fragment
155Operations and the Frame Buffer)
156
157    None.
158
159Additions 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
164        ProgramCallbackMESA.
165
166
167    Add a new section 5.7 "Callback Functions"
168
169    The function
170
171        void ProgramCallbackMESA(enum target, programcallbackMESA callback,
172                                 void *data)
173
174    registers a user-defined callback function with the GL.  <target>
175    may be FRAGMENT_PROGRAM_ARB or VERTEX_PROGRAM_ARB.  The enabled
176    callback functions registered with these targets will be called
177    prior to executing each instruction in the current fragment or
178    vertex program, respectively.  The callbacks are enabled and
179    disabled by calling Enable or Disable with <cap>
180    FRAGMENT_PROGRAM_ARB or VERTEX_PROGRAM_ARB.
181
182    The callback function's signature must match the typedef
183
184        typedef void (*programcallbackMESA)(enum target, void *data)
185
186    When the callback function is called, <target> will either be
187    FRAGMENT_PROGRAM_ARB or VERTEX_PROGRAM_ARB to indicate which
188    program is currently executing and <data> will be the value
189    specified when ProgramCallbackMESA was called.
190
191    From within the callback function, only the following GL commands
192    may be called:
193
194        GetBooleanv
195        GetDoublev
196        GetFloatv
197        GetIntegerv
198        GetProgramLocalParameter
199        GetProgramEnvParameter
200        GetProgramRegisterfvMESA
201        GetProgramivARB
202        GetProgramStringARB
203        GetError
204
205    Calling any other command from within the callback results in
206    undefined behaviour.
207
208
209Additions to Chapter 6 of the OpenGL 1.4 Specification (State and
210State Requests)
211
212    Add a new section 6.1.3 "Program Value Queries":
213
214    The command
215
216        void GetProgramRegisterfvMESA(enum target, sizei len,
217                                      const ubyte *registerName,
218                                      float *v)
219        
220    Is used to query the value of program variables and registers
221    during program execution.  GetProgramRegisterfvMESA may only be
222    called from within a callback function registered with
223    ProgramCallbackMESA.
224
225    <registerName> and <len> specify the name a variable, input
226    attribute, temporary, or result register in the program string.
227    The current value of the named variable is returned as four
228    values in <v>.  If <name> doesn't exist in the program string,
229    the error INVALID_OPERATION is generated.
230
231Additions to Appendix A of the OpenGL 1.4 Specification (Invariance)
232
233    None.
234
235Additions to the AGL/GLX/WGL Specifications
236
237    None.
238
239GLX Protocol
240
241    XXX TBD
242
243Dependencies on NV_vertex_program and NV_fragment_program
244
245    If NV_vertex_program and/or NV_fragment_program are supported,
246    vertex and/or fragment programs defined by those extensions may
247    be debugged as well.  Register queries will use the syntax used
248    by those extensions (i.e. "v[X]" to query vertex attributes,
249    "o[X]" for vertex outputs, etc.)
250
251Errors
252
253    INVALID_OPERATION is generated if ProgramCallbackMESA is called
254    between Begin and End.
255
256    INVALID_ENUM is generated by ProgramCallbackMESA if <target> is not
257    a supported vertex or fragment program type.
258
259    Note: INVALID_OPERAION IS NOT generated by GetProgramRegisterfvMESA,
260    GetBooleanv, GetDoublev, GetFloatv, or GetIntegerv if called between
261    Begin and End when a vertex or fragment program is currently executing.
262
263    INVALID_ENUM is generated by ProgramCallbackMESA,
264    GetProgramRegisterfvMESA if <target> is not a program target supported
265    by ARB_vertex_program, ARB_fragment_program (or NV_vertex_program or
266    NV_fragment_program).
267
268    INVALID_VALUE is generated by GetProgramRegisterfvMESA if <registerName>
269    does not name a known program register or variable.
270
271    INVALID_OPERATION is generated by GetProgramRegisterfvMESA when a
272    register query is attempted for a program target that's not currently
273    being executed.
274
275
276New State
277
278    XXX finish
279
280(table 6.N, p. ###)
281                                                            Initial
282    Get Value                            Type Get Command   Value    Description  Sec.  Attribute
283    ---------                            ---- -----------   -----    -----------  ----  ---------
284    FRAGMENT_PROGRAM_CALLBACK_MESA        B   IsEnabled     FALSE    XXX          XXX   enable
285    VERTEX_PROGRAM_CALLBACK_MESA          B   IsEnabled     FALSE    XXX          XXX   enable
286    FRAGMENT_PROGRAM_POSITION_MESA        Z+  GetIntegerv   -1       XXX          XXX   -
287    VERTEX_PROGRAM_POSITION_MESA          Z+  GetIntegerv   -1       XXX          XXX   -
288    FRAGMENT_PROGRAM_CALLBACK_FUNC_MESA   P   GetPointerv   NULL     XXX          XXX   -
289    VERTEX_PROGRAM_CALLBACK_FUNC_MESA     P   GetPointerv   NULL     XXX          XXX   -
290    FRAGMENT_PROGRAM_CALLBACK_DATA_MESA   P   GetPointerv   NULL     XXX          XXX   -
291    VERTEX_PROGRAM_CALLBACK_DATA_MESA     P   GetPointerv   NULL     XXX          XXX   -
292
293    XXX more?
294
295New Implementation Dependent State
296
297    None.
298
299Revision History
300
301    8 July 2003
302        Initial draft. (Brian Paul)
303    11 July 2003
304        Second draft. (Brian Paul)
305    20 July 2003
306        Third draft.  Lots of fundamental changes. (Brian Paul)
307    23 July 2003
308        Added chapter 5 and 6 spec language. (Brian Paul)
309
310Example Usage
311
312   The following is a very simple example of how this extension may
313   be used to print the values of R0, R1, R2 and R3 while executing
314   vertex programs.
315
316
317    /* This is called by the GL when the vertex program is executing.
318     * We can only make glGet* calls from within this function!
319     */
320    void DebugCallback(GLenum target, GLvoid *data)
321    {
322       GLint pos;
323       GLuint i;
324
325       /* Get PC and current instruction string */
326       glGetIntegerv(GL_VERTEX_PROGRAM_POSITION_ARB, &pos);
327
328       printf("Current position: %d\n", pos);
329
330       printf("Current temporary registers:\n");
331       for (i = 0; i < 4; i++) {
332	  GLfloat v[4];
333	  char s[10];
334	  sprintf(s, "R%d", i);
335	  glGetProgramRegisterfvMESA(GL_VERTEX_PROGRAM_ARB, strlen(s), s, v);
336	  printf("R%d = %g, %g, %g, %g\n", i, v[0], v[1], v[2], v[3]);
337       }
338    }
339
340
341    /*
342     * elsewhere...
343     */
344
345    /* Register our debugger callback function */
346    glProgramCallbackMESA(GL_VERTEX_PROGRAM_ARB, DebugCallback, NULL);
347    glEnable(GL_VERTEX_PROGRAM_CALLBACK_MESA);
348
349    /* define/bind a vertex program */
350
351    glEnable(GL_VERTEX_PROGRAM);
352
353    /* render something */
354    glBegin(GL_POINTS);
355    glVertex2f(0, 0);
356    glEnd();
357
358