Name AMD_occlusion_query_event Name Strings GL_AMD_occlusion_query_event Contact Graham Sellers (graham.sellers 'at' amd.com) Contributors Graham Sellers, AMD Daniel Rakos, AMD Status SHIPPING Version Last Modified Date: 11/20/2013 Author Revision: 3 Number OpenGL Extension #442 Dependencies OpenGL 1.5 is required. This extension is written against the OpenGL 4.4 (core) specification. This extension depends on the definition of OpenGL 3.3 and GL_ARB_occlusion_query2. This extension depends on the definition of OpenGL 4.3 and GL_ARB_ES3_compatibility. This extension depends on the definition of GL_EXT_depth_bounds_test. Overview Occlusion queries provide a means to count the number of fragments that pass the depth and stencil tests and that may contribute to a rendered image. In unextended OpenGL, an occlusion query increments its samples-passed count whenever a sample passes both the stencil test and the depth test (if enabled). However, there is no way to count fragments that fail the stencil test, or pass the stencil test and then subsequently fail the depth test. This extension introduces the concept of occlusion query events and changes the concept of an occlusion query from counting passed fragments to counting fragments that generate any of a user-selectable set of events. Provided events include passing the depth test, and passing or failing the stencil test. For a given occlusion query object, counting of these events may be enabled or disabled, allowing any combination to be counted. New Procedures and Functions void QueryObjectParameteruiAMD(enum target, uint id, enum pname, uint param); New Tokens Accepted by the argument to QueryObejctParameteruiAMD, GetQueryObjectiv, GetQueryObjectuiv, GetQueryObjecti64v, and GetQueryObjectui64v: OCCLUSION_QUERY_EVENT_MASK_AMD 0x874F Accepted by the argument to QueryObjectParameteruiAMD: QUERY_DEPTH_PASS_EVENT_BIT_AMD 0x00000001 QUERY_DEPTH_FAIL_EVENT_BIT_AMD 0x00000002 QUERY_STENCIL_FAIL_EVENT_BIT_AMD 0x00000004 QUERY_DEPTH_BOUNDS_FAIL_EVENT_BIT_AMD 0x00000008 QUERY_ALL_EVENT_BITS_AMD 0xFFFFFFFF Additions to Chapter 4 of the OpenGL 4.4 (core) Specification (Event Model) Insert Section 4.2.1, "Query Object Parameters", p.42. Renumber subsequent sections. Query object parameters control the behavior of the query object. Changing the value of a query object parameter is done by calling void QueryObjectParameteruiAMD(enum target, uint id, enum pname, uint param); with set to a valid query target, set to a value returned from a previous call to GenQueries. specifies the parameter to modify and contains its new value. If is an unused query object name then the name is marked as used and associated with a new query object of the type specified by . Otherwise, must be the name of an existing query object of that type. Additions to Chapter 17 of the OpenGL 4.3 (core) Specification (Writing Fragments and Samples to the Framebuffer) Modify the first paragraph of Subection 17.3.7, "Occlusion Queries" as follows: Occlusion queries use query objects to track fragments as they pass through the depth bounds test, stencil test and depth test, in that order. Each stage may generate an event. An event is generated if a fragment fails the depth bounds test. If a fragment passes the depth bounds test, it then undergoes the stencil test and generates an event should it fail that. Should it pass the stencil test, it undergoes the depth test, upon which it will generate an event indicating whether it passed or failed the depth test. An occlusion query can be started and finished by calling BeginQuery and EndQuery, respectively, with a of SAMPLES_PASSED, ANY_SAMPLES_PASSED, or ANY_SAMPLES_PASSED_CONSERVATIVE. In the remainder of the Subsection, replace any occurrence of "passes the depth test" with "generates an enabled event". Add the following to the end of the subsection: Counting of occlusion query events are enabled and disabled for a query object by calling QueryObjectParameteruiAMD with set to SAMPLES_PASSED, ANY_SAMPLES_PASSED or ANY_SAMPLES_PASSED_CONSERVATIVE, with set to the name of an existing query object of the appropriate type, or to a name returned from a call to GenQueries but not yet associated with a query object, with set to OCCLUSION_QUERY_EVENT_MASK_AMD and with set to the bitwise or of the set of the following flags: +---------------------------------------+---------------------------------------------------------+ | QUERY_DEPTH_PASS_EVENT_BIT_AMD | Indicates that the fragment passed all tests. | | QUERY_DEPTH_FAIL_EVENT_BIT_AMD | Indicates that the fragment passed the depth bounds and | | | stencil tests, but failed the depth test. | | QUERY_STENCIL_FAIL_EVENT_BIT_AMD | Indicates that the fragment passed the depth bounds | | | test but failed the stencil test. | | QUERY_DEPTH_BOUNDS_FAIL_EVENT_BIT_AMD | Indicates that the fragment failed the depth bounds | | | test. | | QUERY_ALL_EVENT_BITS_AMD | Indicates that any event generated by the fragment | | | should be counted. | +---------------------------------------+---------------------------------------------------------+ By default, the value of OCCLUSION_QUERY_EVENT_MASK_AMD for a newly created occlusion query object is QUERY_DEPTH_PASS_EVENT_BIT_AMD. Additions to the AGL/GLX/WGL Specifications None. GLX Protocol None. Errors INVALID_OPERATION is generated by GetQueryObjectiv, GetQueryObjectuiv, GetQueryObjecti64v, and GetQueryObjectui64v if is OCCLUSION_QUERY_EVENT_MASK_AMD and the target of the query object specified by is not SAMPLES_PASSED, ANY_SAMPLES_PASSED, or ANY_SAMPLES_PASSED_CONSERVATIVE. INVALID_ENUM is generated by QueryObjectParameteruiAMD if is not an accepted query target. INVALID_ENUM is generated by QueryObjectParameteruiAMD if is not OCCLUSION_QUERY_EVENT_MASK_AMD. INVALID_VALUE is generated by QueryObjectParameteruiAMD if is not a name returned from a previous call to GenQueries, or if such a name has since been deleted with DeleteQueries. INVALID_OPERATION is generated by QueryObjectParameteruiAMD if is the name of an existing query object whose target does not match , or an active query object name for . INVALID_OPERATION is generated by QueryObjectParameteruiAMD if is OCCLUSION_QUERY_EVENT_MASK_AMD and is not SAMPLES_PASSED, ANY_SAMPLES_PASSED, or ANY_SAMPLES_PASSED_CONSERVATIVE. INVALID_VALUE is generated by QueryObjectParameteruiAMD if is OCCLUSION_QUERY_EVENT_MASK_AMD and contains any unsupported bits, except in the case when is equal to the special value, QUERY_ALL_EVENT_BITS_AMD. New State Append to Table 23.44, "Query Object State" +-----------------------------------+-------+--------------------+--------------------------------+------------------------------------+--------+ | Get Value | Type | Get Command | Initial Value | Description | Sec. | +-----------------------------------+-------+--------------------+--------------------------------+------------------------------------+--------+ | OCCLUSION_QUERY_EVENT_MASK_AMD | Z+ | GetQueryObjectuiv | QUERY_DEPTH_PASS_EVENT_BIT_AMD | Bitmask of events to count in an | 17.3.7 | | | | | | occlusion query | | +-----------------------------------+-------+--------------------+--------------------------------+------------------------------------+--------+ New Implementation Dependent State None. Usage Examples TBD Dependencies on GL_EXT_depth_bounds_test If GL_EXT_depth_bounds_test is not supported, remove any reference to the depth bounds test and the QUERY_DEPTH_BOUNDS_FAIL_EVENT_BIT_AMD token. The value of the QUERY_DEPTH_BOUNDS_FAIL_EVENT_BIT_AMD remains reserved, however. This extension shall behave as if all fragments pass the depth bounds test. Dependencies on OpenGL 3.3 and GL_ARB_occlusion_query2 If GL_ARB_occlusion_query2 is not present, and the GL version is less than 3.3, then remove any reference to the ANY_SAMPLES_PASSED target. Dependencies on OpenGL 4.3 and GL_ARB_ES3_compatibility If GL_ARB_ES3_compatility is not present, and the GL version is less than 4.3, then remove any reference to the ANY_SAMPLES_PASSED_CONSERVATIVE target. Issues 1) Why is there no QUERY_STENCIL_PASS_BIT_AMD or QUERY_DEPTH_BOUNDS_PASS_BIT_AMD? Fragments that pass the depth bounds test proceed to the stencil test and subsequently to the depth test. The sum of depth pass, depth fail and stencil fail is, by definition, the number of fragments that pass the depth bounds test. Likewise, the sum of depth pass and depth fail is the number of fragments that pass the stencil test. Thus, setting the event mask to (QUERY_DEPTH_PASS_EVENT_BIT_AMD | QUERY_DEPTH_FAIL_EVENT_BIT_AMD | QUERY_STENCIL_FAIL_EVENT_BIT_AMD) allows counting of fragments that pass the depth bounds test. Similarly, setting the event mask to (QUERY_DEPTH_PASS_EVENT_BIT_AMD | QUERY_DEPTH_FAIL_EVENT_BIT_AMD) provides the count of fragments that pass the stencil test. 2) Will fragments that fail the stencil test generate a depth pass or fail event as if they were depth tested? Will fragments that fail the depth bounds test generate stencil fail events? RESOLVED: No. Once a fragment fails testing at a particular stage, it is discarded and cannot generate any more events. 3) What happens if the implementation doesn't support EXT_depth_bounds. RESOLVED: It is as if all fragments pass the depth bounds test. No depth bounds failed events are generated. 4) What is the purpose of QUERY_ALL_EVENT_BITS_AMD? RESOLVED: It allows the counting of all fragments that are subjected to any test regardless of the outcome of those tests. 5) What should the new query state setter function be called? DISCUSSION: Unfortunately, the query object API doesn't really follow the naming conventions of object state getters already, as GetQueryObject should have been rather called GetQueryParameter. We considered the following options: (a) QueryObjectuiAMD (b) QueryParameteruiAMD (c) QueryObjectParameteruiAMD Option (a) follows the existing naming convention of the query object API, but is too general. Option (b) follows the naming convention of other object types, but because the getter of existing query states is called GetQueryObject, while there is also a GetQuery getter that returns context state, not per-query object state. Option (c) doesn't follow either the naming convention of the query object API or any other object type's, but rather a mixture of the two, however, it makes explicit both the fact that the setter operates on a query object and that it modifies its parameter. RESOLVED: QueryObjectParameteruiAMD, because the function modifies a state/parameter of a query object. 6) Should there be also a GetQueryObjectParameteruiAMD? RESOLVED: No. GetQueryObject is already defined to query the state of a query object (see also issue #5). Revision History Rev. Date Author Changes ---- -------- -------- --------------------------------------------- 3 11/20/2013 gsellers Make ready for posting 2 08/20/2013 drakos Internal revision 1 10/08/2012 gsellers Initial revision