1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/angle/extensions/ANGLE_timer_query.txt Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,591 @@ 1.4 +Name 1.5 + 1.6 + ANGLE_timer_query 1.7 + 1.8 +Name Strings 1.9 + 1.10 + GL_ANGLE_timer_query 1.11 + 1.12 +Contributors 1.13 + 1.14 + Contributors to ARB_occlusion_query 1.15 + Contributors to EXT_timer_query 1.16 + Contributors to ARB_timer_query 1.17 + Ben Vanik, Google Inc. 1.18 + Daniel Koch, TransGaming Inc. 1.19 + 1.20 +Contact 1.21 + 1.22 + Ben Vanik, Google Inc. (benvanik 'at' google 'dot' com) 1.23 + 1.24 +Status 1.25 + 1.26 + Draft 1.27 + 1.28 +Version 1.29 + 1.30 + Last Modified Date: Apr 28, 2011 1.31 + Author Revision: 1 1.32 + 1.33 +Number 1.34 + 1.35 + OpenGL ES Extension #?? 1.36 + 1.37 +Dependencies 1.38 + 1.39 + OpenGL ES 2.0 is required. 1.40 + 1.41 + The extension is written against the OpenGL ES 2.0 specification. 1.42 + 1.43 +Overview 1.44 + 1.45 + Applications can benefit from accurate timing information in a number of 1.46 + different ways. During application development, timing information can 1.47 + help identify application or driver bottlenecks. At run time, 1.48 + applications can use timing information to dynamically adjust the amount 1.49 + of detail in a scene to achieve constant frame rates. OpenGL 1.50 + implementations have historically provided little to no useful timing 1.51 + information. Applications can get some idea of timing by reading timers 1.52 + on the CPU, but these timers are not synchronized with the graphics 1.53 + rendering pipeline. Reading a CPU timer does not guarantee the completion 1.54 + of a potentially large amount of graphics work accumulated before the 1.55 + timer is read, and will thus produce wildly inaccurate results. 1.56 + glFinish() can be used to determine when previous rendering commands have 1.57 + been completed, but will idle the graphics pipeline and adversely affect 1.58 + application performance. 1.59 + 1.60 + This extension provides a query mechanism that can be used to determine 1.61 + the amount of time it takes to fully complete a set of GL commands, and 1.62 + without stalling the rendering pipeline. It uses the query object 1.63 + mechanisms first introduced in the occlusion query extension, which allow 1.64 + time intervals to be polled asynchronously by the application. 1.65 + 1.66 +IP Status 1.67 + 1.68 + No known IP claims. 1.69 + 1.70 +New Procedures and Functions 1.71 + 1.72 + void GenQueriesANGLE(sizei n, uint *ids); 1.73 + void DeleteQueriesANGLE(sizei n, const uint *ids); 1.74 + boolean IsQueryANGLE(uint id); 1.75 + void BeginQueryANGLE(enum target, uint id); 1.76 + void EndQueryANGLE(enum target); 1.77 + void QueryCounterANGLE(uint id, enum target); 1.78 + void GetQueryivANGLE(enum target, enum pname, int *params); 1.79 + void GetQueryObjectivANGLE(uint id, enum pname, int *params); 1.80 + void GetQueryObjectuivANGLE(uint id, enum pname, uint *params); 1.81 + void GetQueryObjecti64vANGLE(uint id, enum pname, int64 *params); 1.82 + void GetQueryObjectui64vANGLE(uint id, enum pname, uint64 *params); 1.83 + 1.84 +New Tokens 1.85 + 1.86 + Accepted by the <pname> parameter of GetQueryivANGLE: 1.87 + 1.88 + QUERY_COUNTER_BITS_ANGLE 0x8864 1.89 + CURRENT_QUERY_ANGLE 0x8865 1.90 + 1.91 + Accepted by the <pname> parameter of GetQueryObjectivANGLE, 1.92 + GetQueryObjectuivANGLE, GetQueryObjecti64vANGLE, and 1.93 + GetQueryObjectui64vANGLE: 1.94 + 1.95 + QUERY_RESULT_ANGLE 0x8866 1.96 + QUERY_RESULT_AVAILABLE_ANGLE 0x8867 1.97 + 1.98 + Accepted by the <target> parameter of BeginQueryANGLE, EndQueryANGLE, and 1.99 + GetQueryivANGLE: 1.100 + 1.101 + TIME_ELAPSED_ANGLE 0x88BF 1.102 + 1.103 + Accepted by the <target> parameter of GetQueryivANGLE and 1.104 + QueryCounterANGLE: 1.105 + 1.106 + TIMESTAMP_ANGLE 0x8E28 1.107 + 1.108 +Additions to Chapter 2 of the OpenGL ES 2.0 Specification (OpenGL ES Operation) 1.109 + 1.110 + (Modify table 2.1, Correspondence of command suffix letters to GL argument) 1.111 + Add two new types: 1.112 + 1.113 + Letter Corresponding GL Type 1.114 + ------ --------------------- 1.115 + i64 int64ANGLE 1.116 + ui64 uint64ANGLE 1.117 + 1.118 + (Modify table 2.2, GL data types) Add two new types: 1.119 + 1.120 + GL Type Minimum Bit Width Description 1.121 + ------- ----------------- ----------------------------- 1.122 + int64ANGLE 64 Signed 2's complement integer 1.123 + uint64ANGLE 64 Unsigned binary integer 1.124 + 1.125 +Additions to Chapter 5 of the OpenGL ES 2.0 Specification (Special Functions) 1.126 + 1.127 + Add a new section 5.3 "Timer Queries": 1.128 + 1.129 + "5.3 Timer Queries 1.130 + 1.131 + Timer queries use query objects to track the amount of time needed to 1.132 + fully complete a set of GL commands, or to determine the current time 1.133 + of the GL. 1.134 + 1.135 + Timer queries are associated with query objects. The command 1.136 + 1.137 + void GenQueriesANGLE(sizei n, uint *ids); 1.138 + 1.139 + returns <n> previously unused query object names in <ids>. These 1.140 + names are marked as used, but no object is associated with them until 1.141 + the first time they are used by BeginQueryANGLE. Query objects contain 1.142 + one piece of state, an integer result value. This result value is 1.143 + initialized to zero when the object is created. Any positive integer 1.144 + except for zero (which is reserved for the GL) is a valid query 1.145 + object name. 1.146 + 1.147 + Query objects are deleted by calling 1.148 + 1.149 + void DeleteQueriesANGLE(sizei n, const uint *ids); 1.150 + 1.151 + <ids> contains <n> names of query objects to be deleted. After a 1.152 + query object is deleted, its name is again unused. Unused names in 1.153 + <ids> are silently ignored. 1.154 + If an active query object is deleted its name immediately becomes unused, 1.155 + but the underlying object is not deleted until it is no longer active. 1.156 + 1.157 + A timer query can be started and finished by calling 1.158 + 1.159 + void BeginQueryANGLE(enum target, uint id); 1.160 + void EndQueryANGLE(enum target); 1.161 + 1.162 + where <target> is TIME_ELAPSED_ANGLE. If BeginQueryANGLE is called 1.163 + with an unused <id>, that name is marked as used and associated with 1.164 + a new query object. 1.165 + 1.166 + If BeginQueryANGLE is called with an <id> of zero, if the active query 1.167 + object name for <target> is non-zero, if <id> is the name of an existing 1.168 + query object whose type does not match <target>, or if <id> is the active 1.169 + query object name for any query type, the error INVALID_OPERATION is 1.170 + generated. If EndQueryANGLE is called while no query with the same target 1.171 + is in progress, an INVALID_OPERATION error is generated. 1.172 + 1.173 + When BeginQueryANGLE and EndQueryANGLE are called with a <target> of 1.174 + TIME_ELAPSED_ANGLE, the GL prepares to start and stop the timer used for 1.175 + timer queries. The timer is started or stopped when the effects from all 1.176 + previous commands on the GL client and server state and the framebuffer 1.177 + have been fully realized. The BeginQueryANGLE and EndQueryANGLE commands 1.178 + may return before the timer is actually started or stopped. When the timer 1.179 + query timer is finally stopped, the elapsed time (in nanoseconds) is 1.180 + written to the corresponding query object as the query result value, and 1.181 + the query result for that object is marked as available. 1.182 + 1.183 + If the elapsed time overflows the number of bits, <n>, available to hold 1.184 + elapsed time, its value becomes undefined. It is recommended, but not 1.185 + required, that implementations handle this overflow case by saturating at 1.186 + 2^n - 1. 1.187 + 1.188 + The necessary state is a single bit indicating whether an timer 1.189 + query is active, the identifier of the currently active timer 1.190 + query, and a counter keeping track of the time that has passed. 1.191 + 1.192 + When the command 1.193 + 1.194 + void QueryCounterANGLE(uint id, enum target); 1.195 + 1.196 + is called with <target> TIMESTAMP_ANGLE, the GL records the current time 1.197 + into the corresponding query object. The time is recorded after all 1.198 + previous commands on the GL client and server state and the framebuffer 1.199 + have been fully realized. When the time is recorded, the query result for 1.200 + that object is marked available. QueryCounterANGLE timer queries can be 1.201 + used within a BeginQueryANGLE / EndQueryANGLE block where the <target> is 1.202 + TIME_ELAPSED_ANGLE and it does not affect the result of that query object. 1.203 + The error INVALID_OPERATION is generated if the <id> is already in use 1.204 + within a BeginQueryANGLE/EndQueryANGLE block." 1.205 + 1.206 +Additions to Chapter 6 of the OpenGL ES 2.0 Specification (State and State 1.207 +Requests) 1.208 + 1.209 + Add a new section 6.1.9 "Timer Queries": 1.210 + 1.211 + "The command 1.212 + 1.213 + boolean IsQueryANGLE(uint id); 1.214 + 1.215 + returns TRUE if <id> is the name of a query object. If <id> is zero, 1.216 + or if <id> is a non-zero value that is not the name of a query 1.217 + object, IsQueryANGLE returns FALSE. 1.218 + 1.219 + Information about a query target can be queried with the command 1.220 + 1.221 + void GetQueryivANGLE(enum target, enum pname, int *params); 1.222 + 1.223 + <target> identifies the query target and can be TIME_ELAPSED_ANGLE or 1.224 + TIMESTAMP_ANGLE for timer queries. 1.225 + 1.226 + If <pname> is CURRENT_QUERY_ANGLE, the name of the currently active query 1.227 + for <target>, or zero if no query is active, will be placed in <params>. 1.228 + 1.229 + If <pname> is QUERY_COUNTER_BITS_ANGLE, the implementation-dependent number 1.230 + of bits used to hold the query result for <target> will be placed in 1.231 + <params>. The number of query counter bits may be zero, in which case 1.232 + the counter contains no useful information. 1.233 + 1.234 + For timer queries (TIME_ELAPSED_ANGLE and TIMESTAMP_ANGLE), if the number 1.235 + of bits is non-zero, the minimum number of bits allowed is 30 which 1.236 + will allow at least 1 second of timing. 1.237 + 1.238 + The state of a query object can be queried with the commands 1.239 + 1.240 + void GetQueryObjectivANGLE(uint id, enum pname, int *params); 1.241 + void GetQueryObjectuivANGLE(uint id, enum pname, uint *params); 1.242 + void GetQueryObjecti64vANGLE(uint id, enum pname, int64 *params); 1.243 + void GetQueryObjectui64vANGLE(uint id, enum pname, uint64 *params); 1.244 + 1.245 + If <id> is not the name of a query object, or if the query object 1.246 + named by <id> is currently active, then an INVALID_OPERATION error is 1.247 + generated. 1.248 + 1.249 + If <pname> is QUERY_RESULT_ANGLE, then the query object's result 1.250 + value is returned as a single integer in <params>. If the value is so 1.251 + large in magnitude that it cannot be represented with the requested type, 1.252 + then the nearest value representable using the requested type is 1.253 + returned. If the number of query counter bits for target is zero, then 1.254 + the result is returned as a single integer with the value zero. 1.255 + 1.256 + There may be an indeterminate delay before the above query returns. If 1.257 + <pname> is QUERY_RESULT_AVAILABLE_ANGLE, FALSE is returned if such a delay 1.258 + would be required; otherwise TRUE is returned. It must always be true 1.259 + that if any query object returns a result available of TRUE, all queries 1.260 + of the same type issued prior to that query must also return TRUE. 1.261 + 1.262 + Querying the state for a given timer query forces that timer query to 1.263 + complete within a finite amount of time. 1.264 + 1.265 + If multiple queries are issued on the same target and id prior to 1.266 + calling GetQueryObject[u]i[64]vANGLE, the result returned will always be 1.267 + from the last query issued. The results from any queries before the 1.268 + last one will be lost if the results are not retrieved before starting 1.269 + a new query on the same <target> and <id>." 1.270 + 1.271 +Errors 1.272 + 1.273 + The error INVALID_VALUE is generated if GenQueriesANGLE is called where 1.274 + <n> is negative. 1.275 + 1.276 + The error INVALID_VALUE is generated if DeleteQueriesANGLE is called 1.277 + where <n> is negative. 1.278 + 1.279 + The error INVALID_OPERATION is generated if BeginQueryANGLE is called 1.280 + when a query of the given <target> is already active. 1.281 + 1.282 + The error INVALID_OPERATION is generated if EndQueryANGLE is called 1.283 + when a query of the given <target> is not active. 1.284 + 1.285 + The error INVALID_OPERATION is generated if BeginQueryANGLE is called 1.286 + where <id> is zero. 1.287 + 1.288 + The error INVALID_OPERATION is generated if BeginQueryANGLE is called 1.289 + where <id> is the name of a query currently in progress. 1.290 + 1.291 + The error INVALID_OPERATION is generated if BeginQueryANGLE is called 1.292 + where <id> is the name of an existing query object whose type does not 1.293 + match <target>. 1.294 + 1.295 + The error INVALID_ENUM is generated if BeginQueryANGLE or EndQueryANGLE 1.296 + is called where <target> is not TIME_ELAPSED_ANGLE. 1.297 + 1.298 + The error INVALID_ENUM is generated if GetQueryivANGLE is called where 1.299 + <target> is not TIME_ELAPSED_ANGLE or TIMESTAMP_ANGLE. 1.300 + 1.301 + The error INVALID_ENUM is generated if GetQueryivANGLE is called where 1.302 + <pname> is not QUERY_COUNTER_BITS_ANGLE or CURRENT_QUERY_ANGLE. 1.303 + 1.304 + The error INVALID_ENUM is generated if QueryCounterANGLE is called where 1.305 + <target> is not TIMESTAMP_ANGLE. 1.306 + 1.307 + The error INVALID_OPERATION is generated if QueryCounterANGLE is called 1.308 + on a query object that is already in use inside a 1.309 + BeginQueryANGLE/EndQueryANGLE. 1.310 + 1.311 + The error INVALID_OPERATION is generated if GetQueryObjectivANGLE, 1.312 + GetQueryObjectuivANGLE, GetQueryObjecti64vANGLE, or 1.313 + GetQueryObjectui64vANGLE is called where <id> is not the name of a query 1.314 + object. 1.315 + 1.316 + The error INVALID_OPERATION is generated if GetQueryObjectivANGLE, 1.317 + GetQueryObjectuivANGLE, GetQueryObjecti64vANGLE, or 1.318 + GetQueryObjectui64vANGLE is called where <id> is the name of a currently 1.319 + active query object. 1.320 + 1.321 + The error INVALID_ENUM is generated if GetQueryObjectivANGLE, 1.322 + GetQueryObjectuivANGLE, GetQueryObjecti64vANGLE, or 1.323 + GetQueryObjectui64vANGLE is called where <pname> is not 1.324 + QUERY_RESULT_ANGLE or QUERY_RESULT_AVAILABLE_ANGLE. 1.325 + 1.326 +New State 1.327 + 1.328 + (Add a new table 6.xx, "Query Operations") 1.329 + 1.330 + Get Value Type Get Command Initial Value Description Sec 1.331 + --------- ---- ----------- ------------- ----------- ------ 1.332 + - B - FALSE query active 5.3 1.333 + CURRENT_QUERY_ANGLE Z+ GetQueryivANGLE 0 active query ID 5.3 1.334 + QUERY_RESULT_ANGLE Z+ GetQueryObjectuivANGLE, 0 samples-passed count 5.3 1.335 + GetQueryObjectui64vANGLE 1.336 + QUERY_RESULT_AVAILABLE_ANGLE B GetQueryObjectivANGLE FALSE query result available 5.3 1.337 + 1.338 +New Implementation Dependent State 1.339 + 1.340 + (Add the following entry to table 6.18): 1.341 + 1.342 + Get Value Type Get Command Minimum Value Description Sec 1.343 + -------------------------- ---- ----------- ------------- ---------------- ------ 1.344 + QUERY_COUNTER_BITS_ANGLE Z+ GetQueryivANGLE see 6.1.9 Number of bits in 6.1.9 1.345 + query counter 1.346 + 1.347 +Examples 1.348 + 1.349 + (1) Here is some rough sample code that demonstrates the intended usage 1.350 + of this extension. 1.351 + 1.352 + GLint queries[N]; 1.353 + GLint available = 0; 1.354 + // timer queries can contain more than 32 bits of data, so always 1.355 + // query them using the 64 bit types to avoid overflow 1.356 + GLuint64ANGLE timeElapsed = 0; 1.357 + 1.358 + // Create a query object. 1.359 + glGenQueriesANGLE(N, queries); 1.360 + 1.361 + // Start query 1 1.362 + glBeginQueryANGLE(GL_TIME_ELAPSED_ANGLE, queries[0]); 1.363 + 1.364 + // Draw object 1 1.365 + .... 1.366 + 1.367 + // End query 1 1.368 + glEndQueryANGLE(GL_TIME_ELAPSED_ANGLE); 1.369 + 1.370 + ... 1.371 + 1.372 + // Start query N 1.373 + glBeginQueryANGLE(GL_TIME_ELAPSED_ANGLE, queries[N-1]); 1.374 + 1.375 + // Draw object N 1.376 + .... 1.377 + 1.378 + // End query N 1.379 + glEndQueryANGLE(GL_TIME_ELAPSED_ANGLE); 1.380 + 1.381 + // Wait for all results to become available 1.382 + while (!available) { 1.383 + glGetQueryObjectivANGLE(queries[N-1], GL_QUERY_RESULT_AVAILABLE_ANGLE, &available); 1.384 + } 1.385 + 1.386 + for (i = 0; i < N; i++) { 1.387 + // See how much time the rendering of object i took in nanoseconds. 1.388 + glGetQueryObjectui64vANGLE(queries[i], GL_QUERY_RESULT_ANGLE, &timeElapsed); 1.389 + 1.390 + // Do something useful with the time. Note that care should be 1.391 + // taken to use all significant bits of the result, not just the 1.392 + // least significant 32 bits. 1.393 + AdjustObjectLODBasedOnDrawTime(i, timeElapsed); 1.394 + } 1.395 + 1.396 + This example is sub-optimal in that it stalls at the end of every 1.397 + frame to wait for query results. Ideally, the collection of results 1.398 + would be delayed one frame to minimize the amount of time spent 1.399 + waiting for the GPU to finish rendering. 1.400 + 1.401 + (2) This example is basically the same as the example above but uses 1.402 + QueryCounter instead. 1.403 + 1.404 + GLint queries[N+1]; 1.405 + GLint available = 0; 1.406 + // timer queries can contain more than 32 bits of data, so always 1.407 + // query them using the 64 bit types to avoid overflow 1.408 + GLuint64ANGLE timeStart, timeEnd, timeElapsed = 0; 1.409 + 1.410 + // Create a query object. 1.411 + glGenQueriesANGLE(N+1, queries); 1.412 + 1.413 + // Query current timestamp 1 1.414 + glQueryCounterANGLE(queries[0], GL_TIMESTAMP_ANGLE); 1.415 + 1.416 + // Draw object 1 1.417 + .... 1.418 + 1.419 + // Query current timestamp N 1.420 + glQueryCounterANGLE(queries[N-1], GL_TIMESTAMP_ANGLE); 1.421 + 1.422 + // Draw object N 1.423 + .... 1.424 + 1.425 + // Query current timestamp N+1 1.426 + glQueryCounterANGLE(queries[N], GL_TIMESTAMP_ANGLE); 1.427 + 1.428 + // Wait for all results to become available 1.429 + while (!available) { 1.430 + glGetQueryObjectivANGLE(queries[N], GL_QUERY_RESULT_AVAILABLE_ANGLE, &available); 1.431 + } 1.432 + 1.433 + for (i = 0; i < N; i++) { 1.434 + // See how much time the rendering of object i took in nanoseconds. 1.435 + glGetQueryObjectui64vANGLE(queries[i], GL_QUERY_RESULT_ANGLE, &timeStart); 1.436 + glGetQueryObjectui64vANGLE(queries[i+1], GL_QUERY_RESULT_ANGLE, &timeEnd); 1.437 + timeElapsed = timeEnd - timeStart; 1.438 + 1.439 + // Do something useful with the time. Note that care should be 1.440 + // taken to use all significant bits of the result, not just the 1.441 + // least significant 32 bits. 1.442 + AdjustObjectLODBasedOnDrawTime(i, timeElapsed); 1.443 + } 1.444 + 1.445 +Issues from EXT_timer_query 1.446 + 1.447 + (1) What time interval is being measured? 1.448 + 1.449 + RESOLVED: The timer starts when all commands prior to BeginQuery() have 1.450 + been fully executed. At that point, everything that should be drawn by 1.451 + those commands has been written to the framebuffer. The timer stops 1.452 + when all commands prior to EndQuery() have been fully executed. 1.453 + 1.454 + (2) What unit of time will time intervals be returned in? 1.455 + 1.456 + RESOLVED: Nanoseconds (10^-9 seconds). This unit of measurement allows 1.457 + for reasonably accurate timing of even small blocks of rendering 1.458 + commands. The granularity of the timer is implementation-dependent. A 1.459 + 32-bit query counter can express intervals of up to approximately 4 1.460 + seconds. 1.461 + 1.462 + (3) What should be the minimum number of counter bits for timer queries? 1.463 + 1.464 + RESOLVED: 30 bits, which will allow timing sections that take up to 1 1.465 + second to render. 1.466 + 1.467 + (4) How are counter results of more than 32 bits returned? 1.468 + 1.469 + RESOLVED: Via two new datatypes, int64ANGLE and uint64ANGLE, and their 1.470 + corresponding GetQueryObject entry points. These types hold integer 1.471 + values and have a minimum bit width of 64. 1.472 + 1.473 + (5) Should the extension measure total time elapsed between the full 1.474 + completion of the BeginQuery and EndQuery commands, or just time 1.475 + spent in the graphics library? 1.476 + 1.477 + RESOLVED: This extension will measure the total time elapsed between 1.478 + the full completion of these commands. Future extensions may implement 1.479 + a query to determine time elapsed at different stages of the graphics 1.480 + pipeline. 1.481 + 1.482 + (6) If multiple query types are supported, can multiple query types be 1.483 + active simultaneously? 1.484 + 1.485 + RESOLVED: Yes; an application may perform a timer query and another 1.486 + type of query simultaneously. An application can not perform multiple 1.487 + timer queries or multiple queries of other types simultaneously. An 1.488 + application also can not use the same query object for another query 1.489 + and a timer query simultaneously. 1.490 + 1.491 + (7) Do query objects have a query type permanently associated with them? 1.492 + 1.493 + RESOLVED: No. A single query object can be used to perform different 1.494 + types of queries, but not at the same time. 1.495 + 1.496 + Having a fixed type for each query object simplifies some aspects of the 1.497 + implementation -- not having to deal with queries with different result 1.498 + sizes, for example. It would also mean that BeginQuery() with a query 1.499 + object of the "wrong" type would result in an INVALID_OPERATION error. 1.500 + 1.501 + UPDATE: This resolution was relevant for EXT_timer_query and OpenGL 2.0. 1.502 + Since EXT_transform_feedback has since been incorporated into the core, 1.503 + the resolution is that BeginQuery will generate error INVALID_OPERATION 1.504 + if <id> represents a query object of a different type. 1.505 + 1.506 + (8) How predictable/repeatable are the results returned by the timer 1.507 + query? 1.508 + 1.509 + RESOLVED: In general, the amount of time needed to render the same 1.510 + primitives should be fairly constant. But there may be many other 1.511 + system issues (e.g., context switching on the CPU and GPU, virtual 1.512 + memory page faults, memory cache behavior on the CPU and GPU) that can 1.513 + cause times to vary wildly. 1.514 + 1.515 + Note that modern GPUs are generally highly pipelined, and may be 1.516 + processing different primitives in different pipeline stages 1.517 + simultaneously. In this extension, the timers start and stop when the 1.518 + BeginQuery/EndQuery commands reach the bottom of the rendering pipeline. 1.519 + What that means is that by the time the timer starts, the GL driver on 1.520 + the CPU may have started work on GL commands issued after BeginQuery, 1.521 + and the higher pipeline stages (e.g., vertex transformation) may have 1.522 + started as well. 1.523 + 1.524 + (9) What should the new 64 bit integer type be called? 1.525 + 1.526 + RESOLVED: The new types will be called GLint64ANGLE/GLuint64ANGLE. The new 1.527 + command suffixes will be i64 and ui64. These names clearly convey the 1.528 + minimum size of the types. These types are similar to the C99 standard 1.529 + type int_least64_t, but we use names similar to the C99 optional type 1.530 + int64_t for simplicity. 1.531 + 1.532 +Issues from ARB_timer_query 1.533 + 1.534 + (10) What about tile-based implementations? The effects of a command are 1.535 + not complete until the frame is completely rendered. Timing recorded 1.536 + before the frame is complete may not be what developers expect. Also 1.537 + the amount of time needed to render the same primitives is not 1.538 + consistent, which conflicts with issue (8) above. The time depends on 1.539 + how early or late in the scene it is placed. 1.540 + 1.541 + RESOLVED: The current language supports tile-based rendering okay as it 1.542 + is written. Developers are warned that using timers on tile-based 1.543 + implementation may not produce results they expect since rendering is not 1.544 + done in a linear order. Timing results are calculated when the frame is 1.545 + completed and may depend on how early or late in the scene it is placed. 1.546 + 1.547 + (11) Can the GL implementation use different clocks to implement the 1.548 + TIME_ELAPSED and TIMESTAMP queries? 1.549 + 1.550 + RESOLVED: Yes, the implemenation can use different internal clocks to 1.551 + implement TIME_ELAPSED and TIMESTAMP. If different clocks are 1.552 + used it is possible there is a slight discrepancy when comparing queries 1.553 + made from TIME_ELAPSED and TIMESTAMP; they may have slight 1.554 + differences when both are used to measure the same sequence. However, this 1.555 + is unlikely to affect real applications since comparing the two queries is 1.556 + not expected to be useful. 1.557 + 1.558 +Issues 1.559 + 1.560 + (12) What should we call this extension? 1.561 + 1.562 + RESOLVED: ANGLE_timer_query 1.563 + 1.564 + (13) Why is this done as a separate extension instead of just supporting 1.565 + ARB_timer_query? 1.566 + 1.567 + ARB_timer_query is written against OpenGL 3.2, which includes a lot of 1.568 + the required support for dealing with query objects. None of these 1.569 + functions or tokens exist in OpenGL ES, and as such have to be added in 1.570 + this specification. 1.571 + 1.572 + (14) How does this extension differ from ARB_timer_query? 1.573 + 1.574 + This extension contains most ARB_timer_query behavior unchanged as well 1.575 + as a subset of the query support required to use it from the core 1.576 + OpenGL 3.2 spec. It omits the glGetInteger(TIMESTAMP) functionality used to 1.577 + query the current time on the GPU, but the behavior for all remaining 1.578 + functionality taken from ARB_timer_query is the same. 1.579 + 1.580 + (15) Are query objects shareable between multiple contexts? 1.581 + 1.582 + RESOLVED: No. Query objects are lightweight and we normally share 1.583 + large data across contexts. Also, being able to share query objects 1.584 + across contexts is not particularly useful. In order to do the async 1.585 + query across contexts, a query on one context would have to be finished 1.586 + before the other context could query it. 1.587 + 1.588 +Revision History 1.589 + 1.590 + Revision 1, 2011/04/28 1.591 + - copied from revision 9 of ARB_timer_query and revision 7 of 1.592 + ARB_occlusion_query 1.593 + - removed language that was clearly not relevant to ES2 1.594 + - rebased changes against the OpenGL ES 2.0 specification