• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1Name
2
3    EXT_occlusion_query_boolean
4
5Name Strings
6
7    GL_EXT_occlusion_query_boolean
8
9Contributors
10
11    All those who have contributed to the definition of occlusion
12    query functionality in the OpenGL ARB and OpenGL ES workgroups,
13    upon which this extension spec is entirely dependent.
14
15Contact
16
17    Benj Lipchak, Apple (lipchak 'at' apple.com)
18
19Status
20
21    Complete
22
23Version
24
25    Date: July 22, 2011
26    Revision: 2
27
28Number
29
30    OpenGL ES Extension #100
31
32Dependencies
33
34    Written based on the wording of the OpenGL ES 2.0.25 Full Specification
35    (November 2, 2010).
36
37Overview
38
39    This extension defines a mechanism whereby an application can
40    query whether any pixels (or, more precisely, samples) are drawn
41    by a primitive or group of primitives.
42
43    The primary purpose of such a query (hereafter referred to as an
44    "occlusion query") is to determine the visibility of an object.
45    Typically, the application will render the major occluders in the
46    scene, then perform an occlusion query for each detail object in
47    the scene. On subsequent frames, the previous results of the
48    occlusion queries can be used to decide whether to draw an object
49    or not.
50
51New Procedures and Functions
52
53    void GenQueriesEXT(sizei n, uint *ids);
54    void DeleteQueriesEXT(sizei n, const uint *ids);
55    boolean IsQueryEXT(uint id);
56    void BeginQueryEXT(enum target, uint id);
57    void EndQueryEXT(enum target);
58    void GetQueryivEXT(enum target, enum pname, int *params);
59    void GetQueryObjectuivEXT(uint id, enum pname, uint *params);
60
61New Tokens
62
63    Accepted by the <target> parameter of BeginQueryEXT, EndQueryEXT,
64    and GetQueryivEXT:
65
66        ANY_SAMPLES_PASSED_EXT                         0x8C2F
67        ANY_SAMPLES_PASSED_CONSERVATIVE_EXT            0x8D6A
68
69    Accepted by the <pname> parameter of GetQueryivEXT:
70
71        CURRENT_QUERY_EXT                              0x8865
72
73    Accepted by the <pname> parameter of GetQueryObjectivEXT and
74    GetQueryObjectuivEXT:
75
76        QUERY_RESULT_EXT                               0x8866
77        QUERY_RESULT_AVAILABLE_EXT                     0x8867
78
79Additions to Chapter 2 of the OpenGL ES 2.0 Specification (OpenGL ES Operation)
80
81    Add a new section "Asynchronous Queries" between sections 2.12 and 2.13
82    and renumber subsequent sections:
83
84    "2.13 Asynchronous Queries
85
86    Asynchronous queries provide a mechanism to return information about the
87    processing of a sequence of GL commands. There is one query type
88    supported by the GL. Occlusion queries (see section 4.1.6) set a boolean
89    to true when any fragments or samples pass the depth test.
90
91    The results of asynchronous queries are not returned by the GL immediately
92    after the completion of the last command in the set; subsequent commands
93    can be processed while the query results are not complete. When available,
94    the query results are stored in an associated query object. The commands
95    described in section 6.1.6 provide mechanisms to determine when query
96    results are available and return the actual results of the query. The
97    name space for query objects is the unsigned integers, with zero reserved
98    by the GL.
99
100    Each type of query supported by the GL has an active query object name. If
101    the active query object name for a query type is non-zero, the GL is
102    currently tracking the information corresponding to that query type and the
103    query results will be written into the corresponding query object. If the
104    active query object for a query type name is zero, no such information is
105    being tracked.
106
107    A query object is created and made active by calling
108
109        void BeginQueryEXT(enum target, uint id);
110
111    <target> indicates the type of query to be performed; valid values of
112    <target> are defined in subsequent sections. If the query object name <id>
113    has not been created, the name is marked as used and associated with a new
114    query object of the type specified by <target>. Otherwise <id> must be the
115    name of an existing query object of that type.
116
117    BeginQueryEXT fails and an INVALID_OPERATION error is generated if <id>
118    is not a name returned from a previous call to GenQueriesEXT, or if such
119    a name has since been deleted with DeleteQueriesEXT.
120
121    BeginQueryEXT sets the active query object name for the query type given
122    by <target> to <id>. If BeginQueryEXT is called with an <id> of zero, if
123    the active query object name for <target> is non-zero (for the targets
124    ANY_SAMPLES_PASSED_EXT and ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, if the
125    active query for either target is non-zero), if <id> is the name of an
126    existing query object whose type does not match <target>, or if <id> is the
127    active query object name for any query type, the error INVALID_OPERATION is
128    generated.
129
130    The command
131
132        void EndQueryEXT(enum target);
133
134    marks the end of the sequence of commands to be tracked for the query type
135    given by <target>. The active query object for <target> is updated to
136    indicate that query results are not available, and the active query object
137    name for <target> is reset to zero. When the commands issued prior to
138    EndQueryEXT have completed and a final query result is available, the
139    query object active when EndQueryEXT is called is updated by the GL. The
140    query object is updated to indicate that the query results are available
141    and to contain the query result. If the active query object name for
142    <target> is zero when EndQueryEXT is called, the error INVALID_OPERATION
143    is generated.
144
145    The command
146
147        void GenQueriesEXT(sizei n, uint *ids);
148
149    returns <n> previously unused query object names in <ids>. These names are
150    marked as used, for the purposes of GenQueriesEXT only, but no object is
151    associated with them until the first time they are used by BeginQueryEXT.
152
153    Query objects are deleted by calling
154
155        void DeleteQueriesEXT(sizei n, const uint *ids);
156
157    <ids> contains <n> names of query objects to be deleted. After a query
158    object is deleted, its name is again unused. Unused names in <ids> are
159    silently ignored, as is the value zero. If an active query object is
160    deleted its name immediately becomes unused, but the underlying object is
161    not deleted until it is no longer active (see section C.1).
162
163    Query objects contain two pieces of state: a single bit indicating whether
164    a query result is available, and an integer containing the query result
165    value. The number of bits used to represent the query result is
166    implementation-dependent and may vary by query object type. In the initial
167    state of a query object, the result is available and its value is zero.
168
169    The necessary state for each query type is an unsigned integer holding the
170    active query object name (zero if no query object is active), and any state
171    necessary to keep the current results of an asynchronous query in progress.
172    Only a single type of occlusion query can be active at one time, so the
173    required state for occlusion queries is shared."
174
175Additions to Chapter 3 of the OpenGL ES 2.0 Specification (Rasterization)
176
177    None
178
179Additions to Chapter 4 of the OpenGL ES 2.0 Specification (Per-Fragment
180Operations and the Frame Buffer)
181
182    Add a new section "Occlusion Queries" between sections 4.1.5 and
183    4.1.6 and renumber subsequent sections:
184
185    "4.1.6  Occlusion Queries
186
187    Occlusion queries use query objects to track the number of fragments or
188    samples that pass the depth test. An occlusion query can be started and
189    finished by calling BeginQueryEXT and EndQueryEXT, respectively, with a
190    target of ANY_SAMPLES_PASSED_EXT or ANY_SAMPLES_PASSED_CONSERVATIVE_EXT.
191
192    When an occlusion query is started with the target
193    ANY_SAMPLES_PASSED_EXT, the samples-boolean state maintained by the GL is
194    set to FALSE. While that occlusion query is active, the samples-boolean
195    state is set to TRUE if any fragment or sample passes the depth test. When
196    the occlusion query finishes, the samples-boolean state of FALSE or TRUE is
197    written to the corresponding query object as the query result value, and
198    the query result for that object is marked as available. If the target of
199    the query is ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, an implementation may
200    choose to use a less precise version of the test which can additionally set
201    the samples-boolean state to TRUE in some other implementation dependent
202    cases."
203
204Additions to Chapter 5 of the OpenGL ES 2.0 Specification (Special Functions)
205
206    None
207
208Additions to Chapter 6 of the OpenGL ES 2.0 Specification (State and
209State Requests)
210
211    Add a new section "Asynchronous Queries" between sections 6.1.5 and
212    6.1.6 and renumber subsequent sections:
213
214    "6.1.6  Asynchronous Queries
215
216    The command
217
218      boolean IsQueryEXT(uint id);
219
220    returns TRUE if <id> is the name of a query object.  If <id> is zero,
221    or if <id> is a non-zero value that is not the name of a query
222    object, IsQueryEXT returns FALSE.
223
224    Information about a query target can be queried with the command
225
226      void GetQueryivEXT(enum target, enum pname, int *params);
227
228    <target> identifies the query target, and must be one of
229    ANY_SAMPLES_PASSED_EXT or ANY_SAMPLES_PASSED_CONSERVATIVE_EXT.
230
231    <pname> must be CURRENT_QUERY_EXT. The name of the currently active
232    query for <target>, or zero if no query is active, will be placed in
233    <params>.
234
235    The state of a query object can be queried with the command
236
237      void GetQueryObjectuivEXT(uint id, enum pname, uint *params);
238
239    If <id> is not the name of a query object, or if the query object
240    named by <id> is currently active, then an INVALID_OPERATION error is
241    generated. <pname> must be QUERY_RESULT_EXT or QUERY_RESULT_AVAILABLE_EXT.
242
243    If <pname> is QUERY_RESULT_EXT, then the query object's result value
244    is returned as a single integer in <params>. If the value is so large in
245    magnitude that it cannot be represented with the requested type, then the
246    nearest value representable using the requested type is returned.
247
248    There may be an indeterminate delay before the above query returns. If
249    <pname> is QUERY_RESULT_AVAILABLE_EXT, FALSE is returned if such a delay
250    would be required; otherwise TRUE is returned. It must always be true that
251    if any query object returns a result available of TRUE, all queries of the
252    same type issued prior to that query must also return TRUE.
253
254    Querying the state for any given query object forces that occlusion query
255    to complete within a finite amount of time. Repeatedly querying the
256    QUERY_RESULT_AVAILABLE_EXT state for any given query object is guaranteed
257    to return true eventually. Note that multiple queries to the same occlusion
258    object may result in a significant performance loss. For better performance
259    it is recommended to wait N frames before querying this state. N is
260    implementation dependent but is generally between one and three.
261
262    If multiple queries are issued using the same object name prior to calling
263    GetQueryObjectuivEXT, the result and availability information returned
264    will always be from the last query issued. The results from any queries
265    before the last one will be lost if they are not retrieved before starting
266    a new query on the same <target> and <id>."
267
268Additions to Appendix C of the OpenGL ES 2.0 Specification (Shared Object and
269Multiple Contexts)
270
271    Change the first sentence of the first paragraph of section C.1.2 to read:
272
273    "When a buffer, texture, renderbuffer, or query is deleted, ..."
274
275    Add the following sentence to the end of section C.1.2:
276
277    "A query object is in use so long as it is the active query object for a
278    query type and index, as described in section 2.13."
279
280Errors
281
282    The error INVALID_OPERATION is generated if BeginQueryEXT is called
283    where <id> is not a name returned from a previous call to GenQueriesEXT,
284    or if such a name has since been deleted with DeleteQueriesEXT.
285
286    The error INVALID_OPERATION is generated if BeginQueryEXT is called
287    where <id> is zero.
288
289    The error INVALID_OPERATION is generated if BeginQueryEXT is called
290    where <id> is the name of an existing query object whose type does not
291    match <target>.
292
293    The error INVALID_OPERATION is generated if BeginQueryEXT is called
294    where <id> is the active query object name for any query type.
295
296    The error INVALID_OPERATION is generated if BeginQueryEXT is called
297    when the active query object name for either ANY_SAMPLES_PASSED_EXT or
298    ANY_SAMPLES_PASSED_CONSERVATIVE_EXT is non-zero.
299
300    The error INVALID_OPERATION is generated if EndQueryEXT is called
301    when the active query object name for <target> is zero.
302
303    The error INVALID_OPERATION is generated if GetQueryObjectuivEXT is
304    called where <id> is not the name of a query object.
305
306    The error INVALID_OPERATION is generated if GetQueryObjectuivEXT is
307    called where <id> is the name of a currently active query object.
308
309    The error INVALID_VALUE is generated if GenQueriesEXT is called where
310    <n> is negative.
311
312    The error INVALID_VALUE is generated if DeleteQueriesEXT is called
313    where <n> is negative.
314
315    The error INVALID_ENUM is generated if BeginQueryEXT, EndQueryEXT,
316    or GetQueryivEXT is called where <target> is not
317    ANY_SAMPLES_PASSED_EXT or ANY_SAMPLES_PASSED_CONSERVATIVE_EXT.
318
319    The error INVALID_ENUM is generated if GetQueryivEXT is called where
320    <pname> is not CURRENT_QUERY_EXT.
321
322    The error INVALID_ENUM is generated if GetQueryObjectuivEXT is called
323    where <pname> is not QUERY_RESULT_EXT or QUERY_RESULT_AVAILABLE_EXT.
324
325New State
326
327(table 6.18, p. 233)
328
329                                                            Int'l
330    Get Value                   Type  Get Command           Value  Description             Sec
331    --------------------------  ----  --------------------  -----  ----------------------  -----
332    -                           B     -                     FALSE  query active            4.1.6
333    CURRENT_QUERY_EXT           Z+    GetQueryivEXT         0      active query ID         4.1.6
334    QUERY_RESULT_EXT            B     GetQueryObjectuivEXT  FALSE  samples-passed          4.1.6
335    QUERY_RESULT_AVAILABLE_EXT  B     GetQueryObjectuivEXT  FALSE  query result available  4.1.6
336
337Issues
338
339    (1)  What should the enum be called?
340
341        RESOLVED: The enum should be called ANY_SAMPLES_PASSED as in
342        ARB_occlusion_query2 to retain compatibility between the two
343        extensions.
344
345    (2)  Can application-provided names be used as query object names?
346
347        ARB_occlusion_query allows application-provided names, but this
348        was later removed in core OpenGL.
349
350        RESOLVED: No, we will follow core OpenGL on this.
351
352    (3)  Should calling GenQueries or DeleteQueries when a query is
353         active produce an error?
354
355        This behavior is in ARB_occlusion_query but was
356        removed in OpenGL 3.0.
357
358        RESOLVED: Not an error.  Calling DeleteQueries marks the name
359        as no longer used, but the object is not deleted until it is no
360        longer in use (i.e. no longer active).
361
362    (4)  What is the interaction with multisample?
363
364        RESOLVED: The query result is set to true if at least one
365        sample passes the depth test.
366
367    (5)  Exactly what stage in the pipeline are we counting samples at?
368
369        RESOLVED: We are counting immediately after _both_ the depth and
370        stencil tests, i.e., samples that pass both.  Note that the depth
371        test comes after the stencil test, so to say that it is the
372        number that pass the depth test is sufficient; though it is often
373        conceptually helpful to think of the depth and stencil tests as
374        being combined, because the depth test's result impacts the
375        stencil operation used.
376
377    (6)  Is it guaranteed that occlusion queries return in order?
378
379        RESOLVED: Yes.
380
381        If occlusion test X occurred before occlusion query Y, and the driver
382        informs the app that occlusion query Y is done, the app can infer that
383        occlusion query X is also done.
384
385    (7) Will polling a query for QUERY_RESULT_AVAILABLE without a Flush
386        possibly cause an infinite loop?
387
388        RESOLVED: No.
389
390    (8) Should there be a "target" parameter to BeginQuery?
391
392        RESOLVED: Yes.  This distinguishes the boolean queries
393        defined by this extension (and ARB_occlusion_query2) from
394        the counter queries defined by ARB_occlusion_query.
395
396    (9) Are query objects shareable between multiple contexts?
397
398        RESOLVED: No.  Query objects are lightweight and we normally share
399        large data across contexts.  Also, being able to share query objects
400        across contexts is not particularly useful.  In order to do the async
401        query across contexts, a query on one context would have to be finished
402        before the other context could query it.
403
404    (10) Should there be a limit on how many queries can be outstanding?
405
406        RESOLVED: No. If an implementation has an internal limit, it can
407        flush the pipeline when it runs out.
408
409    (11) Can an implementation sometimes return a conservative result,
410         i.e. return true even though no samples were drawn?
411
412        RESOLVED: Yes, but only when explicitly enabled by the
413        application.
414
415        Allowing such results with no restrictions effectively makes
416        the functionality of the extension optional, which decreases
417        its value. Precise restrictions are presumably hard to
418        specify.
419
420        One situation where this restriction could be relevant is if
421        an implementation performs a conservative early depth test at
422        a lower precision and wants to base the occlusion query result
423        on that whenever the early depth test can be used.
424
425    (12) Should the restrictions in issue 11 be explicitly enabled
426         by the application in order to be in effect?
427
428        RESOLVED: Yes.
429
430        The restrictions could be enabled by a hint call or by using
431        a different enum in the BeginQuery call.
432
433        This would enable the application to choose whether it wants a
434        precise (but possibly slow) version or an approximate (but
435        possibly faster) version.
436
437    (13) Can the restrictions in issue 18 be applied nondeterministically?
438
439        An implementation might benefit from taking the decision of
440        whether to apply a particular restriction on a case by case
441        basis. Some of these decisions could depend on
442        nondeterministic effects such as memory bus timing.
443
444        RESOLVED: No. This would violate the GL repeatability
445        principle.
446
447    (14) How does an application request that the result is allowed to
448         be conservative (as defined in issue 11)?
449
450        RESOLVED: It is specified as a separate query target,
451        ANY_SAMPLES_PASSED_CONSERVATIVE.
452
453
454Revision History
455
456   Date: 5/03/2011
457   Revision: 1 (Benj Lipchak)
458      - Initial draft based on XXX_occlusion_query_boolean
459
460   Date: 7/22/2011
461   Revision: 2 (Benj Lipchak)
462      - Rename from APPLE to EXT
463