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