15bd8deadSopenharmony_ciName
25bd8deadSopenharmony_ci
35bd8deadSopenharmony_ci    ARB_timer_query
45bd8deadSopenharmony_ci
55bd8deadSopenharmony_ciName Strings
65bd8deadSopenharmony_ci
75bd8deadSopenharmony_ci    GL_ARB_timer_query
85bd8deadSopenharmony_ci
95bd8deadSopenharmony_ciContact
105bd8deadSopenharmony_ci
115bd8deadSopenharmony_ci    Piers Daniell, NVIDIA Corporation (pdaniell 'at' nvidia.com)
125bd8deadSopenharmony_ci
135bd8deadSopenharmony_ciContributors
145bd8deadSopenharmony_ci
155bd8deadSopenharmony_ci    Axel Mamode, Sony
165bd8deadSopenharmony_ci    Brian Paul, Tungsten Graphics
175bd8deadSopenharmony_ci    Bruce Merry, ARM
185bd8deadSopenharmony_ci    James Jones, NVIDIA Corporation
195bd8deadSopenharmony_ci    Pat Brown, NVIDIA
205bd8deadSopenharmony_ci    Remi Arnaud, Sony
215bd8deadSopenharmony_ci
225bd8deadSopenharmony_ciNotice
235bd8deadSopenharmony_ci
245bd8deadSopenharmony_ci    Copyright (c) 2010-2013 The Khronos Group Inc. Copyright terms at
255bd8deadSopenharmony_ci        http://www.khronos.org/registry/speccopyright.html
265bd8deadSopenharmony_ci
275bd8deadSopenharmony_ciSpecification Update Policy
285bd8deadSopenharmony_ci
295bd8deadSopenharmony_ci    Khronos-approved extension specifications are updated in response to
305bd8deadSopenharmony_ci    issues and bugs prioritized by the Khronos OpenGL Working Group. For
315bd8deadSopenharmony_ci    extensions which have been promoted to a core Specification, fixes will
325bd8deadSopenharmony_ci    first appear in the latest version of that core Specification, and will
335bd8deadSopenharmony_ci    eventually be backported to the extension document. This policy is
345bd8deadSopenharmony_ci    described in more detail at
355bd8deadSopenharmony_ci        https://www.khronos.org/registry/OpenGL/docs/update_policy.php
365bd8deadSopenharmony_ci
375bd8deadSopenharmony_ciStatus
385bd8deadSopenharmony_ci
395bd8deadSopenharmony_ci    Complete. Approved by the ARB at the 2010/01/22 F2F meeting.
405bd8deadSopenharmony_ci    Approved by the Khronos Board of Promoters on March 10, 2010.
415bd8deadSopenharmony_ci
425bd8deadSopenharmony_ciVersion
435bd8deadSopenharmony_ci
445bd8deadSopenharmony_ci    Last Modified Date: August 9, 2014
455bd8deadSopenharmony_ci    Revision: 13
465bd8deadSopenharmony_ci
475bd8deadSopenharmony_ciNumber
485bd8deadSopenharmony_ci
495bd8deadSopenharmony_ci    ARB Extension #85
505bd8deadSopenharmony_ci
515bd8deadSopenharmony_ciDependencies
525bd8deadSopenharmony_ci
535bd8deadSopenharmony_ci    This extension is written against the OpenGL 3.2 specification.
545bd8deadSopenharmony_ci
555bd8deadSopenharmony_ciOverview
565bd8deadSopenharmony_ci
575bd8deadSopenharmony_ci    Applications can benefit from accurate timing information in a number of
585bd8deadSopenharmony_ci    different ways.  During application development, timing information can
595bd8deadSopenharmony_ci    help identify application or driver bottlenecks.  At run time,
605bd8deadSopenharmony_ci    applications can use timing information to dynamically adjust the amount
615bd8deadSopenharmony_ci    of detail in a scene to achieve constant frame rates.  OpenGL
625bd8deadSopenharmony_ci    implementations have historically provided little to no useful timing
635bd8deadSopenharmony_ci    information.  Applications can get some idea of timing by reading timers
645bd8deadSopenharmony_ci    on the CPU, but these timers are not synchronized with the graphics
655bd8deadSopenharmony_ci    rendering pipeline.  Reading a CPU timer does not guarantee the completion
665bd8deadSopenharmony_ci    of a potentially large amount of graphics work accumulated before the
675bd8deadSopenharmony_ci    timer is read, and will thus produce wildly inaccurate results.
685bd8deadSopenharmony_ci    glFinish() can be used to determine when previous rendering commands have
695bd8deadSopenharmony_ci    been completed, but will idle the graphics pipeline and adversely affect
705bd8deadSopenharmony_ci    application performance.
715bd8deadSopenharmony_ci
725bd8deadSopenharmony_ci    This extension provides a query mechanism that can be used to determine
735bd8deadSopenharmony_ci    the amount of time it takes to fully complete a set of GL commands, and
745bd8deadSopenharmony_ci    without stalling the rendering pipeline.  It uses the query object
755bd8deadSopenharmony_ci    mechanisms first introduced in the occlusion query extension, which allow
765bd8deadSopenharmony_ci    time intervals to be polled asynchronously by the application.
775bd8deadSopenharmony_ci
785bd8deadSopenharmony_ciIP Status
795bd8deadSopenharmony_ci
805bd8deadSopenharmony_ci    No known IP claims.
815bd8deadSopenharmony_ci
825bd8deadSopenharmony_ciNew Procedures and Functions
835bd8deadSopenharmony_ci
845bd8deadSopenharmony_ci     void QueryCounter(uint id, enum target);
855bd8deadSopenharmony_ci
865bd8deadSopenharmony_ci     void GetQueryObjecti64v(uint id, enum pname, int64 *params);
875bd8deadSopenharmony_ci     void GetQueryObjectui64v(uint id, enum pname, uint64 *params);
885bd8deadSopenharmony_ci
895bd8deadSopenharmony_ciNew Tokens
905bd8deadSopenharmony_ci
915bd8deadSopenharmony_ci    Accepted by the <target> parameter of BeginQuery, EndQuery, and
925bd8deadSopenharmony_ci    GetQueryiv:
935bd8deadSopenharmony_ci
945bd8deadSopenharmony_ci        TIME_ELAPSED                                   0x88BF
955bd8deadSopenharmony_ci
965bd8deadSopenharmony_ci    Accepted by the <target> parameter of GetQueryiv and QueryCounter.
975bd8deadSopenharmony_ci    Accepted by the <value> parameter of GetBooleanv, GetIntegerv,
985bd8deadSopenharmony_ci    GetInteger64v, GetFloatv, and GetDoublev:
995bd8deadSopenharmony_ci
1005bd8deadSopenharmony_ci        TIMESTAMP                                      0x8E28
1015bd8deadSopenharmony_ci
1025bd8deadSopenharmony_ciAdditions to Chapter 2 of the OpenGL 3.2 (Core Profile) Specification
1035bd8deadSopenharmony_ci(OpenGL Operation)
1045bd8deadSopenharmony_ci
1055bd8deadSopenharmony_ci    (Modify table 2.1, Correspondence of command suffix letters to GL argument
1065bd8deadSopenharmony_ci     types, p. 14) Add one new type and suffix:
1075bd8deadSopenharmony_ci
1085bd8deadSopenharmony_ci    Letter Corresponding GL Type
1095bd8deadSopenharmony_ci    ------ ---------------------
1105bd8deadSopenharmony_ci    ui64   uint64
1115bd8deadSopenharmony_ci
1125bd8deadSopenharmony_ci    (Modify Section 2.14, Asynchronous Queries, p. 89)
1135bd8deadSopenharmony_ci
1145bd8deadSopenharmony_ci    Asynchronous queries provide a mechanism to return information about the
1155bd8deadSopenharmony_ci    processing of a sequence of GL commands. There are three query types
1165bd8deadSopenharmony_ci    supported by the GL. Transform feedback queries (see section 2.16) return
1175bd8deadSopenharmony_ci    information on the number of vertices and primitives processed by the GL
1185bd8deadSopenharmony_ci    and written to one or more buffer objects. Occlusion queries (see section
1195bd8deadSopenharmony_ci    4.1.6) count the number of fragments or samples that pass the depth test.
1205bd8deadSopenharmony_ci    Timer queries (section 5.4) record the amount of time needed to fully
1215bd8deadSopenharmony_ci    process these commands or the current time of the GL.
1225bd8deadSopenharmony_ci
1235bd8deadSopenharmony_ciAdditions to Chapter 3 of the OpenGL 3.2 Specification (Rasterization)
1245bd8deadSopenharmony_ci
1255bd8deadSopenharmony_ci    None.
1265bd8deadSopenharmony_ci
1275bd8deadSopenharmony_ciAdditions to Chapter 4 of the OpenGL 3.2 Specification (Per-Fragment
1285bd8deadSopenharmony_ciOperations and the Framebuffer)
1295bd8deadSopenharmony_ci
1305bd8deadSopenharmony_ci    None.
1315bd8deadSopenharmony_ci
1325bd8deadSopenharmony_ciAdditions to Chapter 5 of the OpenGL 3.2 Specification (Special Functions)
1335bd8deadSopenharmony_ci
1345bd8deadSopenharmony_ci    (Add new Section 5.4, Timer Queries, p. 246)
1355bd8deadSopenharmony_ci
1365bd8deadSopenharmony_ci    Timer queries use query objects to track the amount of time needed to
1375bd8deadSopenharmony_ci    fully complete a set of GL commands, or to determine the current time
1385bd8deadSopenharmony_ci    of the GL.
1395bd8deadSopenharmony_ci
1405bd8deadSopenharmony_ci    When BeginQuery and EndQuery are called with a <target> of
1415bd8deadSopenharmony_ci    TIME_ELAPSED, the GL prepares to start and stop the timer used for
1425bd8deadSopenharmony_ci    timer queries.  The timer is started or stopped when the effects from all
1435bd8deadSopenharmony_ci    previous commands on the GL client and server state and the framebuffer
1445bd8deadSopenharmony_ci    have been fully realized.  The BeginQuery and EndQuery commands may return
1455bd8deadSopenharmony_ci    before the timer is actually started or stopped.  When the timer query
1465bd8deadSopenharmony_ci    timer is finally stopped, the elapsed time (in nanoseconds) is written to
1475bd8deadSopenharmony_ci    the corresponding query object as the query result value, and the query
1485bd8deadSopenharmony_ci    result for that object is marked as available.
1495bd8deadSopenharmony_ci
1505bd8deadSopenharmony_ci    If the elapsed time overflows the number of bits, <n>, available to hold
1515bd8deadSopenharmony_ci    elapsed time, its value becomes undefined.  It is recommended, but not
1525bd8deadSopenharmony_ci    required, that implementations handle this overflow case by saturating at
1535bd8deadSopenharmony_ci    2^n - 1.
1545bd8deadSopenharmony_ci
1555bd8deadSopenharmony_ci    A timer query object is created with the command
1565bd8deadSopenharmony_ci
1575bd8deadSopenharmony_ci         void QueryCounter(uint id, enum target);
1585bd8deadSopenharmony_ci
1595bd8deadSopenharmony_ci    <target> must be TIMESTAMP. If <id> is an unused query object name, the
1605bd8deadSopenharmony_ci    name is marked as used and associated with a new query object of type
1615bd8deadSopenharmony_ci    TIMESTAMP. Otherwise <id> must be the name of an existing query object
1625bd8deadSopenharmony_ci    of that type.
1635bd8deadSopenharmony_ci
1645bd8deadSopenharmony_ci    When QueryCounter is called, the GL records the current time into
1655bd8deadSopenharmony_ci    the corresponding query object. The time is recorded after all previous
1665bd8deadSopenharmony_ci    commands on the GL client and server state and the framebuffer have been
1675bd8deadSopenharmony_ci    fully realized. When the time is recorded, the query result for that
1685bd8deadSopenharmony_ci    object is marked available. QueryCounter timer queries can be used
1695bd8deadSopenharmony_ci    within a BeginQuery / EndQuery block where the <target> is TIME_ELAPSED
1705bd8deadSopenharmony_ci    and it does not affect the result of that query object.
1715bd8deadSopenharmony_ci
1725bd8deadSopenharmony_ci** core profile only
1735bd8deadSopenharmony_ci    QueryCounter fails and an INVALID\_OPERATION error is generated if <id>
1745bd8deadSopenharmony_ci    is not a name returned from a previous call to GenQueries, or if such a
1755bd8deadSopenharmony_ci    name has since been deleted with DeleteQueries.
1765bd8deadSopenharmony_ci** end core profile only
1775bd8deadSopenharmony_ci
1785bd8deadSopenharmony_ci    If <id> is already in use within a BeginQuery / EndQuery block, or if
1795bd8deadSopenharmony_ci    <id> is the name of an existing query object whose type does not match
1805bd8deadSopenharmony_ci    <target>, an INVALID_OPERATION error is generated.
1815bd8deadSopenharmony_ci
1825bd8deadSopenharmony_ci    The current time of the GL may be queried by calling GetIntegerv or
1835bd8deadSopenharmony_ci    GetInteger64v with the symbolic constant TIMESTAMP. This will return the
1845bd8deadSopenharmony_ci    GL time after all previous commands have reached the GL server but have
1855bd8deadSopenharmony_ci    not yet necessarily executed. By using a combination of this synchronous
1865bd8deadSopenharmony_ci    get command and the asynchronous timestamp query object target,
1875bd8deadSopenharmony_ci    applications can measure the latency between when commands reach the GL
1885bd8deadSopenharmony_ci    server and when they are realized in the framebuffer.
1895bd8deadSopenharmony_ci
1905bd8deadSopenharmony_ciAdditions to Chapter 6 of the OpenGL 2.0 Specification (State and State
1915bd8deadSopenharmony_ciRequests)
1925bd8deadSopenharmony_ci
1935bd8deadSopenharmony_ci    (Modify Section 6.1.6, Asynchronous Queries, p. 255)
1945bd8deadSopenharmony_ci
1955bd8deadSopenharmony_ci    Section 6.1.6, Asynchronous Queries
1965bd8deadSopenharmony_ci
1975bd8deadSopenharmony_ci    The command
1985bd8deadSopenharmony_ci
1995bd8deadSopenharmony_ci      boolean IsQuery(uint id);
2005bd8deadSopenharmony_ci
2015bd8deadSopenharmony_ci    returns TRUE if <id> is the name of a query object. If <id> is zero, or if
2025bd8deadSopenharmony_ci    <id> is a non-zero value that is not the name of a query object, IsQuery
2035bd8deadSopenharmony_ci    returns FALSE.
2045bd8deadSopenharmony_ci
2055bd8deadSopenharmony_ci    Information about a query target can be queried with the command
2065bd8deadSopenharmony_ci
2075bd8deadSopenharmony_ci      void GetQueryiv(enum target, enum pname, int *params);
2085bd8deadSopenharmony_ci
2095bd8deadSopenharmony_ci    <target> identifies the query target and can be SAMPLES_PASSED for
2105bd8deadSopenharmony_ci    occlusion queries, PRIMITIVES_GENERATED and
2115bd8deadSopenharmony_ci    TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN for primitive queries, or
2125bd8deadSopenharmony_ci    TIME_ELAPSED or TIMESTAMP for timer queries.
2135bd8deadSopenharmony_ci
2145bd8deadSopenharmony_ci    If <pname> is CURRENT_QUERY, the name of the currently active query for
2155bd8deadSopenharmony_ci    <target>, or zero if no query is active, will be placed in <params>.
2165bd8deadSopenharmony_ci
2175bd8deadSopenharmony_ci    If <pname> is QUERY_COUNTER_BITS, the implementation-dependent number of
2185bd8deadSopenharmony_ci    bits used to hold the query result for <target> will be placed in
2195bd8deadSopenharmony_ci    <params>.  The number of query counter bits may be zero, in which case
2205bd8deadSopenharmony_ci    the counter contains no useful information.
2215bd8deadSopenharmony_ci
2225bd8deadSopenharmony_ci    For primitive queries (PRIMITIVES_GENERATED and
2235bd8deadSopenharmony_ci    TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN) if the number of bits is non-zero,
2245bd8deadSopenharmony_ci    the minimum number of bits allowed is 32.
2255bd8deadSopenharmony_ci
2265bd8deadSopenharmony_ci    For occlusion queries (SAMPLES_PASSED), if the number of bits is
2275bd8deadSopenharmony_ci    non-zero, the minimum number of bits allowed is a function of the
2285bd8deadSopenharmony_ci    implementation's maximum viewport dimensions (MAX_VIEWPORT_DIMS). The
2295bd8deadSopenharmony_ci    counter must be able to represent at least two overdraws for every pixel
2305bd8deadSopenharmony_ci    in the viewport. The formula to compute the allowable minimum value
2315bd8deadSopenharmony_ci    (where <n> is the minimum number of bits) is:
2325bd8deadSopenharmony_ci
2335bd8deadSopenharmony_ci        n = min(32, ceil(log_2(maxViewportWidth * maxViewportHeight * 2))).
2345bd8deadSopenharmony_ci
2355bd8deadSopenharmony_ci    For timer queries (TIME_ELAPSED and TIMESTAMP), if the number
2365bd8deadSopenharmony_ci    of bits is non-zero, the minimum number of bits allowed is 30 which
2375bd8deadSopenharmony_ci    will allow at least 1 second of timing.
2385bd8deadSopenharmony_ci
2395bd8deadSopenharmony_ci    The state of a query object can be queried with the commands
2405bd8deadSopenharmony_ci
2415bd8deadSopenharmony_ci        void GetQueryObjectiv(uint id, enum pname, int *params);
2425bd8deadSopenharmony_ci        void GetQueryObjectuiv(uint id, enum pname, uint *params);
2435bd8deadSopenharmony_ci        void GetQueryObjecti64v(uint id, enum pname, int64 *params);
2445bd8deadSopenharmony_ci        void GetQueryObjectui64v(uint id, enum pname, uint64 *params);
2455bd8deadSopenharmony_ci
2465bd8deadSopenharmony_ci    If <id> is not the name of a query object, or if the query object named
2475bd8deadSopenharmony_ci    by <id> is currently active, then an INVALID_OPERATION error is
2485bd8deadSopenharmony_ci    generated.
2495bd8deadSopenharmony_ci
2505bd8deadSopenharmony_ci    If <pname> is QUERY_RESULT, then the query object's result
2515bd8deadSopenharmony_ci    value is returned as a single integer in <params>. If the value is so
2525bd8deadSopenharmony_ci    large in magnitude that it cannot be represented with the requested type,
2535bd8deadSopenharmony_ci    then the nearest value representable using the requested type is
2545bd8deadSopenharmony_ci    returned. If the number of query counter bits for target is zero, then
2555bd8deadSopenharmony_ci    the result is returned as a single integer with the value zero.
2565bd8deadSopenharmony_ci
2575bd8deadSopenharmony_ci    There may be an indeterminate delay before the above query returns. If
2585bd8deadSopenharmony_ci    <pname> is QUERY_RESULT_AVAILABLE, FALSE is returned if such a delay
2595bd8deadSopenharmony_ci    would be required; otherwise TRUE is returned. It must always be true
2605bd8deadSopenharmony_ci    that if any query object returns a result available of TRUE, all queries
2615bd8deadSopenharmony_ci    of the same type issued prior to that query must also return TRUE.
2625bd8deadSopenharmony_ci
2635bd8deadSopenharmony_ci    Querying the state for any given query object forces that occlusion
2645bd8deadSopenharmony_ci    query to complete within a finite amount of time.
2655bd8deadSopenharmony_ci
2665bd8deadSopenharmony_ci    If multiple queries are issued using the same object name prior to
2675bd8deadSopenharmony_ci    calling GetQueryObject[u]i[64]v, the result and availability information
2685bd8deadSopenharmony_ci    returned will always be from the last query issued. The results from any
2695bd8deadSopenharmony_ci    queries before the last one will be lost if they are not retrieved before
2705bd8deadSopenharmony_ci    starting a new query on the same <target> and <id>.
2715bd8deadSopenharmony_ci
2725bd8deadSopenharmony_ciInteractions with NV_present_video and NV_video_capture
2735bd8deadSopenharmony_ci
2745bd8deadSopenharmony_ci    The GL timer recorded by this extension is the same timer as that used
2755bd8deadSopenharmony_ci    by the NV_present_video and NV_video_capture extensions. This allows
2765bd8deadSopenharmony_ci    the timer to be used with any of these extensions interchangeably.
2775bd8deadSopenharmony_ci
2785bd8deadSopenharmony_ciInteractions with the Compatibility Profile
2795bd8deadSopenharmony_ci
2805bd8deadSopenharmony_ci    In the compatibility profile, query objects support application-provided
2815bd8deadSopenharmony_ci    names, and the language requiring an error is <id> is not a name
2825bd8deadSopenharmony_ci    returned from GenQueries is removed. This is noted in the body text
2835bd8deadSopenharmony_ci    above.
2845bd8deadSopenharmony_ci
2855bd8deadSopenharmony_ciErrors
2865bd8deadSopenharmony_ci
2875bd8deadSopenharmony_ci    The error INVALID_ENUM is generated if BeginQuery or EndQuery is called
2885bd8deadSopenharmony_ci    where <target> is not SAMPLES_PASSED,
2895bd8deadSopenharmony_ci    TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN or TIME_ELAPSED.
2905bd8deadSopenharmony_ci
2915bd8deadSopenharmony_ci    The error INVALID_ENUM is generated if GetQueryiv is called where
2925bd8deadSopenharmony_ci    <target> is not SAMPLES_PASSED, TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN,
2935bd8deadSopenharmony_ci    TIME_ELAPSED or TIMESTAMP.
2945bd8deadSopenharmony_ci
2955bd8deadSopenharmony_ci    The error INVALID_ENUM is generated if QueryCounter is called where
2965bd8deadSopenharmony_ci    <target> is not TIMESTAMP.
2975bd8deadSopenharmony_ci
2985bd8deadSopenharmony_ci    The error INVALID_OPERATION is generated if QueryCounter is called
2995bd8deadSopenharmony_ci    on a query object that is already in use inside a BeginQuery/EndQuery.
3005bd8deadSopenharmony_ci
3015bd8deadSopenharmony_ci    The error INVALID_OPERATION is generated if QueryCounter is called on
3025bd8deadSopenharmony_ci    a query object whose type is not TIMESTAMP.
3035bd8deadSopenharmony_ci
3045bd8deadSopenharmony_ci    (in the core profile only)
3055bd8deadSopenharmony_ci    The error INVALID_OPERATION is generated if QueryCounter is called
3065bd8deadSopenharmony_ci    where <id> is not a name returned from a previous call to GenQueries,
3075bd8deadSopenharmony_ci    or if such a name has since been deleted with DeleteQueries.
3085bd8deadSopenharmony_ci
3095bd8deadSopenharmony_ci    The error INVALID_OPERATION is generated if GetQueryObjecti64v or
3105bd8deadSopenharmony_ci    GetQueryObjectui64v is called where <id> is not the name of a query
3115bd8deadSopenharmony_ci    object.
3125bd8deadSopenharmony_ci
3135bd8deadSopenharmony_ci    The error INVALID_OPERATION is generated if GetQueryObjecti64v or
3145bd8deadSopenharmony_ci    GetQueryObjectui64v is called where <id> is the name of a currently
3155bd8deadSopenharmony_ci    active query object.
3165bd8deadSopenharmony_ci
3175bd8deadSopenharmony_ci    The error INVALID_ENUM is generated if GetQueryObjecti64v or
3185bd8deadSopenharmony_ci    GetQueryObjectui64v is called where <pname> is not QUERY_RESULT or
3195bd8deadSopenharmony_ci    QUERY_RESULT_AVAILABLE.
3205bd8deadSopenharmony_ci
3215bd8deadSopenharmony_ciNew State
3225bd8deadSopenharmony_ci
3235bd8deadSopenharmony_ci    None.
3245bd8deadSopenharmony_ci
3255bd8deadSopenharmony_ciExamples
3265bd8deadSopenharmony_ci
3275bd8deadSopenharmony_ci    (1) Here is some rough sample code that demonstrates the intended usage
3285bd8deadSopenharmony_ci        of this extension.
3295bd8deadSopenharmony_ci
3305bd8deadSopenharmony_ci        GLuint queries[N];
3315bd8deadSopenharmony_ci        GLint available = 0;
3325bd8deadSopenharmony_ci        // timer queries can contain more than 32 bits of data, so always
3335bd8deadSopenharmony_ci        // query them using the 64 bit types to avoid overflow
3345bd8deadSopenharmony_ci        GLuint64 timeElapsed = 0;
3355bd8deadSopenharmony_ci
3365bd8deadSopenharmony_ci        // Create a query object.
3375bd8deadSopenharmony_ci        glGenQueries(N, queries);
3385bd8deadSopenharmony_ci
3395bd8deadSopenharmony_ci        // Start query 1
3405bd8deadSopenharmony_ci        glBeginQuery(GL_TIME_ELAPSED, queries[0]);
3415bd8deadSopenharmony_ci
3425bd8deadSopenharmony_ci        // Draw object 1
3435bd8deadSopenharmony_ci        ....
3445bd8deadSopenharmony_ci
3455bd8deadSopenharmony_ci        // End query 1
3465bd8deadSopenharmony_ci        glEndQuery(GL_TIME_ELAPSED);
3475bd8deadSopenharmony_ci
3485bd8deadSopenharmony_ci        ...
3495bd8deadSopenharmony_ci
3505bd8deadSopenharmony_ci        // Start query N
3515bd8deadSopenharmony_ci        glBeginQuery(GL_TIME_ELAPSED, queries[N-1]);
3525bd8deadSopenharmony_ci
3535bd8deadSopenharmony_ci        // Draw object N
3545bd8deadSopenharmony_ci        ....
3555bd8deadSopenharmony_ci
3565bd8deadSopenharmony_ci        // End query N
3575bd8deadSopenharmony_ci        glEndQuery(GL_TIME_ELAPSED);
3585bd8deadSopenharmony_ci
3595bd8deadSopenharmony_ci        // Wait for all results to become available
3605bd8deadSopenharmony_ci        while (!available) {
3615bd8deadSopenharmony_ci            glGetQueryObjectiv(queries[N-1], GL_QUERY_RESULT_AVAILABLE, &available);
3625bd8deadSopenharmony_ci        }
3635bd8deadSopenharmony_ci
3645bd8deadSopenharmony_ci        for (i = 0; i < N; i++) {
3655bd8deadSopenharmony_ci            // See how much time the rendering of object i took in nanoseconds.
3665bd8deadSopenharmony_ci            glGetQueryObjectui64v(queries[i], GL_QUERY_RESULT, &timeElapsed);
3675bd8deadSopenharmony_ci
3685bd8deadSopenharmony_ci            // Do something useful with the time.  Note that care should be
3695bd8deadSopenharmony_ci            // taken to use all significant bits of the result, not just the
3705bd8deadSopenharmony_ci            // least significant 32 bits.
3715bd8deadSopenharmony_ci            AdjustObjectLODBasedOnDrawTime(i, timeElapsed);
3725bd8deadSopenharmony_ci        }
3735bd8deadSopenharmony_ci
3745bd8deadSopenharmony_ci        This example is sub-optimal in that it stalls at the end of every
3755bd8deadSopenharmony_ci        frame to wait for query results.  Ideally, the collection of results
3765bd8deadSopenharmony_ci        would be delayed one frame to minimize the amount of time spent
3775bd8deadSopenharmony_ci        waiting for the GPU to finish rendering.
3785bd8deadSopenharmony_ci
3795bd8deadSopenharmony_ci    (2) This example is basically the same as the example above but uses
3805bd8deadSopenharmony_ci        QueryCounter instead.
3815bd8deadSopenharmony_ci
3825bd8deadSopenharmony_ci        GLuint queries[N+1];
3835bd8deadSopenharmony_ci        GLint available = 0;
3845bd8deadSopenharmony_ci        // timer queries can contain more than 32 bits of data, so always
3855bd8deadSopenharmony_ci        // query them using the 64 bit types to avoid overflow
3865bd8deadSopenharmony_ci        GLuint64 timeStart, timeEnd, timeElapsed = 0;
3875bd8deadSopenharmony_ci
3885bd8deadSopenharmony_ci        // Create a query object.
3895bd8deadSopenharmony_ci        glGenQueries(N+1, queries);
3905bd8deadSopenharmony_ci
3915bd8deadSopenharmony_ci        // Query current timestamp 1
3925bd8deadSopenharmony_ci        glQueryCounter(queries[0], GL_TIMESTAMP);
3935bd8deadSopenharmony_ci
3945bd8deadSopenharmony_ci        // Draw object 1
3955bd8deadSopenharmony_ci        ....
3965bd8deadSopenharmony_ci
3975bd8deadSopenharmony_ci        // Query current timestamp N
3985bd8deadSopenharmony_ci        glQueryCounter(queries[N-1], GL_TIMESTAMP);
3995bd8deadSopenharmony_ci
4005bd8deadSopenharmony_ci        // Draw object N
4015bd8deadSopenharmony_ci        ....
4025bd8deadSopenharmony_ci
4035bd8deadSopenharmony_ci        // Query current timestamp N+1
4045bd8deadSopenharmony_ci        glQueryCounter(queries[N], GL_TIMESTAMP);
4055bd8deadSopenharmony_ci
4065bd8deadSopenharmony_ci        // Wait for all results to become available
4075bd8deadSopenharmony_ci        while (!available) {
4085bd8deadSopenharmony_ci            glGetQueryObjectiv(queries[N], GL_QUERY_RESULT_AVAILABLE, &available);
4095bd8deadSopenharmony_ci        }
4105bd8deadSopenharmony_ci
4115bd8deadSopenharmony_ci        for (i = 0; i < N; i++) {
4125bd8deadSopenharmony_ci            // See how much time the rendering of object i took in nanoseconds.
4135bd8deadSopenharmony_ci            glGetQueryObjectui64v(queries[i], GL_QUERY_RESULT, &timeStart);
4145bd8deadSopenharmony_ci            glGetQueryObjectui64v(queries[i+1], GL_QUERY_RESULT, &timeEnd);
4155bd8deadSopenharmony_ci            timeElapsed = timeEnd - timeStart;
4165bd8deadSopenharmony_ci
4175bd8deadSopenharmony_ci            // Do something useful with the time.  Note that care should be
4185bd8deadSopenharmony_ci            // taken to use all significant bits of the result, not just the
4195bd8deadSopenharmony_ci            // least significant 32 bits.
4205bd8deadSopenharmony_ci            AdjustObjectLODBasedOnDrawTime(i, timeElapsed);
4215bd8deadSopenharmony_ci        }
4225bd8deadSopenharmony_ci
4235bd8deadSopenharmony_ci    (3) This example demonstrates how to measure the latency between GL
4245bd8deadSopenharmony_ci        commands reaching the server and being realized in the framebuffer.
4255bd8deadSopenharmony_ci
4265bd8deadSopenharmony_ci        /* Submit a frame of rendering commands */
4275bd8deadSopenharmony_ci        while (!doneRendering) {
4285bd8deadSopenharmony_ci          ...
4295bd8deadSopenharmony_ci          glDrawElements(...);
4305bd8deadSopenharmony_ci        }
4315bd8deadSopenharmony_ci
4325bd8deadSopenharmony_ci        /*
4335bd8deadSopenharmony_ci         * Measure rendering latency:
4345bd8deadSopenharmony_ci         *
4355bd8deadSopenharmony_ci         * Some commands may have already been submitted to hardware,
4365bd8deadSopenharmony_ci         * and some of those may have already completed.  The goal is
4375bd8deadSopenharmony_ci         * to measure the time it takes for the remaining commands to
4385bd8deadSopenharmony_ci         * complete, thereby measuring how far behind the app the GPU
4395bd8deadSopenharmony_ci         * is lagging, but without synchronizing the GPU with the CPU.
4405bd8deadSopenharmony_ci         */
4415bd8deadSopenharmony_ci
4425bd8deadSopenharmony_ci        /* Queue a query to find out when the frame finishes on the GL */
4435bd8deadSopenharmony_ci        glQueryCounter(endFrameQuery, GL_TIMESTAMP);
4445bd8deadSopenharmony_ci
4455bd8deadSopenharmony_ci        /* Get the current GL time without stalling the GL */
4465bd8deadSopenharmony_ci        glGet(GL_TIMESTAMP, &flushTime);
4475bd8deadSopenharmony_ci
4485bd8deadSopenharmony_ci        /* Finish the frame, submitting outstanding commands to the GL */
4495bd8deadSopenharmony_ci        SwapBuffers();
4505bd8deadSopenharmony_ci
4515bd8deadSopenharmony_ci        /* Render another frame */
4525bd8deadSopenharmony_ci
4535bd8deadSopenharmony_ci        /*
4545bd8deadSopenharmony_ci         * Later, compare the query result of <endFrameQuery>
4555bd8deadSopenharmony_ci         * and <flushTime> to measure the latency of the frame
4565bd8deadSopenharmony_ci         */
4575bd8deadSopenharmony_ci
4585bd8deadSopenharmony_ci
4595bd8deadSopenharmony_ciIssues from EXT_timer_query
4605bd8deadSopenharmony_ci
4615bd8deadSopenharmony_ci    (1) What time interval is being measured?
4625bd8deadSopenharmony_ci
4635bd8deadSopenharmony_ci    RESOLVED:  The timer starts when all commands prior to BeginQuery() have
4645bd8deadSopenharmony_ci    been fully executed.  At that point, everything that should be drawn by
4655bd8deadSopenharmony_ci    those commands has been written to the framebuffer.  The timer stops
4665bd8deadSopenharmony_ci    when all commands prior to EndQuery() have been fully executed.
4675bd8deadSopenharmony_ci
4685bd8deadSopenharmony_ci    (2) What unit of time will time intervals be returned in?
4695bd8deadSopenharmony_ci
4705bd8deadSopenharmony_ci    RESOLVED:  Nanoseconds (10^-9 seconds).  This unit of measurement allows
4715bd8deadSopenharmony_ci    for reasonably accurate timing of even small blocks of rendering
4725bd8deadSopenharmony_ci    commands.  The granularity of the timer is implementation-dependent.  A
4735bd8deadSopenharmony_ci    32-bit query counter can express intervals of up to approximately 4
4745bd8deadSopenharmony_ci    seconds.
4755bd8deadSopenharmony_ci
4765bd8deadSopenharmony_ci    (3) What should be the minimum number of counter bits for timer queries?
4775bd8deadSopenharmony_ci
4785bd8deadSopenharmony_ci    RESOLVED:  30 bits, which will allow timing sections that take up to 1
4795bd8deadSopenharmony_ci    second to render.
4805bd8deadSopenharmony_ci
4815bd8deadSopenharmony_ci    (4) How are counter results of more than 32 bits returned?
4825bd8deadSopenharmony_ci
4835bd8deadSopenharmony_ci    RESOLVED:  Via two new datatypes, int64EXT and uint64EXT, and their
4845bd8deadSopenharmony_ci    corresponding GetQueryObject entry points.  These types hold integer
4855bd8deadSopenharmony_ci    values and have a minimum bit width of 64.
4865bd8deadSopenharmony_ci
4875bd8deadSopenharmony_ci    UPDATE: This resolution was relevant for EXT_timer_query and OpenGL 2.0.
4885bd8deadSopenharmony_ci    OpenGL 3.2 now has int64 and uint64 datatypes as part of the core spec.
4895bd8deadSopenharmony_ci
4905bd8deadSopenharmony_ci    (5) Should the extension measure total time elapsed between the full
4915bd8deadSopenharmony_ci        completion of the BeginQuery and EndQuery commands, or just time
4925bd8deadSopenharmony_ci        spent in the graphics library?
4935bd8deadSopenharmony_ci
4945bd8deadSopenharmony_ci    RESOLVED:  This extension will measure the total time elapsed between
4955bd8deadSopenharmony_ci    the full completion of these commands.  Future extensions may implement
4965bd8deadSopenharmony_ci    a query to determine time elapsed at different stages of the graphics
4975bd8deadSopenharmony_ci    pipeline.
4985bd8deadSopenharmony_ci
4995bd8deadSopenharmony_ci    (6) This extension introduces a second query type supported by
5005bd8deadSopenharmony_ci        BeginQuery/EndQuery.  Can multiple query types be active
5015bd8deadSopenharmony_ci        simultaneously?
5025bd8deadSopenharmony_ci
5035bd8deadSopenharmony_ci    RESOLVED:  Yes; an application may perform an occlusion query and a
5045bd8deadSopenharmony_ci    timer query simultaneously.  An application can not perform multiple
5055bd8deadSopenharmony_ci    occlusion queries or multiple timer queries simultaneously.  An
5065bd8deadSopenharmony_ci    application also can not use the same query object for an occlusion
5075bd8deadSopenharmony_ci    query and a timer query simultaneously.
5085bd8deadSopenharmony_ci
5095bd8deadSopenharmony_ci    (7) Do query objects have a query type permanently associated with them?
5105bd8deadSopenharmony_ci
5115bd8deadSopenharmony_ci    RESOLVED:  No.  A single query object can be used to perform different
5125bd8deadSopenharmony_ci    types of queries, but not at the same time.
5135bd8deadSopenharmony_ci
5145bd8deadSopenharmony_ci    Having a fixed type for each query object simplifies some aspects of the
5155bd8deadSopenharmony_ci    implementation -- not having to deal with queries with different result
5165bd8deadSopenharmony_ci    sizes, for example.  It would also mean that BeginQuery() with a query
5175bd8deadSopenharmony_ci    object of the "wrong" type would result in an INVALID_OPERATION error.
5185bd8deadSopenharmony_ci
5195bd8deadSopenharmony_ci    UPDATE: This resolution was relevant for EXT_timer_query and OpenGL 2.0.
5205bd8deadSopenharmony_ci    Since EXT_transform_feedback has since been incorporated into the core,
5215bd8deadSopenharmony_ci    the resolution is that BeginQuery will generate error INVALID_OPERATION
5225bd8deadSopenharmony_ci    if <id> represents a query object of a different type.
5235bd8deadSopenharmony_ci
5245bd8deadSopenharmony_ci    (8) How predictable/repeatable are the results returned by the timer
5255bd8deadSopenharmony_ci        query?
5265bd8deadSopenharmony_ci
5275bd8deadSopenharmony_ci    RESOLVED:  In general, the amount of time needed to render the same
5285bd8deadSopenharmony_ci    primitives should be fairly constant.  But there may be many other
5295bd8deadSopenharmony_ci    system issues (e.g., context switching on the CPU and GPU, virtual
5305bd8deadSopenharmony_ci    memory page faults, memory cache behavior on the CPU and GPU) that can
5315bd8deadSopenharmony_ci    cause times to vary wildly.
5325bd8deadSopenharmony_ci
5335bd8deadSopenharmony_ci    Note that modern GPUs are generally highly pipelined, and may be
5345bd8deadSopenharmony_ci    processing different primitives in different pipeline stages
5355bd8deadSopenharmony_ci    simultaneously.  In this extension, the timers start and stop when the
5365bd8deadSopenharmony_ci    BeginQuery/EndQuery commands reach the bottom of the rendering pipeline.
5375bd8deadSopenharmony_ci    What that means is that by the time the timer starts, the GL driver on
5385bd8deadSopenharmony_ci    the CPU may have started work on GL commands issued after BeginQuery,
5395bd8deadSopenharmony_ci    and the higher pipeline stages (e.g., vertex transformation) may have
5405bd8deadSopenharmony_ci    started as well.
5415bd8deadSopenharmony_ci
5425bd8deadSopenharmony_ci   (9) What should the new 64 bit integer type be called?
5435bd8deadSopenharmony_ci
5445bd8deadSopenharmony_ci    RESOLVED: The new types will be called GLint64EXT/GLuint64EXT  The new
5455bd8deadSopenharmony_ci    command suffixes will be i64 and ui64.  These names clearly convey the
5465bd8deadSopenharmony_ci    minimum size of the types.  These types are similar to the C99 standard
5475bd8deadSopenharmony_ci    type int_least64_t, but we use names similar to the C99 optional type
5485bd8deadSopenharmony_ci    int64_t for simplicity.
5495bd8deadSopenharmony_ci
5505bd8deadSopenharmony_ci    UPDATE: This resolution was relevant for EXT_timer_query and OpenGL 2.0.
5515bd8deadSopenharmony_ci    OpenGL 3.2 now has int64 and uint64 datatypes as part of the core spec.
5525bd8deadSopenharmony_ci    The i64 suffix already exists in OpenGL 3.2 and the ui64 suffix has been
5535bd8deadSopenharmony_ci    added as part of this extension.
5545bd8deadSopenharmony_ci
5555bd8deadSopenharmony_ciIssues
5565bd8deadSopenharmony_ci
5575bd8deadSopenharmony_ci   (10) What about tile-based implementations? The effects of a command are
5585bd8deadSopenharmony_ci        not complete until the frame is completely rendered. Timing recorded
5595bd8deadSopenharmony_ci        before the frame is complete may not be what developers expect. Also
5605bd8deadSopenharmony_ci        the amount of time needed to render the same primitives is not
5615bd8deadSopenharmony_ci        consistent, which conflicts with issue (8) above. The time depends on
5625bd8deadSopenharmony_ci        how early or late in the scene it is placed.
5635bd8deadSopenharmony_ci
5645bd8deadSopenharmony_ci    RESOLVED: The current language supports tile-based rendering okay as it
5655bd8deadSopenharmony_ci    is written. Developers are warned that using timers on tile-based
5665bd8deadSopenharmony_ci    implementation may not produce results they expect since rendering is not
5675bd8deadSopenharmony_ci    done in a linear order. Timing results are calculated when the frame is
5685bd8deadSopenharmony_ci    completed and may depend on how early or late in the scene it is placed.
5695bd8deadSopenharmony_ci
5705bd8deadSopenharmony_ci   (11) Can the GL implementation use different clocks to implement the
5715bd8deadSopenharmony_ci        TIME_ELAPSED and TIMESTAMP queries?
5725bd8deadSopenharmony_ci
5735bd8deadSopenharmony_ci    RESOLVED: Yes, the implementation can use different internal clocks to
5745bd8deadSopenharmony_ci    implement TIME_ELAPSED and TIMESTAMP. If different clocks are
5755bd8deadSopenharmony_ci    used it is possible there is a slight discrepancy when comparing queries
5765bd8deadSopenharmony_ci    made from TIME_ELAPSED and TIMESTAMP; they may have slight
5775bd8deadSopenharmony_ci    differences when both are used to measure the same sequence. However, this
5785bd8deadSopenharmony_ci    is unlikely to affect real applications since comparing the two queries is
5795bd8deadSopenharmony_ci    not expected to be useful.
5805bd8deadSopenharmony_ci
5815bd8deadSopenharmony_ci   (12) Why do BeginQuery and QueryCounter have the same arguments in the
5825bd8deadSopenharmony_ci        opposite order?
5835bd8deadSopenharmony_ci
5845bd8deadSopenharmony_ci    RESOLVED: Due to an unfortunate oversight, which cannot be fixed at
5855bd8deadSopenharmony_ci    this point.
5865bd8deadSopenharmony_ci
5875bd8deadSopenharmony_ci
5885bd8deadSopenharmony_ciRevision History
5895bd8deadSopenharmony_ci
5905bd8deadSopenharmony_ci    Rev.  Date          Author    Changes
5915bd8deadSopenharmony_ci    ----  ------------  --------  -------------------------------------------
5925bd8deadSopenharmony_ci    13    Aug 9, 2014   Jon Leech Fix typo in example 3 (bug 12552).
5935bd8deadSopenharmony_ci
5945bd8deadSopenharmony_ci    12    Jul 11, 2013  Jon Leech Change type of queries[] in sample code to
5955bd8deadSopenharmony_ci                                  GLuint (public bug 432).
5965bd8deadSopenharmony_ci
5975bd8deadSopenharmony_ci    11    Apr 13, 2012  Jon Leech Clean up error language, add error for
5985bd8deadSopenharmony_ci                                  query objects which are not of type
5995bd8deadSopenharmony_ci                                  TIMESTAMP, and add issue 12 (Khronos
6005bd8deadSopenharmony_ci                                  internal bug 7662)
6015bd8deadSopenharmony_ci
6025bd8deadSopenharmony_ci    10    June 3, 2011  dkoch     Add INVALID_OPERATION error when calling
6035bd8deadSopenharmony_ci                                  QueryCounter with a non-generated <id> in
6045bd8deadSopenharmony_ci                                  the core profile (Khronos internal bug 7662).
6055bd8deadSopenharmony_ci
6065bd8deadSopenharmony_ci     9    Dec 18, 2009  pdaniell  Remove ambiguous language about "interuptions
6075bd8deadSopenharmony_ci                                  to the GL". Rename CURRENT_TIME to TIMESTAMP.
6085bd8deadSopenharmony_ci
6095bd8deadSopenharmony_ci     8    Dec 10, 2009  Jon Leech Improve description of QueryCounter command.
6105bd8deadSopenharmony_ci
6115bd8deadSopenharmony_ci     7    Dec 10, 2009  Jon Leech Replace non-ASCII punctuation.
6125bd8deadSopenharmony_ci
6135bd8deadSopenharmony_ci     6    Dec 07, 2009  pdaniell  Remove ARB suffix from new tokens for core.
6145bd8deadSopenharmony_ci
6155bd8deadSopenharmony_ci     5    Oct 29, 2009  pdaniell  TIMESTAMP_ARB renamed to CURRENT_TIME_ARB.
6165bd8deadSopenharmony_ci                                  Issue (11) raised about using different
6175bd8deadSopenharmony_ci                                  clocks to implement CURRENT_TIME and
6185bd8deadSopenharmony_ci                                  TIME_ELAPSED queries. Add example (3) for
6195bd8deadSopenharmony_ci                                  calculating the GL latency.
6205bd8deadSopenharmony_ci
6215bd8deadSopenharmony_ci     4    Oct 23, 2009  pdaniell  Add support for TIMESTAMP_ARB as a <value>
6225bd8deadSopenharmony_ci                                  to Get* to allow synchronous time query.
6235bd8deadSopenharmony_ci
6245bd8deadSopenharmony_ci     3    Oct 15, 2009  pdaniell  Resolved Issue (10). Added Interactions
6255bd8deadSopenharmony_ci                                  with NV_present_video and NV_video_capture
6265bd8deadSopenharmony_ci                                  section.
6275bd8deadSopenharmony_ci
6285bd8deadSopenharmony_ci     2    Oct 15, 2009  pdaniell  Clarified some of the old EXT_timer_query
6295bd8deadSopenharmony_ci                                  Issues wrt OpenGL 3.2. Added specification
6305bd8deadSopenharmony_ci                                  for the TIMESTAMP_ARB time. Added new Issue
6315bd8deadSopenharmony_ci                                  for tile-based implementations. Issue 3
6325bd8deadSopenharmony_ci                                  resolution added to the spec.
6335bd8deadSopenharmony_ci
6345bd8deadSopenharmony_ci     1    Oct 13, 2009  pdaniell  Initial revision based on EXT_timer_query
635