Before I just launch into this, I will explain some of the motivation and
(brief) history that led to this document.  

As near as I can tell, the GLX side of DRI has stagnated.  I seems as though
we are approaching a critical mass to make some real improvements in that
area.  Brian and I have had some discussions (both on and off the list)
about adding an extension handling mechanism for GLX that mirrors the
mechanism for regular GL.  Some improvements in that area have already been
committed to the mesa4.1 branch, and they will soon (this weekend?) be merged
into the trunk.

The first change is a new function to query the version of the internal
(i.e., driver to libGL.so) GLX API.  Drivers can use this function to
determine if certain data fields and functions are present in GLX.  Drivers
can then expose enhanced functionality with new enough versions of libGL and
fallback with old versions.  The __glXGetInternalVersion function returns
the version, which is currently a date, as an unsigned integer.  Later, a
function called driCompareGLXAPIVersion will be added to determine if the
current API version is new enough.  This will help drivers handle the case
where libGL is so old that it does not support the __glXGetInternalVersion
function.

The other change was to add private GLX functions that reside in libGL.so to
the table used by glXGetProcAddress.  This allows drivers to avoid the
burden of using dlsym (see the end of lib/GL/mesa/src/drv/r200/r200_screen.c
in the trunk).  They can simply call glXGetProcAddress to get pointers to
functions that may only exist in new versions of libGL.so.
__glXGetInternalVersion is a good example of such a function.

As soon as these changes find their way into the trunk, I will merge them
into the texmem-0-0-1 branch.  I suspect that merging the mesa4.1 merged
trunk into the texmem branch will be very "exciting" work. :)  Good thing
for me that next week is a holiday week...

This sets the stage for drivers to enable or disable GLX extensions in a
clean manner, compatible (forward and backward) manner.  I believe that this
is important for our open source driver work and DRI in general for three
big reasons.  This is why I am very interested in getting this stuff done.

1. We've fallen behind.  There are other vendors of closed-source drivers on
Linux that don't use DRI that have a significant GLX feature advantage.
There is quite a bit of functionality, both the stuff I have listed below
and more, that our open source drivers just flat don't support.

2. Device independence.  Pretty much any GLX extension that requires new
entry points could be implemented the same way that
GLX_NV_VERTEX_ARRAY_RANGE is implemented in the R200 driver (see the bottom
of lib/GL/mesa/src/drv/r200/r200_screen.c).  The problem with that is that
most of the code would be the same or nearly the same for every single
driver.  I've spent enough time refactoring duplicated code in the DRI code
base to know better than to fall into that trap!  Not only that, adding the
extensions in this way would prevent libGL from being used to do indirect
rendering on a remote system (app running on x86 Linux, rendering on MIPS
SGI, for example) that did support the extensions.

3. Closed source drivers that use DRI.  Quite a bit of this functionality is
or could be supported by those few IHVs that actually use DRI for their
close source drivers.  The problem is that they have to supply their own
libGL.  That just causes problems for everyone.  I realize that supporting
closed source drivers is pretty low on most people's priority list, but
doing something to help both open and closed source drivers just gives me
that warm, fuzzy, win-win feeling. :)

I've done some sizing on these changes, and I think that I can handle most
of the device independent parts.  I've already written code to handle
enabling and disabling of extensions.  After I merge in Brian's changes to
the texmem branch, I will commit these changes to the branch.  I've also
made the changes to the R100 driver to support the GLX_SGI_swap_control (and
the "MESA" version, see below).  On some of the remaining extensions I've
notes about whether or not I can reasonably make the changes.  On some of
them I've even noted that a "newbie" could probably make the changes.

The rest of this document is basically broken into two sections.  The first
section lists the changes I propose be made to the internal GLX API.  With
three exceptions, all of the changes are to the __DRI*Rec structures.  The
second section is a list of GLX extensions (or 1.3 features) that could be
supported for direct rendering with these changes.  For a lot of the
extension functions there is a direct or almost direct mapping to added
functions or data in the internal API.  For a couple of the other functions,
I've included some of my notes on how the function could be implemented.
The last section is some commentary about some extensions that aren't
covered by this document.

Links to all of the relevant specs are listed at the bottom.

Note on some silly acronyms:

The MSC, SBC, and UST acronyms all come from the OML_sync_control spec.
Rather than just refer people to that spec, I have defined the acronyms
here.

MSC is the number of vertical refreshes that have occurred since some point
in time.  This will typically be tracked by the DRM (kernel) part of the DRI
driver.  Unlike on IRIX, there is no requirement (or ability) to reset this
counter.

SBC is the number of buffer swaps that have occurred for a given GLXDrawable.

UST is the "unadjusted system time."  For the purposes of DRI, this should
be the number of milliseconds since epoch.  The function ftime can be used
to derive this value.  This is device (driver) independent.

===========================
CHANGES TO THE INTERNAL API
===========================

New device-independent entry points / data:

