1848b8605SmrgName
2848b8605Smrg
3848b8605Smrg    MESA_program_debug
4848b8605Smrg
5848b8605SmrgName Strings
6848b8605Smrg
7848b8605Smrg    GL_MESA_program_debug
8848b8605Smrg
9848b8605SmrgContact
10848b8605Smrg
11848b8605Smrg    Brian Paul (brian.paul 'at' tungstengraphics.com)
12848b8605Smrg
13848b8605SmrgStatus
14848b8605Smrg
15b8e80941Smrg    Obsolete.
16848b8605Smrg
17848b8605SmrgVersion
18848b8605Smrg
19848b8605Smrg    Last Modified Date: July 20, 2003
20848b8605Smrg    Author Revision: 1.0
21848b8605Smrg
22848b8605SmrgNumber
23848b8605Smrg
24848b8605Smrg    TBD
25848b8605Smrg
26848b8605SmrgDependencies
27848b8605Smrg
28848b8605Smrg    OpenGL 1.4 is required
29848b8605Smrg    The extension is written against the OpenGL 1.4 specification.
30848b8605Smrg    ARB_vertex_program or ARB_fragment_program or NV_vertex_program
31848b8605Smrg    or NV_fragment_program is required.
32848b8605Smrg
33848b8605SmrgOverview
34848b8605Smrg
35848b8605Smrg    The extension provides facilities for implementing debuggers for
36848b8605Smrg    vertex and fragment programs.
37848b8605Smrg
38848b8605Smrg    The concept is that vertex and fragment program debuggers will be
39848b8605Smrg    implemented outside of the GL as a utility package.  This extension
40848b8605Smrg    only provides the minimal hooks required to implement a debugger.
41848b8605Smrg
42848b8605Smrg    There are facilities to do the following:
43848b8605Smrg    1. Have the GL call a user-specified function prior to executing
44848b8605Smrg       each vertex or fragment instruction.
45848b8605Smrg    2. Query the current program string's execution position.
46848b8605Smrg    3. Query the current values of intermediate program values.
47848b8605Smrg
48848b8605Smrg    The main feature is the ProgramCallbackMESA function.  It allows the
49848b8605Smrg    user to register a callback function with the GL.  The callback will
50848b8605Smrg    be called prior to executing each vertex or fragment program instruction.
51848b8605Smrg
52848b8605Smrg    From within the callback, the user may issue Get* commands to
53848b8605Smrg    query current GL state.  The GetProgramRegisterfvMESA function allows
54848b8605Smrg    current program values to be queried (such as temporaries, input
55848b8605Smrg    attributes, and result registers).
56848b8605Smrg
57848b8605Smrg    There are flags for enabling/disabling the program callbacks.
58848b8605Smrg
59848b8605Smrg    The current execution position (as an offset from the start of the
60848b8605Smrg    program string) can be queried with
61848b8605Smrg    GetIntegerv(GL_FRAGMENT_PROGRAM_POSITION_MESA, &pos) or
62848b8605Smrg    GetIntegerv(GL_VERTEX_PROGRAM_POSITION_MESA, &pos).
63848b8605Smrg
64848b8605Smrg
65848b8605SmrgIP Status
66848b8605Smrg
67848b8605Smrg    None
68848b8605Smrg
69848b8605SmrgIssues
70848b8605Smrg
71848b8605Smrg    1. Is this the right model for a debugger?
72848b8605Smrg
73848b8605Smrg       It seems prudent to minimize the scope of this extension and leave
74848b8605Smrg       it up to the developer (or developer community) to write debuggers
75848b8605Smrg       that layer on top of this extension.
76848b8605Smrg
77848b8605Smrg       If the debugger were fully implemented within the GL it's not
78848b8605Smrg       clear how terminal and GUI-based interfaces would work, for
79848b8605Smrg       example.
80848b8605Smrg
81848b8605Smrg    2. There aren't any other extensions that register callbacks with
82848b8605Smrg       the GL.  Isn't there another solution?
83848b8605Smrg
84848b8605Smrg       If we want to be able to single-step through vertex/fragment
85848b8605Smrg       programs I don't see another way to do it.
86848b8605Smrg
87848b8605Smrg    3. How do we prevent the user from doing something crazy in the
88848b8605Smrg       callback function, like trying to call glBegin (leading to
89848b8605Smrg       recursion)?
90848b8605Smrg
91848b8605Smrg       The rule is that the callback function can only issue glGet*()
92848b8605Smrg       functions and no other GL commands.  It could be difficult to
93848b8605Smrg       enforce this, however.  Therefore, calling any non-get GL
94848b8605Smrg       command from within the callback will result in undefined
95848b8605Smrg       results.    
96848b8605Smrg
97848b8605Smrg    4. Is this extension amenable to hardware implementation?
98848b8605Smrg
99848b8605Smrg       Hopefully, but if not, the GL implementation will have to fall
100848b8605Smrg       back to a software path when debugging.  This may be acceptable
101848b8605Smrg       for debugging.
102848b8605Smrg
103848b8605Smrg    5. What's the <data> parameter to ProgramCallbackMESA for?
104848b8605Smrg
105848b8605Smrg       It's a common programming practice to associate a user-supplied
106848b8605Smrg       value with callback functions.
107848b8605Smrg
108848b8605Smrg    6. Debuggers often allow one to modify intermediate program values,
109848b8605Smrg       then continue.  Does this extension support that?
110848b8605Smrg
111848b8605Smrg       No.
112848b8605Smrg
113848b8605Smrg
114848b8605SmrgNew Procedures and Functions (and datatypes)
115848b8605Smrg
116848b8605Smrg    typedef void (*programcallbackMESA)(enum target, void *data)
117848b8605Smrg
118848b8605Smrg    void ProgramCallbackMESA(enum target, programcallbackMESA callback,
119848b8605Smrg                             void *data)
120848b8605Smrg
121848b8605Smrg    void GetProgramRegisterfvMESA(enum target, sizei len,
122848b8605Smrg                                  const ubyte *registerName, float *v)
123848b8605Smrg
124848b8605SmrgNew Tokens
125848b8605Smrg
126848b8605Smrg    Accepted by the <cap> parameter of Enable, Disable, IsEnabled,
127848b8605Smrg    GetBooleanv, GetDoublev, GetFloatv and GetIntegerv:
128848b8605Smrg
129848b8605Smrg        FRAGMENT_PROGRAM_CALLBACK_MESA      0x8bb1
130848b8605Smrg        VERTEX_PROGRAM_CALLBACK_MESA        0x8bb4
131848b8605Smrg
132848b8605Smrg    Accepted by the <pname> parameter GetBooleanv, GetDoublev,
133848b8605Smrg    GetFloatv and GetIntegerv:
134848b8605Smrg
135848b8605Smrg        FRAGMENT_PROGRAM_POSITION_MESA      0x8bb0
136b8e80941Smrg        VERTEX_PROGRAM_POSITION_MESA        0x8bb5
137848b8605Smrg
138848b8605Smrg    Accepted by the <pname> parameter of GetPointerv:
139848b8605Smrg
140848b8605Smrg        FRAGMENT_PROGRAM_CALLBACK_FUNC_MESA 0x8bb2
141848b8605Smrg        FRAGMENT_PROGRAM_CALLBACK_DATA_MESA 0x8bb3
142848b8605Smrg        VERTEX_PROGRAM_CALLBACK_FUNC_MESA   0x8bb6
143848b8605Smrg        VERTEX_PROGRAM_CALLBACK_DATA_MESA   0x8bb7
144848b8605Smrg
145848b8605SmrgAdditions to Chapter 2 of the OpenGL 1.4 Specification (OpenGL Operation)
146848b8605Smrg
147848b8605Smrg    None.
148848b8605Smrg
149848b8605SmrgAdditions to Chapter 3 of the OpenGL 1.4 Specification (Rasterization)
150848b8605Smrg
151848b8605Smrg    None.
152848b8605Smrg
153848b8605SmrgAdditions to Chapter 4 of the OpenGL 1.4 Specification (Per-Fragment
154848b8605SmrgOperations and the Frame Buffer)
155848b8605Smrg
156848b8605Smrg    None.
157848b8605Smrg
158848b8605SmrgAdditions to Chapter 5 of the OpenGL 1.4 Specification (Special Functions)
159848b8605Smrg
160848b8605Smrg    In section 5.4 "Display Lists", page 202, add the following command
161848b8605Smrg    to the list of those that are not compiled into display lists:
162848b8605Smrg
163848b8605Smrg        ProgramCallbackMESA.
164848b8605Smrg
165848b8605Smrg
166848b8605Smrg    Add a new section 5.7 "Callback Functions"
167848b8605Smrg
168848b8605Smrg    The function
169848b8605Smrg
170848b8605Smrg        void ProgramCallbackMESA(enum target, programcallbackMESA callback,
171848b8605Smrg                                 void *data)
172848b8605Smrg
173848b8605Smrg    registers a user-defined callback function with the GL.  <target>
174848b8605Smrg    may be FRAGMENT_PROGRAM_ARB or VERTEX_PROGRAM_ARB.  The enabled
175848b8605Smrg    callback functions registered with these targets will be called
176848b8605Smrg    prior to executing each instruction in the current fragment or
177848b8605Smrg    vertex program, respectively.  The callbacks are enabled and
178848b8605Smrg    disabled by calling Enable or Disable with <cap>
179848b8605Smrg    FRAGMENT_PROGRAM_ARB or VERTEX_PROGRAM_ARB.
180848b8605Smrg
181848b8605Smrg    The callback function's signature must match the typedef
182848b8605Smrg
183848b8605Smrg        typedef void (*programcallbackMESA)(enum target, void *data)
184848b8605Smrg
185848b8605Smrg    When the callback function is called, <target> will either be
186848b8605Smrg    FRAGMENT_PROGRAM_ARB or VERTEX_PROGRAM_ARB to indicate which
187848b8605Smrg    program is currently executing and <data> will be the value
188848b8605Smrg    specified when ProgramCallbackMESA was called.
189848b8605Smrg
190848b8605Smrg    From within the callback function, only the following GL commands
191848b8605Smrg    may be called:
192848b8605Smrg
193848b8605Smrg        GetBooleanv
194848b8605Smrg        GetDoublev
195848b8605Smrg        GetFloatv
196848b8605Smrg        GetIntegerv
197848b8605Smrg        GetProgramLocalParameter
198848b8605Smrg        GetProgramEnvParameter
199848b8605Smrg        GetProgramRegisterfvMESA
200848b8605Smrg        GetProgramivARB
201848b8605Smrg        GetProgramStringARB
202848b8605Smrg        GetError
203848b8605Smrg
204848b8605Smrg    Calling any other command from within the callback results in
205848b8605Smrg    undefined behaviour.
206848b8605Smrg
207848b8605Smrg
208848b8605SmrgAdditions to Chapter 6 of the OpenGL 1.4 Specification (State and
209848b8605SmrgState Requests)
210848b8605Smrg
211848b8605Smrg    Add a new section 6.1.3 "Program Value Queries":
212848b8605Smrg
213848b8605Smrg    The command
214848b8605Smrg
215848b8605Smrg        void GetProgramRegisterfvMESA(enum target, sizei len,
216848b8605Smrg                                      const ubyte *registerName,
217848b8605Smrg                                      float *v)
218848b8605Smrg        
219848b8605Smrg    Is used to query the value of program variables and registers
220848b8605Smrg    during program execution.  GetProgramRegisterfvMESA may only be
221848b8605Smrg    called from within a callback function registered with
222848b8605Smrg    ProgramCallbackMESA.
223848b8605Smrg
224848b8605Smrg    <registerName> and <len> specify the name a variable, input
225848b8605Smrg    attribute, temporary, or result register in the program string.
226848b8605Smrg    The current value of the named variable is returned as four
227848b8605Smrg    values in <v>.  If <name> doesn't exist in the program string,
228848b8605Smrg    the error INVALID_OPERATION is generated.
229848b8605Smrg
230848b8605SmrgAdditions to Appendix A of the OpenGL 1.4 Specification (Invariance)
231848b8605Smrg
232848b8605Smrg    None.
233848b8605Smrg
234848b8605SmrgAdditions to the AGL/GLX/WGL Specifications
235848b8605Smrg
236848b8605Smrg    None.
237848b8605Smrg
238848b8605SmrgGLX Protocol
239848b8605Smrg
240848b8605Smrg    XXX TBD
241848b8605Smrg
242848b8605SmrgDependencies on NV_vertex_program and NV_fragment_program
243848b8605Smrg
244848b8605Smrg    If NV_vertex_program and/or NV_fragment_program are supported,
245848b8605Smrg    vertex and/or fragment programs defined by those extensions may
246848b8605Smrg    be debugged as well.  Register queries will use the syntax used
247848b8605Smrg    by those extensions (i.e. "v[X]" to query vertex attributes,
248848b8605Smrg    "o[X]" for vertex outputs, etc.)
249848b8605Smrg
250848b8605SmrgErrors
251848b8605Smrg
252848b8605Smrg    INVALID_OPERATION is generated if ProgramCallbackMESA is called
253848b8605Smrg    between Begin and End.
254848b8605Smrg
255848b8605Smrg    INVALID_ENUM is generated by ProgramCallbackMESA if <target> is not
256848b8605Smrg    a supported vertex or fragment program type.
257848b8605Smrg
258848b8605Smrg    Note: INVALID_OPERAION IS NOT generated by GetProgramRegisterfvMESA,
259848b8605Smrg    GetBooleanv, GetDoublev, GetFloatv, or GetIntegerv if called between
260848b8605Smrg    Begin and End when a vertex or fragment program is currently executing.
261848b8605Smrg
262848b8605Smrg    INVALID_ENUM is generated by ProgramCallbackMESA,
263848b8605Smrg    GetProgramRegisterfvMESA if <target> is not a program target supported
264848b8605Smrg    by ARB_vertex_program, ARB_fragment_program (or NV_vertex_program or
265848b8605Smrg    NV_fragment_program).
266848b8605Smrg
267848b8605Smrg    INVALID_VALUE is generated by GetProgramRegisterfvMESA if <registerName>
268848b8605Smrg    does not name a known program register or variable.
269848b8605Smrg
270848b8605Smrg    INVALID_OPERATION is generated by GetProgramRegisterfvMESA when a
271848b8605Smrg    register query is attempted for a program target that's not currently
272848b8605Smrg    being executed.
273848b8605Smrg
274848b8605Smrg
275848b8605SmrgNew State
276848b8605Smrg
277848b8605Smrg    XXX finish
278848b8605Smrg
279848b8605Smrg(table 6.N, p. ###)
280848b8605Smrg                                                            Initial
281848b8605Smrg    Get Value                            Type Get Command   Value    Description  Sec.  Attribute
282848b8605Smrg    ---------                            ---- -----------   -----    -----------  ----  ---------
283848b8605Smrg    FRAGMENT_PROGRAM_CALLBACK_MESA        B   IsEnabled     FALSE    XXX          XXX   enable
284848b8605Smrg    VERTEX_PROGRAM_CALLBACK_MESA          B   IsEnabled     FALSE    XXX          XXX   enable
285848b8605Smrg    FRAGMENT_PROGRAM_POSITION_MESA        Z+  GetIntegerv   -1       XXX          XXX   -
286848b8605Smrg    VERTEX_PROGRAM_POSITION_MESA          Z+  GetIntegerv   -1       XXX          XXX   -
287848b8605Smrg    FRAGMENT_PROGRAM_CALLBACK_FUNC_MESA   P   GetPointerv   NULL     XXX          XXX   -
288848b8605Smrg    VERTEX_PROGRAM_CALLBACK_FUNC_MESA     P   GetPointerv   NULL     XXX          XXX   -
289848b8605Smrg    FRAGMENT_PROGRAM_CALLBACK_DATA_MESA   P   GetPointerv   NULL     XXX          XXX   -
290848b8605Smrg    VERTEX_PROGRAM_CALLBACK_DATA_MESA     P   GetPointerv   NULL     XXX          XXX   -
291848b8605Smrg
292848b8605Smrg    XXX more?
293848b8605Smrg
294848b8605SmrgNew Implementation Dependent State
295848b8605Smrg
296848b8605Smrg    None.
297848b8605Smrg
298848b8605SmrgRevision History
299848b8605Smrg
300848b8605Smrg    8 July 2003
301848b8605Smrg        Initial draft. (Brian Paul)
302848b8605Smrg    11 July 2003
303848b8605Smrg        Second draft. (Brian Paul)
304848b8605Smrg    20 July 2003
305848b8605Smrg        Third draft.  Lots of fundamental changes. (Brian Paul)
306848b8605Smrg    23 July 2003
307848b8605Smrg        Added chapter 5 and 6 spec language. (Brian Paul)
308848b8605Smrg
309848b8605SmrgExample Usage
310848b8605Smrg
311848b8605Smrg   The following is a very simple example of how this extension may
312848b8605Smrg   be used to print the values of R0, R1, R2 and R3 while executing
313848b8605Smrg   vertex programs.
314848b8605Smrg
315848b8605Smrg
316848b8605Smrg    /* This is called by the GL when the vertex program is executing.
317848b8605Smrg     * We can only make glGet* calls from within this function!
318848b8605Smrg     */
319848b8605Smrg    void DebugCallback(GLenum target, GLvoid *data)
320848b8605Smrg    {
321848b8605Smrg       GLint pos;
322848b8605Smrg       GLuint i;
323848b8605Smrg
324848b8605Smrg       /* Get PC and current instruction string */
325848b8605Smrg       glGetIntegerv(GL_VERTEX_PROGRAM_POSITION_ARB, &pos);
326848b8605Smrg
327848b8605Smrg       printf("Current position: %d\n", pos);
328848b8605Smrg
329848b8605Smrg       printf("Current temporary registers:\n");
330848b8605Smrg       for (i = 0; i < 4; i++) {
331848b8605Smrg	  GLfloat v[4];
332848b8605Smrg	  char s[10];
333848b8605Smrg	  sprintf(s, "R%d", i);
334848b8605Smrg	  glGetProgramRegisterfvMESA(GL_VERTEX_PROGRAM_ARB, strlen(s), s, v);
335848b8605Smrg	  printf("R%d = %g, %g, %g, %g\n", i, v[0], v[1], v[2], v[3]);
336848b8605Smrg       }
337848b8605Smrg    }
338848b8605Smrg
339848b8605Smrg
340848b8605Smrg    /*
341848b8605Smrg     * elsewhere...
342848b8605Smrg     */
343848b8605Smrg
344848b8605Smrg    /* Register our debugger callback function */
345848b8605Smrg    glProgramCallbackMESA(GL_VERTEX_PROGRAM_ARB, DebugCallback, NULL);
346848b8605Smrg    glEnable(GL_VERTEX_PROGRAM_CALLBACK_MESA);
347848b8605Smrg
348848b8605Smrg    /* define/bind a vertex program */
349848b8605Smrg
350848b8605Smrg    glEnable(GL_VERTEX_PROGRAM);
351848b8605Smrg
352848b8605Smrg    /* render something */
353848b8605Smrg    glBegin(GL_POINTS);
354848b8605Smrg    glVertex2f(0, 0);
355848b8605Smrg    glEnd();
356848b8605Smrg
357