• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1Name
2
3    NV_occlusion_query
4
5Name Strings
6
7    GL_NV_occlusion_query
8
9Contact
10
11    Matt Craighead, NVIDIA Corporation (mcraighead 'at' nvidia.com)
12
13Notice
14
15    Copyright NVIDIA Corporation, 2001, 2002.
16
17IP Status
18
19    NVIDIA Proprietary.
20
21Status
22
23    Shipping (version 1.0)
24
25Version
26
27    NVIDIA Date: February 6, 2002 (version 1.0)
28
29Number
30
31    261
32
33Dependencies
34
35    Written based on the wording of the OpenGL 1.3 specification.
36
37    Requires support for the HP_occlusion_test extension.
38
39Overview
40
41    The HP_occlusion_test extension defines a mechanism whereby an
42    application can query the visibility of an object, where "visible"
43    means that at least one pixel passes the depth and stencil tests.
44
45    The HP extension has two major shortcomings.
46
47    - It returns the result as a simple GL_TRUE/GL_FALSE result, when in
48      fact it is often useful to know exactly how many pixels passed.
49    - It provides only a simple "stop-and-wait" model for using multiple
50      queries.  The application begins an occlusion test and ends it;
51      then, at some later point, it asks for the result, at which point
52      the driver must stop and wait until the result from the previous
53      test is back before the application can even begin the next one.
54      This is a very simple model, but its performance is mediocre when
55      an application wishes to perform many queries, and it eliminates
56      most of the opportunites for parallelism between the CPU and GPU.
57
58    This extension solves both of those problems.  It returns as its
59    result the number of pixels that pass, and it provides an interface
60    conceptually similar to that of NV_fence that allows applications to
61    issue many occlusion queries before asking for the result of any one.
62    As a result, they can overlap the time it takes for the occlusion
63    query results to be returned with other, more useful work, such as
64    rendering other parts of the scene or performing other computations
65    on the CPU.
66
67    There are many situations where a pixel count, rather than a boolean
68    result, is useful.
69
70    - If the visibility test is an object bounding box being used to
71      decide whether to skip the object, sometimes it can be acceptable,
72      and beneficial to performance, to skip an object if less than some
73      threshold number of pixels could be visible.
74    - Knowing the number of pixels visible in the bounding box may also
75      help decide what level of detail a model should be drawn with.  If
76      only a few pixels are visible, a low-detail model may be
77      acceptable.  In general, this allows level-of-detail mechanisms to
78      be slightly less ad hoc.
79    - "Depth peeling" techniques, such as order-independent transparency,
80      would typically like to know when to stop rendering more layers; it
81      is difficult to come up with a way to determine a priori how many
82      layers to use.  A boolean count allows applications to stop when
83      more layers will not affect the image at all, but this will likely
84      be unacceptable for performance, with minimal gains to image
85      quality.  Instead, it makes more sense to stop rendering when the
86      number of pixels goes below a threshold; this should provide better
87      results than any of these other algorithms.
88    - Occlusion queries can be used as a replacement for glReadPixels of
89      the depth buffer to determine whether, say, a light source is
90      visible for the purposes of a lens flare effect or a halo to
91      simulate glare.  Pixel counts allow you to compute the percentage
92      of the light source that is visible, and the brightness of these
93      effects can be modulated accordingly.
94
95Issues
96
97    *   Should we use an object-based interface?
98
99        RESOLVED: Yes, this makes the interface much simpler, and it is
100        friendly for indirect rendering.
101
102    *   Should we offer an entry point analogous to glTestFenceNV?
103
104        RESOLVED: No, it is sufficient to have glGetOcclusionQueryivNV
105        provide a query for whether the occlusion query result is back
106        yet.  Whereas it is interesting to poll fence objects, it is
107        relatively less interesting to poll occlusion queries.
108
109    *   Is glGetOcclusionQueryuivNV necessary?
110
111        RESOLVED: Yes, it makes using a 32-bit pixel count less painful.
112
113    *   Should there be a limit on how many queries can be outstanding?
114
115        RESOLVED: No.  This would make the extension much more
116        difficult to spec and use.  Allowing this does not add any
117        significant implementation burden; and even if drivers have some
118        internal limit on the number of outstanding queries, it is not
119        expected that applications will need to know this to achieve
120        optimal or near-optimal performance.
121
122    *   What happens if glBeginOcclusionQueryNV is called when an
123        occlusion query is already outstanding for a different object?
124
125        RESOLVED: This is a GL_INVALID_OPERATION error.
126
127    *   What happens if HP_occlusion_test and NV_occlusion_query usage is
128        overlapped?
129
130        RESOLVED: The two can be overlapped safely.  Counting is enabled
131        if we are _either_ inside a glBeginOcclusionQueryNV or if
132        if GL_OCCLUSION_TEST_HP is enabled.  The alternative (producing
133        an error) does not work -- it would require that glPopAttrib be
134        capable of producing an error, which would be rather problematic.
135
136        Note that glBeginOcclusionQueryNV, not glEndOcclusionQueryNV,
137        resets the pixel counter and occlusion test result.  This can
138        avoid certain types of strange behavior where an occlusion
139        query's pixel count does not always correspond to the pixels
140        rendered during the occlusion query.  The spec would make sense
141        the other way, but the behavior would be strange.
142
143    *   Does EndOcclusionQuery need to take any parameters?
144
145        RESOLVED: No.  Giving it, for example, an "id" parameter would
146        be redundant -- adding complexity for no benefit.  Only one query
147        can be active at a time.
148
149    *   How many bits should we require the pixel counter to be, at
150        minimum?
151
152        RESOLVED: 24.  24 is enough to handle 8.7 full overdraws of a
153        1600x1200 window.  That seems quite sufficient.
154
155    *   What should we do about overflows?
156
157        RESOLVED: Overflows leave the pixel count undefined.  Saturating
158        is recommended but not required.
159
160        The ideal behavior really is to saturate.  This ensures that you
161        always get a "large" result when you render many pixels.  It also
162        ensures that apps which want a boolean test can do one on their
163        own, and not worry about the rare case where the result ends up
164        exactly at zero from wrapping.
165
166        That being said, with 24 bits of pixel count required, it's not
167        clear that this really matters.  It's better to be a bit
168        permissive here.  In addition, even if saturation was required,
169        the goal of having strictly defined behavior is still not really
170        met.
171
172        Applications don't (or at least shouldn't) check for some _exact_
173        number of bits.  Imagine if a multitextured app had been written
174        that required that the number of texture units supported be
175        _exactly_ two!  Implementors of OpenGL would be greatly annoyed
176        to find that the app did not run on, say, three-texture or four-
177        texture hardware.
178
179        So, we expect apps here to always be doing a "greater than or
180        equal to" check.  An app might check for, say, at least 28 bits.
181        This doesn't ensure defined behavior -- it only ensures that once
182        an overflow occurs (which may happen at any power of two), that
183        overflow will be handled with saturation.  This behavior still
184        remains sufficiently unpredictable that the reasons for defining
185        behavior in even rarely-used cases (preventing compatibility
186        problems, for example) are unsatisfied.
187
188        All that having been said, saturation is still explicitly
189        recommended in the spec language.
190
191    *   What is the interaction with multisample, which was not defined
192        in the original spec?
193
194        RESOLVED: The pixel count is the number of samples that pass, not
195        the number of pixels.  This is true even if GL_MULTISAMPLE is
196        disabled but GL_SAMPLE_BUFFERS is 1.  Note that the depth/stencil
197        test optimization whereby implementations may choose to depth
198        test at only one of the samples when GL_MULTISAMPLE is disabled
199        does not cause this to become ill-specified, because we are
200        counting the number of samples that are still alive _after_ the
201        depth test stage.  The mechanism used to decide whether to kill
202        or keep those samples is not relevant.
203
204    *   Exactly what stage are we counting at?  The original spec said
205        depth test; what does stencil test do?
206
207        RESOLVED: We are counting immediately after _both_ the depth and
208        stencil tests, i.e., pixels that pass both.  This was the
209        original spec's intent.  Note that the depth test comes after the
210        stencil test, so to say that it is the number that pass the depth
211        test is reasonable; though it is often helpful to think of the
212        depth and stencil tests as being combined, because the depth test
213        result impacts the stencil operation used.
214
215    *   Is it guaranteed that occlusion queries return in order?
216
217        RESOLVED: Yes.  It makes sense to do this.  If occlusion test X
218        occurred before occlusion query Y, and the driver informs the app
219        that occlusion query Y is done, the app can infer that occlusion
220        query X is also done.  For applications that do poll, this allows
221        them to do so with less effort.
222
223    *   Will polling an occlusion query without a glFlush possibly cause
224        an infinite loop?
225
226        RESOLVED: Yes, this is a risk.  If you ask for the result,
227        however, any flush required will be done automatically.  It is
228        only when you are polling that this is a problem because there is
229        no guarantee that a flush has occured in the time since
230        glEndOcclusionQueryNV, and the spec is written to say that the
231        result is only "available" if the value could be returned
232        _instantaneously_.
233
234        This is different from NV_fence, where FinishFenceNV can cause an
235        app hang, and where TestFenceNV was also not guaranteed to ever
236        finish.
237
238        There need not be any spec language to describe this behavior
239        because it is implied by what is already said.
240
241        In short, if you use GL_PIXEL_COUNT_AVAILABLE_NV, you _must_ use
242        glFlush, or your app may hang.
243
244    *   The HP_occlusion_test specs did not contain the spec edits that
245        explain the exact way the extension works.  Should this spec fill
246        in those details?
247
248        RESOLVED: Yes.  These two extensions are intertwined in so many
249        important ways that doing so is not optional.
250
251    *   Should there be a "target" parameter to BeginOcclusionQuery?
252
253        RESOLVED: No.  We're not trying to solve the problem of "query
254        anything" here.
255
256    *   What might an application that uses this extension look like?
257
258        Here is some rough sample code:
259
260        GLuint occlusionQueries[N];
261        GLuint pixelCount;
262
263        glGenOcclusionQueriesNV(N, occlusionQueries);
264        ...
265        // before this point, render major occluders
266        glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
267        glDepthMask(GL_FALSE);
268        // also disable texturing and any fancy shading features
269        for (i = 0; i < N; i++) {
270            glBeginOcclusionQueryNV(occlusionQueries[i]);
271            // render bounding box for object i
272            glEndOcclusionQueryNV();
273        }
274        // at this point, if possible, go and do some other computation
275        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
276        glDepthMask(GL_TRUE);
277        // reenable other state
278        for (i = 0; i < N; i++) {
279            glGetOcclusionQueryuivNV(occlusionQueries[i], GL_PIXEL_COUNT_NV,
280                                     &pixelCount);
281            if (pixelCount > 0) {
282                // render object i
283            }
284        }
285
286    *   Is this extension useful for saving geometry, fill rate, or both?
287
288        It is expected that it will be most useful for saving geometry
289        work, because for the cost of rendering a bounding box you can
290        save rendering a normal object.
291
292        It is possible for this extension to help in fill-limited
293        situations, but using it may also hurt performance in such
294        situations, because rendering the pixels of a bounding box is
295        hardly free.  In most situations a bounding box will probably
296        have more pixels than the original object.
297
298        One exception is that for objects rendered with multiple passes,
299        the first pass can be wrapped with an occlusion query almost for
300        free.  That is, render the first pass for all objects in the
301        scene, and get the number of pixels rendered on each object.  If
302        zero pixels were rendered for an object, you can skip subsequent
303        rendering passes.  This trick can be very useful in many cases.
304
305    *   What can be said about guaranteeing correctness when using
306        occlusion queries, especially as it relates to invariance?
307
308        Invariance is critical to guarantee the correctness of occlusion
309        queries.  If occlusion queries go through a different code path
310        than standard rendering, the pixels rendered may be different.
311
312        However, the invariance issues are difficult at best to solve.
313        Because of the vagaries of floating-point precision, it is
314        difficult to guarantee that rendering a bounding box will render
315        at least as many pixels with equal or smaller Z values than the
316        object itself would have rendered.
317
318        Likewise, many other aspects of rendering state tend to be
319        different when performing an occlusion query.  Color and depth
320        writes are typically disabled, as are texturing, vertex programs,
321        and any fancy per-pixel math.  So unless all these features have
322        guarantees of invariance themselves (unlikely at best), requiring
323        invariance for NV_occlusion_query would be futile.
324
325        For what it's worth, NVIDIA's implementation is fully invariant
326        with respect to whether an occlusion query is active; that is, it
327        does not affect the operation of any other stage of the pipeline.
328        (When occlusion queries are being emulated on hardware that does
329        not support them, via the emulation registry keys, using an
330        occlusion query produces a software rasteriation fallback, and in
331        such cases invariance cannot be guaranteed.)
332
333        Another problem that can threaten correctness is near and far
334        clipping.  If the bounding box penetrates the near clip plane,
335        for example, it may be clipped away, reducing the number of
336        pixels counted, when in fact the original object may have stayed
337        entirely beyond the near clip plane.  Whenever you design an
338        algorithm using occlusion queries, it is best to be careful about
339        the near and far clip planes.
340
341    *   How can frame-to-frame coherency help applications using this
342        extension get even higher performance?
343
344        Usually, if an object is visible one frame, it will be visible
345        the next frame, and if it is not visible, it will not be visible
346        the next frame.
347
348        Of course, for most applications, "usually" isn't good enough.
349        It is undesirable, but acceptable, to render an object that
350        wasn't visible, because that only costs performance.  It is
351        generally unacceptable to not render an object that was visible.
352
353        The simplest approach is that visible objects should be checked
354        every N frames (where, say, N=5) to see if they have become
355        occluded, while objects that were occluded last frame must be
356        rechecked again in the current frame to guarantee that they are
357        still occluded.  This will reduce the number of wasteful
358        occlusion queries by a factor of almost N.
359
360        It may also pay to do a raycast on the CPU in order to try to
361        prove that an object is visible.  After all, occlusion queries
362        are only one of many items in your bag of tricks to decide
363        whether objects are visible or invisible.  They are not an excuse
364        to skip frustum culling, or precomputing visibility using portals
365        for static environments, or other standard visibility techniques.
366
367        In general, though, taking advantage of frame-to-frame coherency
368        in your occlusion query code is absolutely essential to getting
369        the best possible performance.
370
371New Procedures and Functions
372
373    void GenOcclusionQueriesNV(sizei n, uint *ids);
374    void DeleteOcclusionQueriesNV(sizei n, const uint *ids);
375    boolean IsOcclusionQueryNV(uint id);
376    void BeginOcclusionQueryNV(uint id);
377    void EndOcclusionQueryNV(void);
378    void GetOcclusionQueryivNV(uint id, enum pname, int *params);
379    void GetOcclusionQueryuivNV(uint id, enum pname, uint *params);
380
381New Tokens
382
383    Accepted by the <cap> parameter of Enable, Disable, and IsEnabled,
384    and by the <pname> parameter of GetBooleanv, GetIntegerv, GetFloatv,
385    and GetDoublev:
386
387        OCCLUSION_TEST_HP                              0x8165
388
389    Accepted by the <pname> parameter of GetBooleanv, GetIntegerv,
390    GetFloatv, and GetDoublev:
391
392        OCCLUSION_TEST_RESULT_HP                       0x8166
393        PIXEL_COUNTER_BITS_NV                          0x8864
394        CURRENT_OCCLUSION_QUERY_ID_NV                  0x8865
395
396    Accepted by the <pname> parameter of GetOcclusionQueryivNV and
397    GetOcclusionQueryuivNV:
398
399        PIXEL_COUNT_NV                                 0x8866
400        PIXEL_COUNT_AVAILABLE_NV                       0x8867
401
402Additions to Chapter 2 of the OpenGL 1.3 Specification (OpenGL Operation)
403
404    None.
405
406Additions to Chapter 3 of the OpenGL 1.3 Specification (Rasterization)
407
408    None.
409
410Additions to Chapter 4 of the OpenGL 1.3 Specification (Per-Fragment
411Operations and the Frame Buffer)
412
413    Add a new section "Occlusion Tests and Queries" between sections
414    4.1.6 and 4.1.7:
415
416    "4.1.6A  Occlusion Tests and Queries
417
418    Occlusion testing keeps track of whether any pixels have passed the
419    depth test.  Such testing is enabled or disabled with the generic
420    Enable and Disable commands using the symbolic constant
421    OCCLUSION_TEST_HP.  The occlusion test result is initially FALSE.
422
423    Occlusion queries can be used to track the exact number of fragments
424    that pass the depth test.  Occlusion queries are associated with
425    occlusion query objects.  The command
426
427      void GenOcclusionQueriesNV(sizei n, uint *ids);
428
429    returns n previously unused occlusion query names in ids.  These
430    names are marked as used, but no object is associated with them until
431    the first time BeginOcclusionQueryNV is called on them.  Occlusion
432    queries contain one piece of state, a pixel count result.  This pixel
433    count result is initialized to zero when the object is created.
434
435    Occlusion queries are deleted by calling
436
437      void DeleteOcclusionQueriesNV(sizei n, const uint *ids);
438
439    ids contains n names of occlusion queries to be deleted.  After an
440    occlusion query is deleted, its name is again unused.  Unused names
441    in ids are silently ignored.
442
443    An occlusion query can be started and finished by calling
444
445      void BeginOcclusionQueryNV(uint id);
446      void EndOcclusionQueryNV(void);
447
448    If BeginOcclusionQueryNV is called with an unused id, that id is
449    marked as used and associated with a new occlusion query object.  If
450    it is called while another occlusion query is active, an
451    INVALID_OPERATION error is generated.  If EndOcclusionQueryNV is
452    called while no occlusion query is active, an INVALID_OPERATION error
453    is generated.  Calling either GenOCclusionQueriesNV or
454    DeleteOcclusionQueriesNV while an occlusion query is active causes an
455    INVALID_OPERATION error to be generated.
456
457    When EndOcclusionQueryNV is called, the current pixel counter is
458    copied into the active occlusion query object's pixel count result.
459    BeginOcclusionQueryNV resets the pixel counter to zero and the
460    occlusion test result to FALSE.
461
462    Whenever a fragment reaches this stage and OCCLUSION_TEST_HP is
463    enabled or an occlusion query is active, the occlusion test result is
464    set to TRUE and the pixel counter is incremented.  If the value of
465    SAMPLE_BUFFERS is 1, then the pixel counter is incremented by the
466    number of samples whose coverage bit is set; otherwise, it is always
467    incremented by one.  If it the pixel counter overflows, i.e., exceeds
468    the value 2^PIXEL_COUNTER_BITS_NV-1, its value becomes undefined.
469    It is recommended, but not required, that implementations handle this
470    overflow case by saturating at 2^PIXEL_COUNTER_BITS_NV-1 and
471    incrementing no further.
472
473    The necessary state is a single bit indicating whether the occlusion
474    test is enabled, a single bit indicating whether an occlusion query
475    is active, the identifier of the currently active occlusion query, a
476    counter of no smaller than 24 bits keeping track of the pixel count,
477    and a single bit indicating the occlusion test result."
478
479Additions to Chapter 5 of the OpenGL 1.3 Specification (Special Functions)
480
481    Add to the end of Section 5.4 "Display Lists":
482
483    "DeleteOcclusionQueriesNV, GenOcclusionQueriesNV, IsOcclusionQueryNV,
484    GetOcclusionQueryivNV, and GetOcclusionQueryuivNV are not complied
485    into display lists but are executed immediately."
486
487Additions to Chapter 6 of the OpenGL 1.3 Specification (State and
488State Requests)
489
490    Add a new section 6.1.13 "Occlusion Test and Occlusion Queries":
491
492    "The occlusion test result can be queried using GetBooleanv,
493    GetIntegerv, GetFloatv, or GetDoublev with a <pname> of
494    OCCLUSION_TEST_RESULT_HP.  Whenever such a query is performed, the
495    occlusion test result is reset to FALSE and the pixel counter is
496    reset to zero as a side effect.
497
498    Which occlusion query is active can be queried using GetBooleanv,
499    GetIntegerv, GetFloatv, or GetDoublev with a <pname> of
500    CURRENT_OCCLUSION_QUERY_ID_NV.  This query returns the name of the
501    currently active occlusion query if one is active, and zero
502    otherwise.
503
504    The state of an occlusion query can be queried with the commands
505
506      void GetOcclusionQueryivNV(uint id, enum pname, int *params);
507      void GetOcclusionQueryuivNV(uint id, enum pname, uint *params);
508
509    If the occlusion query object named by id is currently active, then
510    an INVALID_OPERATION error is generated.
511
512    If <pname> is PIXEL_COUNT_NV, then the occlusion query's pixel count
513    result is placed in params.
514
515    Often, occlusion query results will be returned asychronously with
516    respect to the host processor's operation.  As a result, sometimes,
517    if a pixel count is queried, the host must wait until the result is
518    back.  If <pname> is PIXEL_COUNT_AVAILABLE_NV, the value placed in
519    params indicates whether or not such a wait would occur if the pixel
520    count for that occlusion query were to be queried presently.  A
521    result of TRUE means no wait would be required; a result of FALSE
522    means that some wait would occur.  The length of this wait is
523    potentially unbounded.  It must always be true that if the result for
524    one occlusion query is available, the result for all previous
525    occlusion queries must also be available at that point in time."
526
527GLX Protocol
528
529    Seven new GL commands are added.
530
531    The following two rendering commands are sent to the server as part
532    of a glXRender request:
533
534        BeginOcclusionQueryNV
535            2           8               rendering command length
536            2           ????            rendering command opcode
537            4           CARD32          id
538
539        EndOcclusionQueryNV
540            2           4               rendering command length
541            2           ????            rendering command opcode
542
543    The remaining fivecommands are non-rendering commands.  These
544    commands are sent separately (i.e., not as part of a glXRender or
545    glXRenderLarge request), using the glXVendorPrivateWithReply
546    request:
547
548        DeleteOcclusionQueriesNV
549            1           CARD8           opcode (X assigned)
550            1           17              GLX opcode (glXVendorPrivateWithReply)
551            2           4+n             request length
552            4           ????            vendor specific opcode
553            4           GLX_CONTEXT_TAG context tag
554            4           INT32           n
555            n*4         LISTofCARD32    ids
556
557        GenOcclusionQueriesNV
558            1           CARD8           opcode (X assigned)
559            1           17              GLX opcode (glXVendorPrivateWithReply)
560            2           4               request length
561            4           ????            vendor specific opcode
562            4           GLX_CONTEXT_TAG context tag
563            4           INT32           n
564          =>
565            1           1               reply
566            1                           unused
567            2           CARD16          sequence number
568            4           n               reply length
569            24                          unused
570            n*4         LISTofCARD322   queries
571
572        IsOcclusionQueryNV
573            1           CARD8           opcode (X assigned)
574            1           17              GLX opcode (glXVendorPrivateWithReply)
575            2           4               request length
576            4           ????            vendor specific opcode
577            4           GLX_CONTEXT_TAG context tag
578            4           CARD32          id
579          =>
580            1           1               reply
581            1                           unused
582            2           CARD16          sequence number
583            4           0               reply length
584            4           BOOL32          return value
585            20                          unused
586            1           1               reply
587
588        GetOcclusionQueryivNV
589            1           CARD8           opcode (X assigned)
590            1           17              GLX opcode (glXVendorPrivateWithReply)
591            2           5               request length
592            4           ????            vendor specific opcode
593            4           GLX_CONTEXT_TAG context tag
594            4           CARD32          id
595            4           ENUM            pname
596          =>
597            1           1               reply
598            1                           unused
599            2           CARD16          sequence number
600            4           m               reply length, m=(n==1?0:n)
601            4                           unused
602            4           CARD32          n
603
604            if (n=1) this follows:
605
606            4           INT32           params
607            12                          unused
608
609            otherwise this follows:
610
611            16                          unused
612            n*4         LISTofINT32     params
613
614        GetOcclusionQueryuivNV
615            1           CARD8           opcode (X assigned)
616            1           17              GLX opcode (glXVendorPrivateWithReply)
617            2           5               request length
618            4           ????            vendor specific opcode
619            4           GLX_CONTEXT_TAG context tag
620            4           CARD32          id
621            4           ENUM            pname
622          =>
623            1           1               reply
624            1                           unused
625            2           CARD16          sequence number
626            4           m               reply length, m=(n==1?0:n)
627            4                           unused
628            4           CARD32          n
629
630            if (n=1) this follows:
631
632            4           CARD32          params
633            12                          unused
634
635            otherwise this follows:
636
637            16                          unused
638            n*4         LISTofCARD32    params
639
640Errors
641
642    The error INVALID_VALUE is generated if GenOcclusionQueriesNV is
643    called where n is negative.
644
645    The error INVALID_VALUE is generated if DeleteOcclusionQueriesNV is
646    called where n is negative.
647
648    The error INVALID_OPERATION is generated if GenOcclusionQueriesNV or
649    DeleteOcclusionQueriesNV is called when an occlusion query is active.
650
651    The error INVALID_OPERATION is generated if BeginOcclusionQueryNV is
652    called when an occlusion query is already active.
653
654    The error INVALID_OPERATION is generated if EndOcclusionQueryNV is
655    called when an occlusion query is not active.
656
657    The error INVALID_OPERATION is generated if GetOcclusionQueryivNV or
658    GetOcclusionQueryuivNV is called where id is not the name of an
659    occlusion query.
660
661    The error INVALID_OPERATION is generated if GetOcclusionQueryivNV or
662    GetOcclusionQueryuivNV is called where id is the name of the
663    currently active occlusion query.
664
665    The error INVALID_ENUM is generated if GetOcclusionQueryivNV or
666    GetOcclusionQueryuivNV is called where pname is not either
667    PIXEL_COUNT_NV or PIXEL_COUNT_AVAILABLE_NV.
668
669    The error INVALID_OPERATION is generated if any of the commands
670    defined in this extension is executed between the execution of Begin
671    and the corresponding execution of End.
672
673New State
674
675(table 6.18, p. 226)
676
677    Get Value                      Type    Get Command     Initial Value   Description              Sec     Attribute
678    ---------                      ----    -----------     -------------   -----------              ------  ---------
679    OCCLUSION_TEST_HP              B       IsEnabled       FALSE           occlusion test enable    4.1.6A  enable
680    OCCLUSION_TEST_RESULT_HP       B       GetBooleanv     FALSE           occlusion test result    4.1.6A  -
681    -                              B       GetBooleanv     FALSE           occlusion query active   4.1.6A  -
682    CURRENT_OCCLUSION_QUERY_ID_NV  Z+      GetIntegerv     0               occlusion query ID       4.1.6A  -
683    -                              Z+      -               0               pixel counter            4.1.6A  -
684
685New Implementation Dependent State
686
687(table 6.29, p. 237) Add the following entry:
688
689    Get Value                    Type    Get Command   Minimum Value   Description         Sec     Attribute
690    --------------------------   ----    -----------   -------------   ----------------    ------  --------------
691    PIXEL_COUNTER_BITS_NV        Z+      GetIntegerv   24              Number of bits in   6.1.13  -
692                                                                       pixel counters
693
694Revision History
695
696    none yet
697