int __glXGetUST( int64_t * ust );

In __GLXcontextRec:

GLXDrawable  currentReadDrawable;


New device-dependent entry points / data:

In __DRIdisplayRec:

unsigned int maxSwapBarriers;

In __DRIdrawableRec:

int64_t (*swapBuffersMSC)( Display *dpy, void *drawablePrivate,
                           int64_t target_msc, int64_t divisor,
                           int64_t remainder );

Bool (*waitForMSC)( Display *dpy, void *drawablePrivate,
                    int64_t target_msc, int64_t divisor, int64_t remainder,
                    int64_t * msc, int64_t * sbc );

Bool (*waitForSBC)( Display *dpy, void *drawablePrivate,
                    int64_t target_sbc,
                    int64_t * msc, int64_t * sbc );

bool (*getSBC)( Display *dpy, void *drawablePrivate, int64_t * sbc );

int (*frameTrackingState)( Display *dpy, void *drawablePrivate,
                           GLboolean enable );

int (*getPreviousSwapUSTs)( Display *dpy, void *drawablePrivate,
                            int64_t * ust_of_swaps );

void (*joinSwapGroup)( Display *dpy, void *drawablePrivate,
                       void *memberPrivate );

void (*bindSwapBarrier)( Display *dpy, void *drawablePrivate, int barrier );

In __DRIscreenRec:

int (*getMSCRate)( Display *dpy, int scrn,
                   GLuint * numerator, GLuint * denominator );
int (*getMSC)( Display *dpy, int scrn, int64_t * msc );

In __DRIcontextRec:

unsigned swap_interval;

Bool (*bindContext2)(Display *dpy, int scrn, GLXDrawable draw,
                     GLXDrawable read_drawable, GLXContext gc );

    bindContext2 would just point to driBindContext2 instead of
    driBindContext.

================================
EXTENSIONS THAT CAN BE SUPPORTED
================================

GLX_SGI_video_sync:
    glXGetVideoSyncSGI -
        The direct rendering path for this function should be pretty
        trivial.  Just call getMSC and getSBC.

        requires  getMSC, getSBC

    glXWaitVideoSyncSGI -
        The direct rendering path for this function should be pretty
        trivial.  Just call waitForMSC.  There is no indirect path.

        requires  waitForMSC

GLX_OML_sync_control:
    glXGetSyncValuesOML -
        The direct rendering path for this function should be pretty
        trivial.  Just call getMSC, getSBC, and __glXGetUST.

        requires  getMSC, getSBC, __glXGetUST

    glXGetMscRateOML -
        The direct rendering path for this function should be pretty
        trivial.  Just call getMSCRate.  It may be possible to implement
        this without going into the DRI driver.  Afterall, the DDX driver
        already knows this information.

        requires  getMSCRate

    glXSwapBuffersMscOML -
        The direct rendering path for this function should be pretty
        trivial.  Just call swapBuffersMSC.

        requires  swapBuffersMSC

    glXWaitForMscOML -
        The direct rendering path for this function should be pretty
        trivial.  Just call waitForMSC.

        requires  waitForMSC

    glXWaitForSbcOML -
        The direct rendering path for this function should be pretty
        trivial.  Just call waitForSBC.

        requires  waitForSBC

WGL_I3D_swap_frame_usage:
    A GLX_MESA (GLX_EXT?) version of this extension would need to be
    written.  It would be functionally identical.  I think it would be safe
    and reasonable to restrict GetFrameUsage to direct rendering, but
    QueryFrameTracking should be applicable to both direct and indirect
    (remote) rendering.

    Most these functions should be pretty trivial to implement.

    wglGetFrameUsageI3D -
        *pUsage = (ust - previous_swap_ust[0]) / mst_rate_in_ms

        requires  getPreviousSwapUSTs, getMSC, getSBC

    wglBeginFrameTrackingI3D -
        requires  frameTrackingState

    wglEndFrameTrackingI3D -
        requires  frameTrackingState

    wglQueryFrameTrackingI3D -
        *pFrameCount = msc
        *pMissedFrames = (msc / swap_interval) - sbc
        *pLastMissedUsage = (previous_swap_ust[0] - previous_swap_ust[1])
                            / mst_rate_in_ms
        requires  getPreviousSwapUSTs, getMSC, getSBC

GLX_SGI_make_current_read / GLX 1.3:

    glXMakeCurrentReadSGI / glXMakeContextCurrent -
        After looking at glXMakeCurrent, it will require quite a bit of
        effort in glxcmds.c to enable this extension.  Even so, adding the
        bindContext2 method allows us to only make changes to
        driCreateContext and later have the extension automatically be added
        when an update libGL.so exists.
        
        I'm not sure I understand the subtleties of the existing
        glXMakeCurrent code to implement this.

        requires  bindContext2

    glXGetCurrentReadDrawableSGI / glXGetCurrentReadDrawable -
        I believe that the existing functions would just need to be updated
        to return currentReadDrawable.

