back  Return to list

homeprevnext Name
homeprevnext Name Strings
homeprevnext Contact
    John Spitzer, NVIDIA Corporation (jspitzer 'at'  
    Mark Kilgard, NVIDIA Corporation (mjk 'at'  
homeprevnext Notice
    Copyright NVIDIA Corporation, 2000, 2001.  
homeprevnext IP Status
    NVIDIA Proprietary.  
homeprevnext Status
    Shipping as of June 8, 2000 (version 1.0)  
    Shipping as of November, 2003 (version 1.1)  
homeprevnext Version
    October 3, 2003 (version 1.1)  
    $Date$ $Revision$  
    $Id: //sw/main/docs/OpenGL/specs/GL_NV_fence.txt#13 $  
homeprevnext Number
homeprevnext Dependencies
homeprevnext Overview
    The goal of this extension is provide a finer granularity of  
    synchronizing GL command completion than offered by standard OpenGL,  
    which offers only two mechanisms for synchronization: Flush and Finish.  
    Since Flush merely assures the user that the commands complete in a  
    finite (though undetermined) amount of time, it is, thus, of only  
    modest utility.  Finish, on the other hand, stalls CPU execution  
    until all pending GL commands have completed.  This extension offers  
    a middle ground - the ability to "finish" a subset of the command  
    stream, and the ability to determine whether a given command has  
    completed or not.  
    This extension introduces the concept of a "fence" to the OpenGL  
    command stream.  Once the fence is inserted into the command stream, it  
    can be queried for a given condition - typically, its completion.  
    Moreover, the application may also request a partial Finish -- that is,  
    all commands prior to the fence will be forced to complete until control  
    is returned to the calling process.  These new mechanisms allow for  
    synchronization between the host CPU and the GPU, which may be accessing  
    the same resources (typically memory).  
    This extension is useful in conjunction with NV_vertex_array_range  
    to determine when vertex information has been pulled from the  
    vertex array range.  Once a fence has been tested TRUE or finished,  
    all vertex indices issued before the fence must have been pulled.  
    This ensures that the vertex data memory corresponding to the issued  
    vertex indices can be safely modified (assuming no other outstanding  
    vertex indices are issued subsequent to the fence).  
homeprevnext Issues
    Do we need an IsFenceNV command?  
        RESOLUTION:  Yes.  Not sure who would use this, but it's in there.  
        Semantics currently follow the texture object definition --  
        that is, calling IsFenceNV before SetFenceNV will return FALSE.  
    Are the fences sharable between multiple contexts?  
        RESOLUTION:  No.  
        Potentially this could change with a subsequent extension.  
    What other conditions will be supported?  
        Only ALL_COMPLETED_NV will be supported initially.  Future extensions  
        may wish to implement additional fence conditions.  
    What is the relative performance of the calls?  
        Execution of a SetFenceNV is not free, but will not trigger a  
        Flush or Finish.  
    Is the TestFenceNV call really necessary?  How often would this be used  
    compared to the FinishFenceNV call (which also flushes to ensure this  
    happens in finite time)?  
        It is conceivable that a user may use TestFenceNV to decide  
        which portion of memory should be used next without stalling  
        the CPU.  An example of this would be a scenario where a single  
        AGP buffer is used for both static (unchanged for multiple frames)  
        and dynamic (changed every frame) data.  If the user has written  
        dynamic data to all banks dedicated to dynamic data, and still  
        has more dynamic objects to write, the user would first want to  
        check if the first dynamic object has completed, before writing  
        into the buffer.  If the object has not completed, instead of  
        stalling the CPU with a FinishFenceNV call, it would possibly  
        be better to start overwriting static objects instead.  
    What should happen if TestFenceNV is called for a name before SetFenceNV  
    is called?  
        We generate an INVALID_OPERATION error, and return TRUE.  
        This follows the semantics for texture object names before  
        they are bound, in that they acquire their state upon binding.  
        We will arbitrarily return TRUE for consistency.  
    What should happen if FinishFenceNV is called for a name before  
    SetFenceNV is called?  
        RESOLUTION:  Generate an INVALID_OPERATION error because the  
        fence id does not exist yet.  SetFenceNV must be called to create  
        a fence.  
    Do we need a mechanism to query which condition a given fence was  
    set with?  
        RESOLUTION:  Yes, use glGetFenceivNV with FENCE_CONDITION_NV.  
    Should we allow these commands to be compiled within display list?  
    Which ones?  How about within Begin/End pairs?  
        RESOLUTION:  DeleteFencesNV, FinishFenceNV, GenFencesNV,  
        TestFenceNV, and IsFenceNV are executed immediately while  
        SetFenceNV is compiled.  Do not allow any of these commands  
        within Begin/End pairs.  
    Can fences be used as a form of performance monitoring?  
        Yes, with some caveats.  By setting and testing or finishing  
        fences, developers can measure the GPU latency for completing  
        GL operations.  For example, developers might do the following:  
          start = getCurrentTime();  
          textureLoadEnd = getCurrentTime();  
          drawBackgroundEnd = getCurrentTime();  
          drawCharactersEnd = getCurrentTime();  
          printf("texture load time = %d\n", textureLoadEnd - start);  
          printf("draw background time = %d\n", drawBackgroundEnd - textureLoadEnd);  
          printf("draw characters time = %d\n", drawCharacters - drawBackgroundEnd);  
        Note that there is a small amount of overhead associated with  
        inserting each fence into the GL command stream.  Each fence  
        causes the GL command stream to momentarily idle (idling the  
        entire GPU pipeline).  The significance of this idling should  
        be small if there are a small number of fences and large amount  
        of intervening commands.  
        If the time between two fences is zero or very near zero,  
        it probably means that a GPU-CPU synchronization such as a  
        glFinish probably occurred.  A glFinish is an explicit GPU-CPU  
        synchronization, but sometimes implicit GPU-CPU synchronizations  
        are performed by the driver.  
    What happens if you set the same fence object twice?  
        The second SetFenceNV clobbers whatever status the fence object  
        previously had by forcing the object's status to GL_TRUE.  
        The completion of the first SetFenceNV's fence command placed  
        in the command stream is ignored (its completion does NOT  
        update the fence object's status).  The second SetFenceNV sets a  
        new fence command in the GL command stream.  This second fence  
        command will update the fence object's status (assuming it is  
        not ignored by a subsequent SetFenceNV to the same fence object).  
    What happens to a fence command that is still pending execution  
    when its fence object is deleted?  
        The fence command completion is ignored.  
homeprevnext New Procedures and Functions
    void GenFencesNV(sizei n, uint *fences);  
    void DeleteFencesNV(sizei n, const uint *fences);  
    void SetFenceNV(uint fence, enum condition);  
    boolean TestFenceNV(uint fence);  
    void FinishFenceNV(uint fence);  
    boolean IsFenceNV(uint fence);  
    void GetFenceivNV(uint fence, enum pname, int *params);  
homeprevnext New Tokens
    Accepted by the <condition> parameter of SetFenceNV:  
        ALL_COMPLETED_NV                   0x84F2  
    Accepted by the <pname> parameter of GetFenceivNV:  
        FENCE_STATUS_NV                    0x84F3  
        FENCE_CONDITION_NV                 0x84F4  
homeprevnext Additions to Chapter 5 of the OpenGL 1.2.1 Specification (Special Functions)
    Add to the end of Section 5.4 "Display Lists"  
    "DeleteFencesNV, FinishFenceNV, GenFencesNV, GetFenceivNV,  
    TestFenceNV, and IsFenceNV are not complied into display lists but  
    are executed immediately."  
    After the discussion of Flush and Finish (Section 5.5) add a  
    description of the fence operations:  
    "5.X  Fences  
    The command   
       void SetFenceNV(uint fence, enum condition);  
    creates a fence object named <fence> if one does not already exist  
    and sets a fence command within the GL command stream.  If the named  
    fence object already exists, a new fence command is set within the GL  
    command stream (and any previous pending fence command corresponding  
    to the fence object is ignored).  Whether or not a new fence object is  
    created, SetFenceNV assigns the named fence object a status of FALSE  
    and a condition as set by the condition argument.  The condition  
    argument must be ALL_COMPLETED_NV.  Once the fence's condition is  
    satisfied within the command stream, the corresponding fence object's  
    state is changed to TRUE.  For a condition of ALL_COMPLETED_NV,  
    this is completion of the fence command and all preceding commands.  
    No other state is affected by execution of the fence command.  
    A fence's state can be queried by calling the command  
      boolean TestFenceNV(uint fence);  
    The command  
      void FinishFenceNV(uint fence);  
    forces all GL commands prior to the fence to satisfy the condition  
    set within SetFenceNV, which, in this spec, is always completion.  
    FinishFenceNV does not return until all effects from these commands  
    on GL client and server state and the framebuffer are fully realized.  
    The fence must first be created before it can be used.  The command  
      void GenFencesNV(sizei n, uint *fences);  
    returns n previously unused fence names in fences.  These names  
    are marked as used, for the purposes of GenFencesNV only, but acquire  
    boolean state only when they have been set.  
    Fences are deleted by calling  
      void DeleteFencesNV(sizei n, const uint *fences);  
    fences contains n names of fences to be deleted.  After a fence is  
    deleted, it has no state, and its name is again unused.  Unused names  
    in fences are silently ignored.  
    If the fence passed to TestFenceNV or FinishFenceNV is not the name  
    of a fence, the error INVALID_OPERATION is generated.  In this case,  
    TestFenceNV will return TRUE, for the sake of consistency.  
    State must be maintained to indicate which fence integers are  
    currently used or set.  In the initial state, no indices are in use.  
    When a fence integer is set, the condition and status of the fence  
    are also maintained.  The status is a boolean.  The condition is  
    the value last set as the condition by SetFenceNV.  
    Once the status of a fence has been finished (via FinishFenceNV)  
    or tested and the returned status is TRUE (via either TestFenceNV  
    or GetFenceivNV querying the FENCE_STATUS_NV), the status remains  
    TRUE until the next SetFenceNV of the fence."  
homeprevnext Additions to Chapter 6 of the OpenGL 1.2.1 Specification (State and State Requests)
    Insert new section after Section 6.1.10 "Minmax Query"  
    "6.1.11 Fence Query  
    The command  
      boolean IsFenceNV(uint fence);  
    return TRUE if texture is the name of a fence.  If fence is not the  
    name of a fence, or if an error condition occurs, IsFenceNV returns  
    FALSE.  A name returned by GenFencesNV, but not yet set via SetFenceNV,  
    is not the name of a fence.  
    The command  
      void GetFenceivNV(uint fence, enum pname, int *params)  
    obtains the indicated fence state for the specified fence in the array  
    params.  pname must be either FENCE_STATUS_NV or FENCE_CONDITION_NV.  
    The INVALID_OPERATION error is generated if the named fence does  
    not exist."  
homeprevnext Additions to the GLX Specification
homeprevnext GLX Protocol
    Seven new GL commands are added.  
    The following two rendering commands are sent to the sever as part  
    of a glXRender request:  
            2           12              rendering command length  
            2           4143            rendering command opcode  
            4           CARD32          fence  
            4           CARD32          condition  
    The remaining five commands are non-rendering commands.  These  
    commands are sent separately (i.e., not as part of a glXRender or  
    glXRenderLarge request), using the glXVendorPrivateWithReply request:  
            1           CARD8           opcode (X assigned)  
            1           17              GLX opcode (glXVendorPrivateWithReply)  
            2           4+n             request length  
            4           1276            vendor specific opcode  
            4           GLX_CONTEXT_TAG context tag  
            4           INT32           n  
            n*4         LISTofCARD32    fences  
            1           CARD8           opcode (X assigned)  
            1           17              GLX opcode (glXVendorPrivateWithReply)  
            2           4               request length  
            4           1277            vendor specific opcode  
            4           GLX_CONTEXT_TAG context tag  
            4           INT32           n  
            1           1               reply  
            1                           unused  
            2           CARD16          sequence number  
            4           n               reply length  
            24                          unused  
            n*4         LISTofCARD322   fences  
            1           CARD8           opcode (X assigned)  
            1           17              GLX opcode (glXVendorPrivateWithReply)  
            2           4               request length  
            4           1278            vendor specific opcode  
            4           GLX_CONTEXT_TAG context tag  
            4           INT32           n  
            1           1               reply  
            1                           unused  
            2           CARD16          sequence number  
            4           0               reply length  
            4           BOOL32          return value  
            20                          unused  
            1           CARD8           opcode (X assigned)  
            1           17              GLX opcode (glXVendorPrivateWithReply)  
            2           4               request length  
            4           1279            vendor specific opcode  
            4           GLX_CONTEXT_TAG context tag  
            4           INT32           fence  
            1           1               reply  
            1                           unused  
            2           CARD16          sequence number  
            4           0               reply length  
            4           BOOL32          return value  
            20                          unused  
            1           CARD8           opcode (X assigned)  
            1           17              GLX opcode (glXVendorPrivateWithReply)  
            2           5               request length  
            4           1280            vendor specific opcode  
            4           GLX_CONTEXT_TAG context tag  
            4           INT32           fence  
            4           CARD32          pname  
            1           1               reply  
            1                           unused  
            2           CARD16          sequence number  
            4           m               reply length, m=(n==1?0:n)  
            4                           unused  
            4           CARD32          n  
            if (n=1) this follows:  
            4           INT32           params  
            12                          unused  
            otherwise this follows:  
            16                          unused  
            n*4         LISTofINT32     params  
            1           CARD8           opcode (X assigned)  
            1           17              GLX opcode (glXVendorPrivateWithReply)  
            2           4               request length  
            4           1312            vendor specific opcode  
            4           GLX_CONTEXT_TAG context tag  
            4           INT32           fence  
            1           1               reply  
            1                           unused  
            2           CARD16          sequence number  
            4           0               reply length  
            24                          unused  
homeprevnext Errors
    INVALID_VALUE is generated if GenFencesNV parameter <n> is negative.  
    INVALID_VALUE is generated if DeleteFencesNV parameter <n> is negative.  
    INVALID_OPERATION is generated if the fence used in TestFenceNV or  
    FinishFenceNV is not the name of a fence.  
    INVALID_ENUM is generated if the condition used in SetFenceNV  
    is not ALL_COMPLETED_NV.  
    INVALID_OPERATION is generated if any of the commands defined in  
    this extension is executed between the execution of Begin and the  
    corresponding execution of End.  
    INVALID_OPERATION is generated if the named fence in GetFenceivNV  
    does not exist.  
    INVALID_VALUE is generated if DeleteFencesNV or GenFencesNV are  
    called where n is negative.  
homeprevnext New State
Table 6.X.  Fence Objects.  
Get value           Type  Get command   Initial value                 Description      Section  Attribute  
------------------  ----  ------------  ----------------------------  ---------------  -------  ---------  
FENCE_STATUS_NV     B     GetFenceivNV  determined by 1st SetFenceNV  Fence status     5.X      -  
FENCE_CONDITION_NV  Z1    GetFenceivNV  determined by 1st SetFenceNV  Fence condition  5.X      -  
homeprevnext New Implementation Dependent State
GeForce Implementation Details  
    This section describes implementation-defined limits for GeForce:  
        SetFenceNV calls are not free.  They should be used prudently,  
        and a "good number" of commands should be sent between calls to  
        SetFenceNV.  Each fence insertion will cause the GPU's command  
        processing to go momentarily idle.  Testing or finishing a fence  
        may require an one or more somewhat expensive uncached reads.  
        Do not leave a fence untested or unfinished for an extremely large  
        interval of intervening fences.  If more than approximately 2  
        billion (specifically 2^31-1) intervening fences are inserted into  
        the GL command stream before a fence is tested or finished, said  
        fence may indicate an incorrect status.  Note that certain GL  
        operations involving display lists, compiled vertex arrays, and  
        textures may insert fences implicitly for internal driver use.  
        In practice, this limitation is unlikely to be a practical  
        limitation if fences are finished or tested within a few frames  
        of their insertion into the GL command stream.  
homeprevnext Revision History
    November 13, 2000 - GLX enumerant values assigned  
    October 3, 2003 - Changed version to 1.1.  glFinishFenceNV should  
    not be compiled into display lists but rather executed immediately  
    when called during display list construction.  Version 1.0 allowed  
    this though it should not have been allowed.  Changed GLX protocol  
    so that FinishFenceNV is a non-render request with a reply now.  
    Thanks to Bob Beretta for noticing this issue.  
    Also fix a typo in the GLX protocol specification for IsFenceNV so  
    the reply is 32 (not 33) bytes.  
    the reply is 32 (not 33) bytes.  
Valid XHTML 1.1! Valid CSS! Last update: November 14, 2006.
Cette page doit être lue avec un navigateur récent respectant le standard XHTML 1.1.