• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1Name
2
3    NV_fence
4
5Name Strings
6
7    GL_NV_fence
8
9Contact
10
11    John Spitzer, NVIDIA Corporation (jspitzer 'at' nvidia.com)
12    Mark Kilgard, NVIDIA Corporation (mjk 'at' nvidia.com)
13
14Contributors
15
16    John Spitzer
17    Mark Kilgard
18    Acorn Pooley
19
20Notice
21
22    Copyright NVIDIA Corporation, 2000, 2001.
23
24IP Status
25
26    NVIDIA Proprietary.
27
28Status
29
30    Shipping as of June 8, 2000 (version 1.0)
31
32    Shipping as of November, 2003 (version 1.1)
33
34    Version 1.2 adds ES support and clarification; otherwise identical to 1.1.
35
36Version
37
38    December 17, 2008 (version 1.2)
39
40Number
41
42    OpenGL Extension #222
43    OpenGL ES Extension #52
44
45Dependencies
46
47    This extension is written against the OpenGL 1.2.1 Specification.
48    It can also be used with OpenGL ES (see the section, "Dependencies on
49    OpenGL ES," below).
50
51Overview
52
53    The goal of this extension is provide a finer granularity of
54    synchronizing GL command completion than offered by standard OpenGL,
55    which offers only two mechanisms for synchronization: Flush and Finish.
56    Since Flush merely assures the user that the commands complete in a
57    finite (though undetermined) amount of time, it is, thus, of only
58    modest utility.  Finish, on the other hand, stalls CPU execution
59    until all pending GL commands have completed.  This extension offers
60    a middle ground - the ability to "finish" a subset of the command
61    stream, and the ability to determine whether a given command has
62    completed or not.
63
64    This extension introduces the concept of a "fence" to the OpenGL
65    command stream.  Once the fence is inserted into the command stream, it
66    can be queried for a given condition - typically, its completion.
67    Moreover, the application may also request a partial Finish -- that is,
68    all commands prior to the fence will be forced to complete until control
69    is returned to the calling process.  These new mechanisms allow for
70    synchronization between the host CPU and the GPU, which may be accessing
71    the same resources (typically memory).
72
73    This extension is useful in conjunction with NV_vertex_array_range
74    to determine when vertex information has been pulled from the
75    vertex array range.  Once a fence has been tested TRUE or finished,
76    all vertex indices issued before the fence must have been pulled.
77    This ensures that the vertex data memory corresponding to the issued
78    vertex indices can be safely modified (assuming no other outstanding
79    vertex indices are issued subsequent to the fence).
80
81Issues
82
83    Do we need an IsFenceNV command?
84
85        RESOLUTION:  Yes.  Not sure who would use this, but it's in there.
86        Semantics currently follow the texture object definition --
87        that is, calling IsFenceNV before SetFenceNV will return FALSE.
88
89    Are the fences sharable between multiple contexts?
90
91        RESOLUTION:  No.
92
93        Potentially this could change with a subsequent extension.
94
95    What other conditions will be supported?
96
97        Only ALL_COMPLETED_NV will be supported initially.  Future extensions
98        may wish to implement additional fence conditions.
99
100    What is the relative performance of the calls?
101
102        Execution of a SetFenceNV is not free, but will not trigger a
103        Flush or Finish.
104
105    Is the TestFenceNV call really necessary?  How often would this be used
106    compared to the FinishFenceNV call (which also flushes to ensure this
107    happens in finite time)?
108
109        It is conceivable that a user may use TestFenceNV to decide
110        which portion of memory should be used next without stalling
111        the CPU.  An example of this would be a scenario where a single
112        AGP buffer is used for both static (unchanged for multiple frames)
113        and dynamic (changed every frame) data.  If the user has written
114        dynamic data to all banks dedicated to dynamic data, and still
115        has more dynamic objects to write, the user would first want to
116        check if the first dynamic object has completed, before writing
117        into the buffer.  If the object has not completed, instead of
118        stalling the CPU with a FinishFenceNV call, it would possibly
119        be better to start overwriting static objects instead.
120
121    What should happen if TestFenceNV is called for a name before SetFenceNV
122    is called?
123
124        We generate an INVALID_OPERATION error, and return TRUE.
125        This follows the semantics for texture object names before
126        they are bound, in that they acquire their state upon binding.
127        We will arbitrarily return TRUE for consistency.
128
129    What should happen if FinishFenceNV is called for a name before
130    SetFenceNV is called?
131
132        RESOLUTION:  Generate an INVALID_OPERATION error because the
133        fence id does not exist yet.  SetFenceNV must be called to create
134        a fence.
135
136    Do we need a mechanism to query which condition a given fence was
137    set with?
138
139        RESOLUTION:  Yes, use glGetFenceivNV with FENCE_CONDITION_NV.
140
141    Should we allow these commands to be compiled within display list?
142    Which ones?  How about within Begin/End pairs?
143
144        RESOLUTION:  DeleteFencesNV, FinishFenceNV, GenFencesNV,
145        TestFenceNV, and IsFenceNV are executed immediately while
146        SetFenceNV is compiled.  Do not allow any of these commands
147        within Begin/End pairs.
148
149    Can fences be used as a form of performance monitoring?
150
151        Yes, with some caveats.  By setting and testing or finishing
152        fences, developers can measure the GPU latency for completing
153        GL operations.  For example, developers might do the following:
154
155          start = getCurrentTime();
156          updateTextures();
157          glSetFenceNV(TEXTURE_LOAD_FENCE, GL_ALL_COMPLETED_NV);
158          drawBackground();
159          glSetFenceNV(DRAW_BACKGROUND_FENCE, GL_ALL_COMPLETED_NV);
160          drawCharacters();
161          glSetFenceNV(DRAW_CHARACTERS_FENCE, GL_ALL_COMPLETED_NV);
162
163          glFinishFenceNV(TEXTURE_LOAD_FENCE);
164          textureLoadEnd = getCurrentTime();
165
166          glFinishFenceNV(DRAW_BACKGROUND_FENCE);
167          drawBackgroundEnd = getCurrentTime();
168
169          glFinishFenceNV(DRAW_CHARACTERS_FENCE);
170          drawCharactersEnd = getCurrentTime();
171
172          printf("texture load time = %d\n", textureLoadEnd - start);
173          printf("draw background time = %d\n", drawBackgroundEnd - textureLoadEnd);
174          printf("draw characters time = %d\n", drawCharacters - drawBackgroundEnd);
175
176        Note that there is a small amount of overhead associated with
177        inserting each fence into the GL command stream.  Each fence
178        causes the GL command stream to momentarily idle (idling the
179        entire GPU pipeline).  The significance of this idling should
180        be small if there are a small number of fences and large amount
181        of intervening commands.
182
183        If the time between two fences is zero or very near zero,
184        it probably means that a GPU-CPU synchronization such as a
185        glFinish probably occurred.  A glFinish is an explicit GPU-CPU
186        synchronization, but sometimes implicit GPU-CPU synchronizations
187        are performed by the driver.
188
189    What happens if you set the same fence object twice?
190
191        The second SetFenceNV clobbers whatever status the fence object
192        previously had by forcing the object's status to GL_TRUE.
193        The completion of the first SetFenceNV's fence command placed
194        in the command stream is ignored (its completion does NOT
195        update the fence object's status).  The second SetFenceNV sets a
196        new fence command in the GL command stream.  This second fence
197        command will update the fence object's status (assuming it is
198        not ignored by a subsequent SetFenceNV to the same fence object).
199
200    What happens to a fence command that is still pending execution
201    when its fence object is deleted?
202
203        The fence command completion is ignored.
204
205    What happens if you use an arbitrary number for the SetFenceNV() <fence>
206    parameter instead of obtaining the name from GenFences()?
207
208        This works fine (just as with texture objects).
209
210New Procedures and Functions
211
212    void GenFencesNV(sizei n, uint *fences);
213
214    void DeleteFencesNV(sizei n, const uint *fences);
215
216    void SetFenceNV(uint fence, enum condition);
217
218    boolean TestFenceNV(uint fence);
219
220    void FinishFenceNV(uint fence);
221
222    boolean IsFenceNV(uint fence);
223
224    void GetFenceivNV(uint fence, enum pname, int *params);
225
226New Tokens
227
228    Accepted by the <condition> parameter of SetFenceNV:
229
230        ALL_COMPLETED_NV                   0x84F2
231
232    Accepted by the <pname> parameter of GetFenceivNV:
233
234        FENCE_STATUS_NV                    0x84F3
235        FENCE_CONDITION_NV                 0x84F4
236
237Additions to Chapter 5 of the OpenGL 1.2.1 Specification (Special Functions)
238
239    Add to the end of Section 5.4 "Display Lists"
240
241    "DeleteFencesNV, FinishFenceNV, GenFencesNV, GetFenceivNV,
242    TestFenceNV, and IsFenceNV are not complied into display lists but
243    are executed immediately."
244
245    After the discussion of Flush and Finish (Section 5.5) add a
246    description of the fence operations:
247
248    "5.X  Fences
249
250    The command
251
252       void SetFenceNV(uint fence, enum condition);
253
254    creates a fence object named <fence> if one does not already exist
255    and sets a fence command within the GL command stream.  If the named
256    fence object already exists, a new fence command is set within the GL
257    command stream (and any previous pending fence command corresponding
258    to the fence object is ignored).  Whether or not a new fence object is
259    created, SetFenceNV assigns the named fence object a status of FALSE
260    and a condition as set by the condition argument.  The condition
261    argument must be ALL_COMPLETED_NV.  Once the fence's condition is
262    satisfied within the command stream, the corresponding fence object's
263    state is changed to TRUE.  For a condition of ALL_COMPLETED_NV,
264    this is completion of the fence command and all preceding commands.
265    No other state is affected by execution of the fence command.  The name
266    <fence> may be one returned by GenFencesNV() but that is not required.
267
268    A fence's state can be queried by calling the command
269
270      boolean TestFenceNV(uint fence);
271
272    The command
273
274      void FinishFenceNV(uint fence);
275
276    forces all GL commands prior to the fence to satisfy the condition
277    set within SetFenceNV, which, in this spec, is always completion.
278    FinishFenceNV does not return until all effects from these commands
279    on GL client and server state and the framebuffer are fully realized.
280
281    The command
282
283      void GenFencesNV(sizei n, uint *fences);
284
285    returns n previously unused fence names in fences.  These names
286    are marked as used, for the purposes of GenFencesNV only, but
287    corresponding fence objects do not exist (have no state) until created
288    with SetFenceNV().
289
290    Fences are deleted by calling
291
292      void DeleteFencesNV(sizei n, const uint *fences);
293
294    fences contains n names of fences to be deleted.  After a fence is
295    deleted, it has no state, and its name is again unused.  Unused names
296    in fences are silently ignored.
297
298    If the fence passed to TestFenceNV or FinishFenceNV is not the name of an
299    existing fence, the error INVALID_OPERATION is generated.  In this case,
300    TestFenceNV will return TRUE, for the sake of consistency.
301
302    State must be maintained to indicate which fence integers are
303    currently used or set.  In the initial state, no indices are in use.
304    When a fence integer is set, the condition and status of the fence
305    are also maintained.  The status is a boolean.  The condition is
306    the value last set as the condition by SetFenceNV.
307
308    Once the status of a fence has been finished (via FinishFenceNV)
309    or tested and the returned status is TRUE (via either TestFenceNV
310    or GetFenceivNV querying the FENCE_STATUS_NV), the status remains
311    TRUE until the next SetFenceNV of the fence."
312
313Additions to Chapter 6 of the OpenGL 1.2.1 Specification (State and State Requests)
314
315    Insert new section after Section 6.1.10 "Minmax Query"
316
317    "6.1.11 Fence Query
318
319    The command
320
321      boolean IsFenceNV(uint fence);
322
323    return TRUE if <fence> is the name of an existing fence.  If <fence> is
324    not the name of an existing fence, or if an error condition occurs,
325    IsFenceNV returns FALSE.  A name returned by GenFencesNV, but not yet set
326    via SetFenceNV, is not the name of an existing fence.
327
328    The command
329
330      void GetFenceivNV(uint fence, enum pname, int *params)
331
332    obtains the indicated fence state for the specified fence in the array
333    params.  pname must be either FENCE_STATUS_NV or FENCE_CONDITION_NV.
334    The INVALID_OPERATION error is generated if the named fence does
335    not exist."
336
337Additions to the GLX Specification
338
339    None
340
341GLX Protocol
342
343    Seven new GL commands are added.
344
345    The following rendering command is sent to the sever as part of a
346    glXRender request:
347
348        SetFenceNV
349            2           12              rendering command length
350            2           4143            rendering command opcode
351            4           CARD32          fence
352            4           CARD32          condition
353
354    The remaining five commands are non-rendering commands.  These
355    commands are sent separately (i.e., not as part of a glXRender or
356    glXRenderLarge request), using the glXVendorPrivateWithReply request:
357
358        DeleteFencesNV
359            1           CARD8           opcode (X assigned)
360            1           17              GLX opcode (glXVendorPrivateWithReply)
361            2           4+n             request length
362            4           1276            vendor specific opcode
363            4           GLX_CONTEXT_TAG context tag
364            4           INT32           n
365            n*4         LISTofCARD32    fences
366
367        GenFencesNV
368            1           CARD8           opcode (X assigned)
369            1           17              GLX opcode (glXVendorPrivateWithReply)
370            2           4               request length
371            4           1277            vendor specific opcode
372            4           GLX_CONTEXT_TAG context tag
373            4           INT32           n
374          =>
375            1           1               reply
376            1                           unused
377            2           CARD16          sequence number
378            4           n               reply length
379            24                          unused
380            n*4         LISTofCARD322   fences
381
382        IsFenceNV
383            1           CARD8           opcode (X assigned)
384            1           17              GLX opcode (glXVendorPrivateWithReply)
385            2           4               request length
386            4           1278            vendor specific opcode
387            4           GLX_CONTEXT_TAG context tag
388            4           INT32           n
389          =>
390            1           1               reply
391            1                           unused
392            2           CARD16          sequence number
393            4           0               reply length
394            4           BOOL32          return value
395            20                          unused
396
397        TestFenceNV
398            1           CARD8           opcode (X assigned)
399            1           17              GLX opcode (glXVendorPrivateWithReply)
400            2           4               request length
401            4           1279            vendor specific opcode
402            4           GLX_CONTEXT_TAG context tag
403            4           INT32           fence
404          =>
405            1           1               reply
406            1                           unused
407            2           CARD16          sequence number
408            4           0               reply length
409            4           BOOL32          return value
410            20                          unused
411
412        GetFenceivNV
413            1           CARD8           opcode (X assigned)
414            1           17              GLX opcode (glXVendorPrivateWithReply)
415            2           5               request length
416            4           1280            vendor specific opcode
417            4           GLX_CONTEXT_TAG context tag
418            4           INT32           fence
419            4           CARD32          pname
420          =>
421            1           1               reply
422            1                           unused
423            2           CARD16          sequence number
424            4           m               reply length, m=(n==1?0:n)
425            4                           unused
426            4           CARD32          n
427
428            if (n=1) this follows:
429
430            4           INT32           params
431            12                          unused
432
433            otherwise this follows:
434
435            16                          unused
436            n*4         LISTofINT32     params
437
438        FinishFenceNV
439            1           CARD8           opcode (X assigned)
440            1           17              GLX opcode (glXVendorPrivateWithReply)
441            2           4               request length
442            4           1312            vendor specific opcode
443            4           GLX_CONTEXT_TAG context tag
444            4           INT32           fence
445          =>
446            1           1               reply
447            1                           unused
448            2           CARD16          sequence number
449            4           0               reply length
450            24                          unused
451
452Errors
453
454    INVALID_VALUE is generated if GenFencesNV or DeleteFencesNV parameter <n>
455    is negative.
456
457    INVALID_OPERATION is generated if the fence used in TestFenceNV,
458    FinishFenceNV or GetFenceivNV is not the name of an existing fence.
459
460    INVALID_ENUM is generated if the condition used in SetFenceNV
461    is not ALL_COMPLETED_NV.
462
463    INVALID_OPERATION is generated if any of the commands defined in
464    this extension is executed between the execution of Begin and the
465    corresponding execution of End.
466
467New State
468
469Table 6.X.  Fence Objects.
470
471Get value           Type  Get command   Initial value                 Description      Section  Attribute
472------------------  ----  ------------  ----------------------------  ---------------  -------  ---------
473FENCE_STATUS_NV     B     GetFenceivNV  determined by 1st SetFenceNV  Fence status     5.X      -
474FENCE_CONDITION_NV  Z1    GetFenceivNV  determined by 1st SetFenceNV  Fence condition  5.X      -
475
476New Implementation Dependent State
477
478    None
479
480Dependencies on OpenGL ES
481
482    If implemented for OpenGL ES, NV_fence acts as described in this spec,
483    except:
484
485        * Ignore all references to display lists and immediate mode, including
486          changes to section 5.4 "Display Lists".
487        * Ignore all references to GLX and GLX protocol.
488
489GeForce Implementation Details
490
491    This section describes implementation-defined limits for GeForce:
492
493        SetFenceNV calls are not free.  They should be used prudently,
494        and a "good number" of commands should be sent between calls to
495        SetFenceNV.  Each fence insertion will cause the GPU's command
496        processing to go momentarily idle.  Testing or finishing a fence
497        may require an one or more somewhat expensive uncached reads.
498
499        Do not leave a fence untested or unfinished for an extremely large
500        interval of intervening fences.  If more than approximately 2
501        billion (specifically 2^31-1) intervening fences are inserted into
502        the GL command stream before a fence is tested or finished, said
503        fence may indicate an incorrect status.  Note that certain GL
504        operations involving display lists, compiled vertex arrays, and
505        textures may insert fences implicitly for internal driver use.
506
507        In practice, this limitation is unlikely to be a practical
508        limitation if fences are finished or tested within a few frames
509        of their insertion into the GL command stream.
510
511Revision History
512
513    November 13, 2000 - GLX enumerant values assigned
514
515    October 3, 2003 - Changed version to 1.1.  glFinishFenceNV should
516    not be compiled into display lists but rather executed immediately
517    when called during display list construction.  Version 1.0 allowed
518    this though it should not have been allowed.  Changed GLX protocol
519    so that FinishFenceNV is a non-render request with a reply now.
520    Thanks to Bob Beretta for noticing this issue.
521
522    Also fix a typo in the GLX protocol specification for IsFenceNV so
523    the reply is 32 (not 33) bytes.
524
525    December 17. 2008 - Add "Dependencies on OpenGL ES" section.  Clarify
526    generation of fence name vs creation of the fence itself.
527