GLX_SGI_swap_control / GLX_MESA_swap_control:
    If either if these extensions are supported, the default swap_interval
    is 1.  Current drivers are implemented as though the default
    swap_interval was 0.  The environment variable LIBGL_NO_SYNCREFRESH will
    revert the default swap_interval to 0.

    The spec for the MESA version is not yet written.  It adds the ability
    to specify a swap interval of 0 and adds the GetSwapInterval function
    from the WGL version of the extension.

    glXSwapIntervalSGI -
        This function is implemented completely in libGL.so.  It is up to
        the driver to enable the extension and respect the swap_interval
        value when performing buffer swaps.

        requires  swap_interval

    glXSwapIntervalMESA -
        This is exactly the same as glXSwapIntervalSGI with the single
        exception that 0 is a valid value for the swap_interval.  This sets
        what is essentially the default behavior with current drivers.

        requires  swap_interval

    glXGetSwapIntervalMESA -
        Simply returns the value of swap_interval.

GLX_SGIX_swap_group:
    It would be interesting to see the Mesa demo 'tunnel2' modified to use
    this extension.

    glXJoinSwapGroupSGIX -
        The implementation of this would be completely driver side.  I
        suspect that a lot of the implementation could be abstracted out and
        put in lib/GL/mesa/src/common.  I think that there's be a new
        structure called driSwapGroup that contained two linked lists.  One
        list for drawables that are swappable and one for those that aren't.
        Each drawable would have a pointer to it's driSwapGroup.  In the
        swapBuffers call, if the pointer is NULL or if the list of
        not-swappable drawables was empty, all of the swaps would happen.
        Otherwise the drawable would just be moved to the swappable list.
        
        This should be pretty easy, but there may be some subtlties that
        I've missed here.

        One side-effect is that page-flipping could be used if all of the
        drawables on the screen are part of the same swap group.

        requires joinSwapGroup

GLX_SGIX_swap_barrier:
    This extension is not currently useful in the open source DRI drivers,
    but some IHVs may find it useful.  It basically extends the idea of a
    swap group to multiple screens.

    glXBindSwapBarrierSGIX -
        The implementation of this would be completely driver side.  The
        only reason this really needs to exist in libGL is to support remote
        rendering.

        requires  bindSwapBarrier

==========================
EXTENSIONS NOT ON THE LIST
==========================

Please notice that the FBconfig and Pbuffer related functions and extensions
are missing from the list of extensions that could be supported
by these changes.  I would *REALLY* like to see the support glue added for
these extension soon.  Both ATI and PowerVR support these features in their
close source driver and EVERYBODY wants to see them in our open source
drivers.  Getting the glue in soon only helps.  I have omitted all of that
from this list because I suspect that the volume and significance of changes
required for these extensions would dwarf the current list.  I'll save that
for round two. :) The list of specific extensions I'm omitting that I think
should go in "next" is:

        GLX_SGIX_fbconfig
        GLX_SGIX_pbuffer
        GLX_ARB_render_texture (spec not yet complete)
        WGL_EXT_depth_float
        GLX_OML_swap_method
        GLX_ARB_multisample
        WGL_NV_render_texture_rectangle
        WGL_NV_render_depth_texture
        GLX_SGIX_visual_select_group
        other related extensions?


http://oss.sgi.com/projects/ogl-sample/registry/ARB/wgl_render_texture.txt
http://oss.sgi.com/projects/ogl-sample/registry/EXT/wgl_depth_float.txt
http://oss.sgi.com/projects/ogl-sample/registry/SGI/make_current_read.txt
http://oss.sgi.com/projects/ogl-sample/registry/SGI/swap_control.txt
http://oss.sgi.com/projects/ogl-sample/registry/SGI/video_sync.txt
http://oss.sgi.com/projects/ogl-sample/registry/SGIX/fbconfig.txt
http://oss.sgi.com/projects/ogl-sample/registry/SGIX/pbuffer.txt
http://oss.sgi.com/projects/ogl-sample/registry/SGIX/swap_barrier.txt
http://oss.sgi.com/projects/ogl-sample/registry/SGIX/swap_group.txt
http://oss.sgi.com/projects/ogl-sample/registry/SGIX/visual_select_group.txt
http://oss.sgi.com/projects/ogl-sample/registry/OML/glx_swap_method.txt
http://oss.sgi.com/projects/ogl-sample/registry/OML/glx_sync_control.txt
http://oss.sgi.com/projects/ogl-sample/registry/I3D/wgl_swap_frame_usage.txt
http://oss.sgi.com/projects/ogl-sample/registry/NV/render_depth_texture.txt
http://oss.sgi.com/projects/ogl-sample/registry/NV/render_texture_rectangle.txt

-- 
Smile!  http://antwrp.gsfc.nasa.gov/apod/ap990315.html


-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
Dri-devel mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/dri-devel

Reply via email to