Home | History | Annotate | Download | only in OLD
      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.paul 'at' 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 
     22 Number
     23 
     24     TBD
     25 
     26 Dependencies
     27 
     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.
     32 
     33 Overview
     34 
     35     The extension provides facilities for implementing debuggers for
     36     vertex and fragment programs.
     37 
     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.
     41 
     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.
     47 
     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.
     51 
     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).
     56 
     57     There are flags for enabling/disabling the program callbacks.
     58 
     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).
     63 
     64 
     65 IP Status
     66 
     67     None
     68 
     69 Issues
     70 
     71     1. Is this the right model for a debugger?
     72 
     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.
     76 
     77        If the debugger were fully implemented within the GL it's not
     78        clear how terminal and GUI-based interfaces would work, for
     79        example.
     80 
     81     2. There aren't any other extensions that register callbacks with
     82        the GL.  Isn't there another solution?
     83 
     84        If we want to be able to single-step through vertex/fragment
     85        programs I don't see another way to do it.
     86 
     87     3. How do we prevent the user from doing something crazy in the
     88        callback function, like trying to call glBegin (leading to
     89        recursion)?
     90 
     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
     95        results.    
     96 
     97     4. Is this extension amenable to hardware implementation?
     98 
     99        Hopefully, but if not, the GL implementation will have to fall
    100        back to a software path when debugging.  This may be acceptable
    101        for debugging.
    102 
    103     5. What's the <data> parameter to ProgramCallbackMESA for?
    104 
    105        It's a common programming practice to associate a user-supplied
    106        value with callback functions.
    107 
    108     6. Debuggers often allow one to modify intermediate program values,
    109        then continue.  Does this extension support that?
    110 
    111        No.
    112 
    113 
    114 New Procedures and Functions (and datatypes)
    115 
    116     typedef void (*programcallbackMESA)(enum target, void *data)
    117 
    118     void ProgramCallbackMESA(enum target, programcallbackMESA callback,
    119                              void *data)
    120 
    121     void GetProgramRegisterfvMESA(enum target, sizei len,
    122                                   const ubyte *registerName, float *v)
    123 
    124 New Tokens
    125 
    126     Accepted by the <cap> parameter of Enable, Disable, IsEnabled,
    127     GetBooleanv, GetDoublev, GetFloatv and GetIntegerv:
    128 
    129         FRAGMENT_PROGRAM_CALLBACK_MESA      0x8bb1
    130         VERTEX_PROGRAM_CALLBACK_MESA        0x8bb4
    131 
    132     Accepted by the <pname> parameter GetBooleanv, GetDoublev,
    133     GetFloatv and GetIntegerv:
    134 
    135         FRAGMENT_PROGRAM_POSITION_MESA      0x8bb0
    136         VERTEX_PROGRAM_POSITION_MESA        0x8bb4
    137 
    138     Accepted by the <pname> parameter of GetPointerv:
    139 
    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
    144 
    145 Additions to Chapter 2 of the OpenGL 1.4 Specification (OpenGL Operation)
    146 
    147     None.
    148 
    149 Additions to Chapter 3 of the OpenGL 1.4 Specification (Rasterization)
    150 
    151     None.
    152 
    153 Additions to Chapter 4 of the OpenGL 1.4 Specification (Per-Fragment
    154 Operations and the Frame Buffer)
    155 
    156     None.
    157 
    158 Additions to Chapter 5 of the OpenGL 1.4 Specification (Special Functions)
    159 
    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:
    162 
    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>
    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.
    180 
    181     The callback function's signature must match the typedef
    182 
    183         typedef void (*programcallbackMESA)(enum target, void *data)
    184 
    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.
    189 
    190     From within the callback function, only the following GL commands
    191     may be called:
    192 
    193         GetBooleanv
    194         GetDoublev
    195         GetFloatv
    196         GetIntegerv
    197         GetProgramLocalParameter
    198         GetProgramEnvParameter
    199         GetProgramRegisterfvMESA
    200         GetProgramivARB
    201         GetProgramStringARB
    202         GetError
    203 
    204     Calling any other command from within the callback results in
    205     undefined behaviour.
    206 
    207 
    208 Additions to Chapter 6 of the OpenGL 1.4 Specification (State and
    209 State Requests)
    210 
    211     Add a new section 6.1.3 "Program Value Queries":
    212 
    213     The command
    214 
    215         void GetProgramRegisterfvMESA(enum target, sizei len,
    216                                       const ubyte *registerName,
    217                                       float *v)
    218         
    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
    222     ProgramCallbackMESA.
    223 
    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.
    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 
    357