1Name 2 3 ARB_occlusion_query 4 5Name Strings 6 7 GL_ARB_occlusion_query 8 9Contributors 10 11 Ross Cunniff 12 Matt Craighead 13 Daniel Ginsburg 14 Kevin Lefebvre 15 Bill Licea-Kane 16 Nick Triantos 17 18Contact 19 20 Matt Craighead, NVIDIA Corporation (mcraighead 'at' nvidia.com) 21 Daniel Ginsburg, AMD (dan.ginsburg 'at' amd.com) 22 23Notice 24 25 Copyright (c) 2003-2013 The Khronos Group Inc. Copyright terms at 26 http://www.khronos.org/registry/speccopyright.html 27 28Specification Update Policy 29 30 Khronos-approved extension specifications are updated in response to 31 issues and bugs prioritized by the Khronos OpenGL Working Group. For 32 extensions which have been promoted to a core Specification, fixes will 33 first appear in the latest version of that core Specification, and will 34 eventually be backported to the extension document. This policy is 35 described in more detail at 36 https://www.khronos.org/registry/OpenGL/docs/update_policy.php 37 38IP Status 39 40 HP has claimed that they hold IP around use of this extension. HP 41 has committed to releasing rights to this IP to the ARB if the 42 functionality is included in OpenGL (April 10, 2003). 43 44Status 45 46 Approved by the ARB (version 1.0), June 10, 2003, pending further minor 47 revisions 48 49Version 50 51 Date: April 21, 2007 52 Revision: 7 53 $Id$ 54 55Number 56 57 ARB Extension #29 58 59Dependencies 60 61 Written based on the wording of the OpenGL 1.4 specification. 62 63 HP_occlusion_test affects the definition of this extension. 64 65Overview 66 67 This extension defines a mechanism whereby an application can query 68 the number of pixels (or, more precisely, samples) drawn by a 69 primitive or group of primitives. 70 71 The primary purpose of such a query (hereafter referred to as an 72 "occlusion query") is to determine the visibility of an object. 73 Typically, the application will render the major occluders in the 74 scene, then perform an occlusion query for the bounding box of each 75 detail object in the scene. Only if said bounding box is visible, 76 i.e., if at least one sample is drawn, should the corresponding object 77 be drawn. 78 79 The earlier HP_occlusion_test extension defined a similar mechanism, 80 but it had two major shortcomings. 81 82 - It returned the result as a simple GL_TRUE/GL_FALSE result, when in 83 fact it is often useful to know exactly how many samples were 84 drawn. 85 - It provided only a simple "stop-and-wait" model for using multiple 86 queries. The application begins an occlusion test and ends it; 87 then, at some later point, it asks for the result, at which point 88 the driver must stop and wait until the result from the previous 89 test is back before the application can even begin the next one. 90 This is a very simple model, but its performance is mediocre when 91 an application wishes to perform many queries, and it eliminates 92 most of the opportunities for parallelism between the CPU and GPU. 93 94 This extension solves both of those problems. It returns as its 95 result the number of samples that pass the depth and stencil tests, 96 and it encapsulates occlusion queries in "query objects" that allow 97 applications to issue many queries before asking for the result of 98 any one. As a result, they can overlap the time it takes for the 99 occlusion query results to be returned with other, more useful work, 100 such as rendering other parts of the scene or performing other 101 computations on the CPU. 102 103 There are many situations where a pixel/sample count, rather than a 104 boolean result, is useful. 105 106 - Objects that are visible but cover only a very small number of 107 pixels can be skipped at a minimal reduction of image quality. 108 - Knowing exactly how many pixels an object might cover may help the 109 application decide which level-of-detail model should be used. If 110 only a few pixels are visible, a low-detail model may be 111 acceptable. 112 - "Depth peeling" techniques, such as order-independent transparency, 113 need to know when to stop rendering more layers; it is difficult to 114 determine a priori how many layers are needed. A boolean result 115 allows applications to stop when more layers will not affect the 116 image at all, but this will likely result in unacceptable 117 performance. Instead, it makes more sense to stop rendering when 118 the number of pixels in each layer falls below a given threshold. 119 - Occlusion queries can replace glReadPixels of the depth buffer to 120 determine whether (for example) a light source is visible for the 121 purposes of a lens flare effect or a halo to simulate glare. Pixel 122 counts allow you to compute the percentage of the light source that 123 is visible, and the brightness of these effects can be modulated 124 accordingly. 125 126Issues 127 128 How is this extension different from NV_occlusion_query? 129 130 The following changes have been made. 131 - A "target" parameter has been added. Only one target exists at 132 present, SAMPLES_PASSED_ARB, but future extensions could add 133 additional types of queries. 134 - Terminology changed slightly. "Pixel" was being used 135 incorrectly, where "fragment" or "sample" would be more 136 accurate. 137 - Various NVIDIA-specific references have been removed. 138 - Interactions with multisample have been changed slightly to 139 allow implementations based on either a sample count or a 140 fragment count. The result is returned in units of samples. 141 - Clarified that using an id of zero is illegal. 142 - Added missing spec language for IsQuery entry point. 143 - General language, issues, etc. cleanup. 144 - HP_occlusion_test is no longer required. 145 - Modified the minimum required counter bits to be dependent on 146 the implementation's maximum viewport or the value 0 147 - Clarified that active query state is per target server state. 148 This implies that a loop of QUERY_RESULT_AVAILABLE_ARB will 149 return TRUE in finite time. NV_occlusion_query asked 150 that the application flush to prevent an infinite loop. 151 - Clarified the behavior of the async QUERY_RESULT_AVAILABLE_ARB 152 command. 153 - When the count of samples that pass the occlusion query overflows, 154 the value should saturate. 155 156 Should we use an object-based interface? 157 158 RESOLVED: Yes, this makes the interface much simpler, and it is 159 friendly for indirect rendering. 160 161 What is the difference between a "query object" and an "occlusion 162 query"? 163 164 "Occlusion query" is a synonym for "query object used with target 165 SAMPLES_PASSED". 166 167 Should we offer a way to poll whether an occlusion query has 168 completed and its result is available? 169 170 RESOLVED. Yes, this allows applications to use CPU time that might 171 have been spent spinning more usefully. However, the polling 172 method introduced in the NV_occlusion_query spec allowed for a 173 potential infinite loop if the application does not do a flush. 174 This version of the spec clarifies the behavior which now makes such 175 a flush unnecessary. 176 177 Is GetQueryObjectuivARB necessary? 178 179 RESOLVED: Yes, it makes using a 32-bit count less painful. 180 181 Should there be a limit on how many queries can be outstanding? 182 183 RESOLVED: No. This would make the extension much more 184 difficult to spec and use. Allowing this does not add any 185 significant implementation burden; and even if drivers have some 186 internal limit on the number of outstanding queries, it is not 187 expected that applications will need to know this to achieve 188 optimal or near-optimal performance. 189 190 What happens if BeginQueryARB is called when a query is already 191 outstanding for a different object on the same target? 192 193 RESOLVED: This is an INVALID_OPERATION error. 194 195 What happens if BeginQueryARB is called with an ID of a query that is 196 already in progress? 197 198 RESOLVED: This is also an INVALID_OPERATION error. 199 200 What parameters should EndQueryARB have? 201 202 RESOLVED: Just a target. It doesn't need to take an "id" 203 argument, since this would be redundant -- only one query can be 204 active for any given target at a given time. 205 206 How many bits should we require the samples-passed count to be, at 207 minimum? 208 209 RESOLVED. The largest minimum that can be required of a GL 210 implementation is 32, the minimum bit width of an int or uint. 211 212 The minimum number of bits required for the samples-passed 213 count will be dependent on the implementation's maximum viewport size. 214 In order to allow for two overdraws in the case of only one sample 215 buffer, the minimum counter precision (n) will be determined by: 216 217 n = min (32 , ceil (log2 (maxViewportWidth x maxViewportHeight x 218 1 sample x 2 overdraws) ) ) 219 220 An implementation can either set QUERY_COUNTER_BITS_ARB to the 221 value 0, or to some number greater than or equal to n. If an 222 implementation returns 0 for QUERY_COUNTER_BITS_ARB, then the 223 occlusion queries will always return that zero samples passed the 224 occlusion test, and so an application should not use occlusion queries 225 on that implementation. 226 227 Note that other targets may come along in the future that require more 228 or fewer bits. 229 230 What should we do about overflows? 231 232 RESOLVED: Overflows are required to saturate, though it is expected 233 that several current implementations will not conform to this 234 requirement. 235 236 The ideal behavior is to saturate. This ensures that you always 237 get a "large" result when you render many samples. It also 238 ensures that apps which want a boolean test can do this without 239 worrying about the rare case where the result ends up exactly at 240 zero after wrapping. 241 242 Either way, it's unlikely that this matters much as long as a 243 sufficient number of bits are required. 244 245 What is the interaction with multisample? 246 247 RESOLVED: We count samples, not pixels -- even if MULTISAMPLE is 248 disabled but SAMPLE_BUFFERS is 1. 249 250 A given fragment may have anywhere between zero and SAMPLES of 251 its samples covered. Ideally, the samples-passed count would be 252 incremented by the precise number of samples, but we permit 253 implementations to instead increment the samples-passed count by 254 SAMPLES if at least one sample in a given fragment is covered. 255 256 Note that the depth/stencil test optimization whereby 257 implementations may choose to depth test at only one of the 258 samples when MULTISAMPLE is disabled does not cause this to 259 become ill-specified, because we are counting the number of 260 samples that are still alive _after_ the depth test stage. The 261 particular mechanism used to decide whether to kill or keep those 262 samples is not relevant. 263 264 Exactly what stage in the pipeline are we counting samples at? 265 266 RESOLVED: We are counting immediately after _both_ the depth and 267 stencil tests, i.e., samples that pass both. Note that the depth 268 test comes after the stencil test, so to say that it is the 269 number that pass the depth test is sufficient; though it is often 270 conceptually helpful to think of the depth and stencil tests as 271 being combined, because the depth test's result impacts the 272 stencil operation used. 273 274 Is it guaranteed that occlusion queries return in order? 275 276 RESOLVED: Yes. It makes sense to do this. If occlusion test X 277 occurred before occlusion query Y, and the driver informs the app 278 that occlusion query Y is done, the app can infer that occlusion 279 query X is also done. For applications that do poll, this allows 280 them to do so with less effort. 281 282 Will polling a query without a Flush possibly cause an infinite loop? 283 284 RESOLVED: No. An infinite loop was possible in the original 285 NV_occlusion_query spec if an application did not perform a 286 flush prior to polling. This behavior was removed in this version 287 of the spec as it violated language in the core GL spec. 288 289 Instead of allowing for an infinite loop, performing a 290 QUERY_RESULT_AVAILABLE_ARB will perform a flush if the result 291 is not ready yet on the first time it is queried. This ensures 292 that the async query will return true in finite time. 293 294 This behavior is not a significant performance loss over the original 295 version of the spec. A flush would need to be performed at some 296 point anyway and the flush performed when QUERY_RESULT_AVAILABLE_ARB 297 is requested will only occur *if the result is not back yet*. 298 299 What should be the interaction between this spec and 300 HP_occlusion_test? 301 302 RESOLVED: Whereas NV_occlusion_query required that you implement 303 HP_occlusion_test, and even went so far as to specify the precise 304 behavior of HP_occlusion_test (since the HP_occlusion_test spec 305 did not contain those details), this spec does not. This spec 306 explains the interaction with HP_occlusion_test, but does not 307 attempt to double as a spec for that extension. 308 309 What happens if HP_occlusion_test and ARB_occlusion_query usage is 310 overlapped? 311 312 RESOLVED: The two can be overlapped safely. Counting is enabled 313 if either an occlusion query is active *or* OCCLUSION_TEST_HP is 314 enabled. The alternative (producing an error) does not work -- 315 it would require that PopAttrib be capable of producing an error, 316 which would be rather problematic. 317 318 Note that BeginQueryARB, not EndQueryARB, resets the sample 319 count (and therefore the occlusion test result). This can avoid 320 certain types of strange behavior where an occlusion query's 321 samples-passed count does not always correspond to the samples 322 rendered during the occlusion query. The spec would make sense 323 the other way, but the behavior would be strange. 324 325 Should there be a "target" parameter to BeginQueryARB? 326 327 RESOLVED: Yes. Whereas NV_occlusion_query wasn't trying to solve 328 a problem beyond simple occlusion queries, this extension creates 329 a framework useful for future queries. 330 331 Does GenQueriesARB need a "target" parameter? 332 333 RESOLVED: No. A query can be reused any number of times with any 334 targets. 335 336 How can one ask for the currently active query? 337 338 RESOLVED: A new entry point has been added to query information 339 about a given query target. This makes it unnecessary to add two 340 new enumerants (# of bits and current query ID) for each new 341 target that is introduced. 342 343 Are query objects shareable between multiple contexts? 344 345 RESOLVED: No. Query objects are lightweight and we normally share 346 large data across contexts. Also, being able to share query objects 347 across contexts is not particularly useful. In order to do the async 348 query across contexts, a query on one context would have to be finished 349 before the other context could query it. 350 351 What happens when an app begins a query on a target, ends it, begins 352 a query on the same target with the same id, ends it, and then tries 353 to retrieve data about the query using GetQueryObjecti[u]vARB? Which 354 query does the GetQueryObjecti[u]vARB return results for? 355 356 RESOLVED. In this case, the result retrieved from 357 GetQueryObjecti[u]vARB will be from the last query on that target and 358 id. The result returned from GetQueryObjecti[u]vARB will always be from 359 the last BeginQueryARB/EndQueryARB pair on that target and id. 360 361 Is this extension useful for saving geometry, fill rate, or both? 362 363 The answer to this question is to some extent implementation- 364 dependent, but it is expected that it is most useful for reducing 365 geometry workload, and less so for fill rate. 366 367 For the cost of rendering a bounding box, you can potentially 368 save rendering a normal object. A bounding box consists of only 369 12 triangles, whereas the original object might have contained 370 thousands or even millions of triangles. 371 372 Using bounding box occlusion queries may either help or hurt in 373 fill-limited situations, because rendering the pixels of a 374 bounding box is not free. In most situations, a bounding box 375 will probably have more pixels than the original object. Those 376 pixels can probably be rendered more quickly, though, since they 377 involve only Z reads (no Z writes or color traffic), and they 378 need not be textured or otherwise shaded. 379 380 In multipass rendering situations, however, occlusion queries can 381 almost always save fill rate, because wrapping an object with an 382 occlusion query is generally cheap. See "Usage Examples" for an 383 illustration. 384 385 What can be said about guaranteeing correctness when using 386 occlusion queries, especially as it relates to invariance? 387 388 Invariance is critical to guarantee the correctness of occlusion 389 queries. If occlusion queries go through a different code path 390 than standard rendering, the fragments rendered may be different. 391 392 However, the invariance issues are difficult at best to solve. 393 Because of the vagaries of floating-point precision, it is 394 difficult to guarantee that rendering a bounding box will render 395 at least as many pixels with equal or smaller Z values than the 396 object itself would have rendered. 397 398 Likewise, many other aspects of rendering state tend to be 399 different when performing an occlusion query. Color and depth 400 writes are typically disabled, as are texturing, vertex programs, 401 and any fancy per-fragment math. So unless all these features 402 have guarantees of invariance themselves (unlikely at best), 403 requiring invariance for ARB_occlusion_query would be futile. 404 405 In general, implementations are recommended to be fully invariant 406 with respect to whether any given type of query is active, 407 insofar as it is possible. That is, having an occlusion query 408 active should not affect the operation of any other stage of the 409 pipeline. Following this rule is essential to numerous occlusion 410 query algorithms working correctly. However, to permit 411 implementations where this feature is implemented in software, 412 this rule is only a recommendation, not a requirement. 413 414 Another unrelated problem that can threaten correctness is near 415 and far clipping. The bounding box of an object may penetrate 416 the near clip plane, even though the original object may not 417 have. In such a circumstance, a bounding box occlusion query may 418 produce an incorrect result. Whenever you design an algorithm 419 using occlusion queries, it is best to be careful about the near 420 and far clip planes. 421 422 How can frame-to-frame coherency help applications using this 423 extension get even higher performance? 424 425 Usually, if an object is visible one frame, it will be visible 426 the next frame, and if it is not visible, it will not be visible 427 the next frame. 428 429 Of course, for most applications, "usually" isn't good enough. 430 It is undesirable, but acceptable, to render an object that 431 *isn't* visible, because that only costs performance. It is 432 generally unacceptable to *not* render an object that *is* 433 visible. 434 435 The simplest approach is that visible objects should be checked 436 every N frames (where, say, N=5) to see if they have become 437 occluded, while objects that were occluded last frame must be 438 rechecked again in the current frame to guarantee that they are 439 still occluded. This will reduce the number of wasteful 440 occlusion queries by almost a factor of N. 441 442 Other, more complicated techniques exist but are beyond the scope 443 of this extension document. 444 445 Do occlusion queries make other visibility algorithms obsolete? 446 447 No. 448 449 Occlusion queries are helpful, but they are not a cure-all. They 450 should be only one of many items in your bag of tricks to decide 451 whether objects are visible or invisible. They are not an excuse 452 to skip frustum culling, or precomputing visibility using portals 453 for static environments, or other standard visibility techniques. 454 455New Procedures and Functions 456 457 void GenQueriesARB(sizei n, uint *ids); 458 void DeleteQueriesARB(sizei n, const uint *ids); 459 boolean IsQueryARB(uint id); 460 void BeginQueryARB(enum target, uint id); 461 void EndQueryARB(enum target); 462 void GetQueryivARB(enum target, enum pname, int *params); 463 void GetQueryObjectivARB(uint id, enum pname, int *params); 464 void GetQueryObjectuivARB(uint id, enum pname, uint *params); 465 466New Tokens 467 468 Accepted by the <target> parameter of BeginQueryARB, EndQueryARB, 469 and GetQueryivARB: 470 471 SAMPLES_PASSED_ARB 0x8914 472 473 Accepted by the <pname> parameter of GetQueryivARB: 474 475 QUERY_COUNTER_BITS_ARB 0x8864 476 CURRENT_QUERY_ARB 0x8865 477 478 Accepted by the <pname> parameter of GetQueryObjectivARB and 479 GetQueryObjectuivARB: 480 481 QUERY_RESULT_ARB 0x8866 482 QUERY_RESULT_AVAILABLE_ARB 0x8867 483 484Additions to Chapter 2 of the OpenGL 1.4 Specification (OpenGL Operation) 485 486 Modify Section 2.1, OpenGL Fundamentals (p. 4) 487 488 (modify fourth paragraph, p. 4) It also means that queries and 489 pixel read operations return state consistent with complete 490 execution of all previously invoked GL commands, except where 491 explicitly specified otherwise 492 493Additions to Chapter 3 of the OpenGL 1.4 Specification (Rasterization) 494 495 None. 496 497Additions to Chapter 4 of the OpenGL 1.4 Specification (Per-Fragment 498Operations and the Frame Buffer) 499 500 Add a new section "Occlusion Queries" between sections 4.1.6 and 501 4.1.7: 502 503 "4.1.6A Occlusion Queries 504 505 Occlusion queries can be used to track the number of fragments or 506 samples that pass the depth test. 507 508 Occlusion queries are associated with query objects. The command 509 510 void GenQueriesARB(sizei n, uint *ids); 511 512 returns <n> previously unused query object names in <ids>. These 513 names are marked as used, but no object is associated with them until 514 the first time they are used by BeginQueryARB. Query objects contain 515 one piece of state, an integer result value. This result value is 516 initialized to zero when the object is created. Any positive integer 517 except for zero (which is reserved for the GL) is a valid query 518 object name. 519 520 Query objects are deleted by calling 521 522 void DeleteQueriesARB(sizei n, const uint *ids); 523 524 <ids> contains <n> names of query objects to be deleted. After a 525 query object is deleted, its name is again unused. Unused names in 526 <ids> are silently ignored. 527 528 An occlusion query can be started and finished by calling 529 530 void BeginQueryARB(enum target, uint id); 531 void EndQueryARB(enum target); 532 533 where <target> is SAMPLES_PASSED_ARB. If BeginQueryARB is called 534 with an unused <id>, that name is marked as used and associated with 535 a new query object. If BeginQueryARB is called while another query 536 is already in progress with the same target, an INVALID_OPERATION 537 error is generated. If EndQueryARB is called while no query with the 538 same target is in progress, an INVALID_OPERATION error is generated. 539 Calling either GenQueriesARB or DeleteQueriesARB while any query of 540 any target is active causes an INVALID_OPERATION error to be 541 generated. 542 543 BeginQueryARB with a <target> of SAMPLES_PASSED_ARB resets the 544 current samples-passed count to zero and sets the query active 545 state to TRUE and the active query id to <id>. EndQueryARB with 546 a target of SAMPLES_PASSED_ARB initializes a copy of the current 547 samples-passed count into the active occlusion query object's results 548 value, sets the active occlusion query object's result available to 549 FALSE, sets the query active state to FALSE, and the active query 550 id to 0. 551 552 If BeginQueryARB is called with an <id> of zero, or where <id> is the 553 name of a query currently in progress, an INVALID_OPERATION error is 554 generated. 555 556 When an occlusion query is active, the samples-passed count increases 557 by a certain quantity for each fragment that passes the depth test. 558 If the value of SAMPLE_BUFFERS is 0, then the samples-passed count 559 increases by 1 for each fragment. If the value of SAMPLE_BUFFERS is 560 1, then the samples-passed count increases by the number of samples 561 whose coverage bit is set. However, implementations, at their 562 discretion, are allowed to instead increase the samples-passed count 563 by the value of SAMPLES if any sample in the fragment is covered. 564 565 If the samples-passed count overflows, i.e., exceeds the value 2^n-1 566 (where n is the number of bits in the samples-passed count), its 567 value becomes undefined. It is recommended, but not required, that 568 implementations handle this overflow case by saturating at 2^n-1 and 569 incrementing no further. 570 571 The necessary state is a single bit indicating whether an occlusion 572 query is active, the identifier of the currently active occlusion 573 query, and a counter keeping track of the number of samples that 574 have passed." 575 576Additions to Chapter 5 of the OpenGL 1.4 Specification (Special Functions) 577 578 Add to the end of Section 5.4 "Display Lists": 579 580 "DeleteQueriesARB, GenQueriesARB, IsQueryARB, GetQueryivARB, 581 GetQueryObjectivARB, and GetQueryObjectuivARB are not compiled into 582 display lists but are executed immediately." 583 584Additions to Chapter 6 of the OpenGL 1.4 Specification (State and 585State Requests) 586 587 Add a new section 6.1.13 "Occlusion Queries": 588 589 "The command 590 591 boolean IsQueryARB(uint id); 592 593 returns TRUE if <id> is the name of a query object. If <id> is zero, 594 or if <id> is a non-zero value that is not the name of a query 595 object, IsQueryARB returns FALSE. 596 597 Information about a query target can be queried with the command 598 599 void GetQueryivARB(enum target, enum pname, int *params); 600 601 If <pname> is CURRENT_QUERY_ARB, the name of the currently active 602 query for <target>, or zero if no query is active, will be placed in 603 <params>. 604 605 If <pname> is QUERY_COUNTER_BITS_ARB, the number of bits in the counter for 606 <target> will be placed in <params>. The minimum number of query counter 607 bits allowed is a function of the implementation's maximum viewport 608 dimensions (MAX_VIEWPORT_DIMS). If the counter is non-zero, then the 609 counter must be able to represent at least two overdraws for every pixel 610 in the viewport using only one sample buffer. The formula to compute the 611 allowable minimum value is below (where n is the minimum number of bits): 612 613 n = (min (32, ceil (log2 (maxViewportWidth x maxViewportHeight x 2) ) ) ) or 614 0 615 616 If the value of n is 0, then the result from GetQueryiv(SAMPLES_PASSED_ARB) 617 will always return 0, 618 619 The state of a query object can be queried with the commands 620 621 void GetQueryObjectivARB(uint id, enum pname, int *params); 622 void GetQueryObjectuivARB(uint id, enum pname, uint *params); 623 624 If <id> is not the name of a query object, or if the query object 625 named by <id> is currently active, then an INVALID_OPERATION error is 626 generated. 627 628 If <pname> is QUERY_RESULT_ARB, then the query object's result value 629 is placed in <params>. 630 631 Often, query object results will be returned asynchronously with 632 respect to the host processor's operation. As a result, sometimes, 633 if a result is queried, the host must wait until the result is back. 634 If <pname> is QUERY_RESULT_AVAILABLE_ARB, the value placed in 635 <params> indicates whether or not such a wait would occur if the 636 result of that query object were to be queried presently. A result 637 of TRUE means no wait would be required; a result of FALSE means that 638 some wait would occur. It must always be true that if the result for one 639 query is available, the result for all previous queries must also be 640 available at that point in time. 641 642 Querying the state for a given occlusion query forces that occlusion 643 query to complete within a finite amount of time. 644 645 If multiple queries are issued on the same target and id prior to 646 calling GetQueryObject[u]iVARB, the result returned will always be 647 from the last query issued. The results from any queries before the 648 last one will be lost if the results are not retrieved before starting 649 a new query on the same target and id." 650 651Dependencies on HP_occlusion_test 652 653 When GetIntegerv is called with <pname> of OCCLUSION_TEST_RESULT_HP, 654 the current samples-passed count is reset to zero. The occlusion 655 test result is TRUE when the samples-passed count is nonzero, and 656 FALSE when it is zero. Sample counting is active (i.e. the samples- 657 passed count increases as fragments are drawn) whenever either an 658 occlusion query is active *or* OCCLUSION_TEST_HP is enabled. 659 660GLX Protocol 661 662 Seven new GL commands are added. 663 664 The following two rendering commands are sent to the server as part 665 of a glXRender request: 666 667 BeginQueryARB 668 2 12 rendering command length 669 2 231 rendering command opcode 670 4 ENUM target 671 4 CARD32 id 672 673 EndQueryARB 674 2 8 rendering command length 675 2 232 rendering command opcode 676 4 ENUM target 677 678 The remaining fivecommands are non-rendering commands. These 679 commands are sent separately (i.e., not as part of a glXRender or 680 glXRenderLarge request), using glx single requests: 681 682 DeleteQueriesARB 683 1 CARD8 opcode (X assigned) 684 1 161 GLX opcode 685 2 3+n request length 686 4 GLX_CONTEXT_TAG context tag 687 4 INT32 n 688 n*4 LISTofCARD32 ids 689 690 GenQueriesARB 691 1 CARD8 opcode (X assigned) 692 1 162 GLX opcode 693 2 3 request length 694 4 GLX_CONTEXT_TAG context tag 695 4 INT32 n 696 => 697 1 1 reply 698 1 unused 699 2 CARD16 sequence number 700 4 n reply length 701 24 unused 702 n*4 LISTofCARD32 queries 703 704 IsQueryARB 705 1 CARD8 opcode (X assigned) 706 1 163 GLX opcode 707 2 3 request length 708 4 GLX_CONTEXT_TAG context tag 709 4 CARD32 id 710 => 711 1 1 reply 712 1 unused 713 2 CARD16 sequence number 714 4 0 reply length 715 4 BOOL32 return value 716 20 unused 717 718 GetQueryivARB 719 1 CARD8 opcode (X assigned) 720 1 164 GLX opcode 721 2 4 request length 722 4 GLX_CONTEXT_TAG context tag 723 4 ENUM target 724 4 ENUM pname 725 => 726 1 1 reply 727 1 unused 728 2 CARD16 sequence number 729 4 m reply length, m=(n==1?0:n) 730 4 unused 731 4 CARD32 n 732 733 if (n=1) this follows: 734 735 4 INT32 params 736 12 unused 737 738 otherwise this follows: 739 740 16 unused 741 n*4 LISTofINT32 params 742 743 GetQueryObjectivARB 744 1 CARD8 opcode (X assigned) 745 1 165 GLX opcode 746 2 4 request length 747 4 GLX_CONTEXT_TAG context tag 748 4 CARD32 id 749 4 ENUM pname 750 => 751 1 1 reply 752 1 unused 753 2 CARD16 sequence number 754 4 m reply length, m=(n==1?0:n) 755 4 unused 756 4 CARD32 n 757 758 if (n=1) this follows: 759 760 4 INT32 params 761 12 unused 762 763 otherwise this follows: 764 765 16 unused 766 n*4 LISTofINT32 params 767 768 GetQueryObjectuivARB 769 1 CARD8 opcode (X assigned) 770 1 166 GLX opcode 771 2 4 request length 772 4 GLX_CONTEXT_TAG context tag 773 4 CARD32 id 774 4 ENUM pname 775 => 776 1 1 reply 777 1 unused 778 2 CARD16 sequence number 779 4 m reply length, m=(n==1?0:n) 780 4 unused 781 4 CARD32 n 782 783 if (n=1) this follows: 784 785 4 CARD32 params 786 12 unused 787 788 otherwise this follows: 789 790 16 unused 791 n*4 LISTofCARD32 params 792 793Errors 794 795 The error INVALID_VALUE is generated if GenQueriesARB is called where 796 <n> is negative. 797 798 The error INVALID_VALUE is generated if DeleteQueriesARB is called 799 where <n> is negative. 800 801 The error INVALID_OPERATION is generated if GenQueriesARB or 802 DeleteQueriesARB is called when a query of any target is active. 803 804 The error INVALID_ENUM is generated if BeginQueryARB, EndQueryARB, or 805 GetQueryivARB is called where <target> is not SAMPLES_PASSED_ARB. 806 807 The error INVALID_OPERATION is generated if BeginQueryARB is called 808 when a query of the given <target> is already active. 809 810 The error INVALID_OPERATION is generated if EndQueryARB is called 811 when a query of the given <target> is not active. 812 813 The error INVALID_OPERATION is generated if BeginQueryARB is called 814 where <id> is zero. 815 816 The error INVALID_OPERATION is generated if BeginQueryARB is called 817 where <id> is is the name of a query currently in progress. 818 819 The error INVALID_ENUM is generated if GetQueryivARB is called where 820 <pname> is not QUERY_COUNTER_BITS_ARB or CURRENT_QUERY_ARB. 821 822 The error INVALID_OPERATION is generated if GetQueryObjectivARB or 823 GetQueryObjectuivARB is called where <id> is not the name of a query 824 object. 825 826 The error INVALID_OPERATION is generated if GetQueryObjectivARB or 827 GetQueryObjectuivARB is called where <id> is the name of a currently 828 active query object. 829 830 The error INVALID_ENUM is generated if GetQueryObjectivARB or 831 GetQueryObjectuivARB is called where <pname> is not QUERY_RESULT_ARB 832 or QUERY_RESULT_AVAILABLE_ARB. 833 834 The error INVALID_OPERATION is generated if any of the commands 835 defined in this extension is executed between the execution of Begin 836 and the corresponding execution of End. 837 838New State 839 840(table 6.18, p. 233) 841 842 Get Value Type Get Command Initial Value Description Sec Attribute 843 --------- ---- ----------- ------------- ----------- ------ --------- 844 - B - FALSE query active 4.1.6A - 845 CURRENT_QUERY_ARB Z+ GetQueryiv 0 active query ID 4.1.6A - 846 QUERY_RESULT_ARB Z+ GetQueryObjectuivARB 0 samples-passed count 4.1.6A - 847 QUERY_RESULT_AVAILABLE_ARB B GetQueryObjectivARB FALSE query result available 4.1.6A - 848 849New Implementation Dependent State 850 851(table 6.29, p. 224) Add the following entry: 852 853 Get Value Type Get Command Minimum Value Description Sec Attribute 854 -------------------------- ---- ----------- ------------- ---------------- ------ -------------- 855 QUERY_COUNTER_BITS_ARB Z+ GetQueryiv see 6.1.13 Number of bits in 6.1.13 - 856 query counter 857 858Revision History 859 860 Date: 4/21/2007 861 Revision: 7 (Jon Leech) 862 - Added QUERY_RESULT_ARB and QUERY_RESULT_AVAILABLE to state table 863 6.18 (also fixed in OpenGL 2.1 spec). 864 865 Date: 11/4/2006 866 Revision: 6 (Benj Lipchak, AMD) 867 - Updated contact info after ATI/AMD merger. 868 869 Date: 10/27/2004 870 Revision: 5? (James Jones, NVIDIA) 871 - Added GLX protocol. 872 873Usage Examples 874 875 Here is some rough sample code that illustrates how this extension 876 can be used. 877 878 GLuint queries[N]; 879 GLuint sampleCount; 880 GLint available; 881 GLuint bitsSupported; 882 883 // check to make sure functionality is supported 884 glGetQueryiv(GL_QUERY_COUNTER_BITS_ARB, &bitsSupported); 885 if (bitsSupported == 0) { 886 // render scene without using occlusion queries 887 } 888 889 glGenQueriesARB(N, queries); 890 ... 891 // before this point, render major occluders 892 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); 893 glDepthMask(GL_FALSE); 894 // also disable texturing and any fancy shaders 895 for (i = 0; i < N; i++) { 896 glBeginQueryARB(GL_SAMPLES_PASSED_ARB, queries[i]); 897 // render bounding box for object i 898 glEndQueryARB(GL_SAMPLES_PASSED_ARB); 899 } 900 901 glFlush(); 902 903 // Do other work until "most" of the queries are back, to avoid 904 // wasting time spinning 905 i = N*3/4; // instead of N-1, to prevent the GPU from going idle 906 do { 907 DoSomeStuff(); 908 glGetQueryObjectivARB(queries[i], 909 GL_QUERY_RESULT_AVAILABLE_ARB, 910 &available); 911 } while (!available); 912 913 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 914 glDepthMask(GL_TRUE); 915 // reenable other state, such as texturing 916 for (i = 0; i < N; i++) { 917 glGetQueryObjectuivARB(queries[i], GL_QUERY_RESULT_ARB, 918 &sampleCount); 919 if (sampleCount > 0) { 920 // render object i 921 } 922 } 923 924 Here is some rough sample code for a simple multipass rendering 925 application that does not use occlusion queries. 926 927 for (i = 0; i < N; i++) { 928 // First rendering pass 929 glDisable(GL_BLEND); 930 glDepthFunc(GL_LESS); 931 glDepthMask(GL_TRUE); 932 // configure shader 0 933 // render object i 934 935 // Second rendering pass 936 glEnable(GL_BLEND); 937 glBlendFunc(...); 938 glDepthFunc(GL_EQUAL); 939 glDepthMask(GL_FALSE); 940 // configure shader 1 941 // render object i 942 } 943 944 Here is the previous example, enhanced using occlusion queries. 945 946 GLuint queries[N]; 947 GLuint sampleCount; 948 949 glGenQueriesARB(N, queries); 950 ... 951 // First rendering pass plus almost-free visibility checks 952 glDisable(GL_BLEND); 953 glDepthFunc(GL_LESS); 954 glDepthMask(GL_TRUE); 955 // configure shader 0 956 for (i = 0; i < N; i++) { 957 glBeginQueryARB(GL_SAMPLES_PASSED_ARB, queries[i]); 958 // render object i 959 glEndQueryARB(GL_SAMPLES_PASSED_ARB); 960 } 961 962 // Second pass only on objects that were visible 963 glEnable(GL_BLEND); 964 glBlendFunc(...); 965 glDepthFunc(GL_EQUAL); 966 glDepthMask(GL_FALSE); 967 // configure shader 1 968 for (i = 0; i < N; i++) { 969 glGetQueryObjectuivARB(queries[i], GL_QUERY_RESULT_ARB, 970 &sampleCount); 971 if (sampleCount > 0) { 972 // render object i 973 } 974 } 975