Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenqueryobj.c
Go to the documentation of this file.
00001 /* 00002 * Mesa 3-D graphics library 00003 * Version: 7.1 00004 * 00005 * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. 00006 * 00007 * Permission is hereby granted, free of charge, to any person obtaining a 00008 * copy of this software and associated documentation files (the "Software"), 00009 * to deal in the Software without restriction, including without limitation 00010 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 00011 * and/or sell copies of the Software, and to permit persons to whom the 00012 * Software is furnished to do so, subject to the following conditions: 00013 * 00014 * The above copyright notice and this permission notice shall be included 00015 * in all copies or substantial portions of the Software. 00016 * 00017 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00018 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00019 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 00020 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 00021 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 00022 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00023 */ 00024 00025 00026 #include "glheader.h" 00027 #include "context.h" 00028 #include "hash.h" 00029 #include "imports.h" 00030 #include "queryobj.h" 00031 #include "mtypes.h" 00032 00033 00041 struct gl_query_object * 00042 _mesa_new_query_object(GLcontext *ctx, GLuint id) 00043 { 00044 struct gl_query_object *q = MALLOC_STRUCT(gl_query_object); 00045 (void) ctx; 00046 if (q) { 00047 q->Id = id; 00048 q->Result = 0; 00049 q->Active = GL_FALSE; 00050 q->Ready = GL_TRUE; /* correct, see spec */ 00051 } 00052 return q; 00053 } 00054 00055 00060 void 00061 _mesa_begin_query(GLcontext *ctx, struct gl_query_object *q) 00062 { 00063 /* no-op */ 00064 } 00065 00066 00071 void 00072 _mesa_end_query(GLcontext *ctx, struct gl_query_object *q) 00073 { 00074 q->Ready = GL_TRUE; 00075 } 00076 00077 00082 void 00083 _mesa_wait_query(GLcontext *ctx, struct gl_query_object *q) 00084 { 00085 /* For software drivers, _mesa_end_query() should have completed the query. 00086 * For real hardware, implement a proper WaitQuery() driver function. 00087 */ 00088 assert(q->Ready); 00089 } 00090 00091 00096 void 00097 _mesa_delete_query(GLcontext *ctx, struct gl_query_object *q) 00098 { 00099 _mesa_free(q); 00100 } 00101 00102 00103 static struct gl_query_object * 00104 lookup_query_object(GLcontext *ctx, GLuint id) 00105 { 00106 return (struct gl_query_object *) 00107 _mesa_HashLookup(ctx->Query.QueryObjects, id); 00108 } 00109 00110 00111 00112 void GLAPIENTRY 00113 _mesa_GenQueriesARB(GLsizei n, GLuint *ids) 00114 { 00115 GLuint first; 00116 GET_CURRENT_CONTEXT(ctx); 00117 ASSERT_OUTSIDE_BEGIN_END(ctx); 00118 00119 if (n < 0) { 00120 _mesa_error(ctx, GL_INVALID_VALUE, "glGenQueriesARB(n < 0)"); 00121 return; 00122 } 00123 00124 /* No query objects can be active at this time! */ 00125 if (ctx->Query.CurrentOcclusionObject || 00126 ctx->Query.CurrentTimerObject) { 00127 _mesa_error(ctx, GL_INVALID_OPERATION, "glGenQueriesARB"); 00128 return; 00129 } 00130 00131 first = _mesa_HashFindFreeKeyBlock(ctx->Query.QueryObjects, n); 00132 if (first) { 00133 GLsizei i; 00134 for (i = 0; i < n; i++) { 00135 struct gl_query_object *q 00136 = ctx->Driver.NewQueryObject(ctx, first + i); 00137 if (!q) { 00138 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenQueriesARB"); 00139 return; 00140 } 00141 ids[i] = first + i; 00142 _mesa_HashInsert(ctx->Query.QueryObjects, first + i, q); 00143 } 00144 } 00145 } 00146 00147 00148 void GLAPIENTRY 00149 _mesa_DeleteQueriesARB(GLsizei n, const GLuint *ids) 00150 { 00151 GLint i; 00152 GET_CURRENT_CONTEXT(ctx); 00153 ASSERT_OUTSIDE_BEGIN_END(ctx); 00154 00155 if (n < 0) { 00156 _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteQueriesARB(n < 0)"); 00157 return; 00158 } 00159 00160 /* No query objects can be active at this time! */ 00161 if (ctx->Query.CurrentOcclusionObject || 00162 ctx->Query.CurrentTimerObject) { 00163 _mesa_error(ctx, GL_INVALID_OPERATION, "glDeleteQueriesARB"); 00164 return; 00165 } 00166 00167 for (i = 0; i < n; i++) { 00168 if (ids[i] > 0) { 00169 struct gl_query_object *q = lookup_query_object(ctx, ids[i]); 00170 if (q) { 00171 ASSERT(!q->Active); /* should be caught earlier */ 00172 _mesa_HashRemove(ctx->Query.QueryObjects, ids[i]); 00173 ctx->Driver.DeleteQuery(ctx, q); 00174 } 00175 } 00176 } 00177 } 00178 00179 00180 GLboolean GLAPIENTRY 00181 _mesa_IsQueryARB(GLuint id) 00182 { 00183 GET_CURRENT_CONTEXT(ctx); 00184 ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); 00185 00186 if (id && lookup_query_object(ctx, id)) 00187 return GL_TRUE; 00188 else 00189 return GL_FALSE; 00190 } 00191 00192 00193 void GLAPIENTRY 00194 _mesa_BeginQueryARB(GLenum target, GLuint id) 00195 { 00196 struct gl_query_object *q; 00197 GET_CURRENT_CONTEXT(ctx); 00198 ASSERT_OUTSIDE_BEGIN_END(ctx); 00199 00200 FLUSH_VERTICES(ctx, _NEW_DEPTH); 00201 00202 switch (target) { 00203 case GL_SAMPLES_PASSED_ARB: 00204 if (!ctx->Extensions.ARB_occlusion_query) { 00205 _mesa_error(ctx, GL_INVALID_ENUM, "glBeginQueryARB(target)"); 00206 return; 00207 } 00208 if (ctx->Query.CurrentOcclusionObject) { 00209 _mesa_error(ctx, GL_INVALID_OPERATION, "glBeginQueryARB"); 00210 return; 00211 } 00212 break; 00213 #if FEATURE_EXT_timer_query 00214 case GL_TIME_ELAPSED_EXT: 00215 if (!ctx->Extensions.EXT_timer_query) { 00216 _mesa_error(ctx, GL_INVALID_ENUM, "glBeginQueryARB(target)"); 00217 return; 00218 } 00219 if (ctx->Query.CurrentTimerObject) { 00220 _mesa_error(ctx, GL_INVALID_OPERATION, "glBeginQueryARB"); 00221 return; 00222 } 00223 break; 00224 #endif 00225 default: 00226 _mesa_error(ctx, GL_INVALID_ENUM, "glBeginQueryARB(target)"); 00227 return; 00228 } 00229 00230 if (id == 0) { 00231 _mesa_error(ctx, GL_INVALID_OPERATION, "glBeginQueryARB(id==0)"); 00232 return; 00233 } 00234 00235 q = lookup_query_object(ctx, id); 00236 if (!q) { 00237 /* create new object */ 00238 q = ctx->Driver.NewQueryObject(ctx, id); 00239 if (!q) { 00240 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBeginQueryARB"); 00241 return; 00242 } 00243 _mesa_HashInsert(ctx->Query.QueryObjects, id, q); 00244 } 00245 else { 00246 /* pre-existing object */ 00247 if (q->Active) { 00248 _mesa_error(ctx, GL_INVALID_OPERATION, 00249 "glBeginQueryARB(query already active)"); 00250 return; 00251 } 00252 } 00253 00254 q->Target = target; 00255 q->Active = GL_TRUE; 00256 q->Result = 0; 00257 q->Ready = GL_FALSE; 00258 00259 if (target == GL_SAMPLES_PASSED_ARB) { 00260 ctx->Query.CurrentOcclusionObject = q; 00261 } 00262 #if FEATURE_EXT_timer_query 00263 else if (target == GL_TIME_ELAPSED_EXT) { 00264 ctx->Query.CurrentTimerObject = q; 00265 } 00266 #endif 00267 00268 ctx->Driver.BeginQuery(ctx, q); 00269 } 00270 00271 00272 void GLAPIENTRY 00273 _mesa_EndQueryARB(GLenum target) 00274 { 00275 struct gl_query_object *q; 00276 GET_CURRENT_CONTEXT(ctx); 00277 ASSERT_OUTSIDE_BEGIN_END(ctx); 00278 00279 FLUSH_VERTICES(ctx, _NEW_DEPTH); 00280 00281 switch (target) { 00282 case GL_SAMPLES_PASSED_ARB: 00283 if (!ctx->Extensions.ARB_occlusion_query) { 00284 _mesa_error(ctx, GL_INVALID_ENUM, "glEndQueryARB(target)"); 00285 return; 00286 } 00287 q = ctx->Query.CurrentOcclusionObject; 00288 ctx->Query.CurrentOcclusionObject = NULL; 00289 break; 00290 #if FEATURE_EXT_timer_query 00291 case GL_TIME_ELAPSED_EXT: 00292 if (!ctx->Extensions.EXT_timer_query) { 00293 _mesa_error(ctx, GL_INVALID_ENUM, "glEndQueryARB(target)"); 00294 return; 00295 } 00296 q = ctx->Query.CurrentTimerObject; 00297 ctx->Query.CurrentTimerObject = NULL; 00298 break; 00299 #endif 00300 default: 00301 _mesa_error(ctx, GL_INVALID_ENUM, "glEndQueryARB(target)"); 00302 return; 00303 } 00304 00305 if (!q || !q->Active) { 00306 _mesa_error(ctx, GL_INVALID_OPERATION, 00307 "glEndQueryARB(no matching glBeginQueryARB)"); 00308 return; 00309 } 00310 00311 q->Active = GL_FALSE; 00312 ctx->Driver.EndQuery(ctx, q); 00313 } 00314 00315 00316 void GLAPIENTRY 00317 _mesa_GetQueryivARB(GLenum target, GLenum pname, GLint *params) 00318 { 00319 struct gl_query_object *q; 00320 GET_CURRENT_CONTEXT(ctx); 00321 ASSERT_OUTSIDE_BEGIN_END(ctx); 00322 00323 switch (target) { 00324 case GL_SAMPLES_PASSED_ARB: 00325 if (!ctx->Extensions.ARB_occlusion_query) { 00326 _mesa_error(ctx, GL_INVALID_ENUM, "glEndQueryARB(target)"); 00327 return; 00328 } 00329 q = ctx->Query.CurrentOcclusionObject; 00330 break; 00331 #if FEATURE_EXT_timer_query 00332 case GL_TIME_ELAPSED_EXT: 00333 if (!ctx->Extensions.EXT_timer_query) { 00334 _mesa_error(ctx, GL_INVALID_ENUM, "glEndQueryARB(target)"); 00335 return; 00336 } 00337 q = ctx->Query.CurrentTimerObject; 00338 break; 00339 #endif 00340 default: 00341 _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryivARB(target)"); 00342 return; 00343 } 00344 00345 switch (pname) { 00346 case GL_QUERY_COUNTER_BITS_ARB: 00347 *params = 8 * sizeof(q->Result); 00348 break; 00349 case GL_CURRENT_QUERY_ARB: 00350 *params = q ? q->Id : 0; 00351 break; 00352 default: 00353 _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryivARB(pname)"); 00354 return; 00355 } 00356 } 00357 00358 00359 void GLAPIENTRY 00360 _mesa_GetQueryObjectivARB(GLuint id, GLenum pname, GLint *params) 00361 { 00362 struct gl_query_object *q = NULL; 00363 GET_CURRENT_CONTEXT(ctx); 00364 ASSERT_OUTSIDE_BEGIN_END(ctx); 00365 00366 if (id) 00367 q = lookup_query_object(ctx, id); 00368 00369 if (!q || q->Active) { 00370 _mesa_error(ctx, GL_INVALID_OPERATION, 00371 "glGetQueryObjectivARB(id=%d is invalid or active)", id); 00372 return; 00373 } 00374 00375 switch (pname) { 00376 case GL_QUERY_RESULT_ARB: 00377 if (!q->Ready) 00378 ctx->Driver.WaitQuery(ctx, q); 00379 /* if result is too large for returned type, clamp to max value */ 00380 if (q->Result > 0x7fffffff) { 00381 *params = 0x7fffffff; 00382 } 00383 else { 00384 *params = (GLint)q->Result; 00385 } 00386 break; 00387 case GL_QUERY_RESULT_AVAILABLE_ARB: 00388 if (!q->Ready) 00389 ctx->Driver.CheckQuery( ctx, q ); 00390 *params = q->Ready; 00391 break; 00392 default: 00393 _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryObjectivARB(pname)"); 00394 return; 00395 } 00396 } 00397 00398 00399 void GLAPIENTRY 00400 _mesa_GetQueryObjectuivARB(GLuint id, GLenum pname, GLuint *params) 00401 { 00402 struct gl_query_object *q = NULL; 00403 GET_CURRENT_CONTEXT(ctx); 00404 ASSERT_OUTSIDE_BEGIN_END(ctx); 00405 00406 if (id) 00407 q = lookup_query_object(ctx, id); 00408 00409 if (!q || q->Active) { 00410 _mesa_error(ctx, GL_INVALID_OPERATION, 00411 "glGetQueryObjectuivARB(id=%d is invalid or active)", id); 00412 return; 00413 } 00414 00415 switch (pname) { 00416 case GL_QUERY_RESULT_ARB: 00417 if (!q->Ready) 00418 ctx->Driver.WaitQuery(ctx, q); 00419 /* if result is too large for returned type, clamp to max value */ 00420 if (q->Result > 0xffffffff) { 00421 *params = 0xffffffff; 00422 } 00423 else { 00424 *params = (GLuint)q->Result; 00425 } 00426 break; 00427 case GL_QUERY_RESULT_AVAILABLE_ARB: 00428 if (!q->Ready) 00429 ctx->Driver.CheckQuery( ctx, q ); 00430 *params = q->Ready; 00431 break; 00432 default: 00433 _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryObjectuivARB(pname)"); 00434 return; 00435 } 00436 } 00437 00438 00439 #if FEATURE_EXT_timer_query 00440 00444 void GLAPIENTRY 00445 _mesa_GetQueryObjecti64vEXT(GLuint id, GLenum pname, GLint64EXT *params) 00446 { 00447 struct gl_query_object *q = NULL; 00448 GET_CURRENT_CONTEXT(ctx); 00449 ASSERT_OUTSIDE_BEGIN_END(ctx); 00450 00451 if (id) 00452 q = lookup_query_object(ctx, id); 00453 00454 if (!q || q->Active) { 00455 _mesa_error(ctx, GL_INVALID_OPERATION, 00456 "glGetQueryObjectui64vARB(id=%d is invalid or active)", id); 00457 return; 00458 } 00459 00460 switch (pname) { 00461 case GL_QUERY_RESULT_ARB: 00462 if (!q->Ready) 00463 ctx->Driver.WaitQuery(ctx, q); 00464 *params = q->Result; 00465 break; 00466 case GL_QUERY_RESULT_AVAILABLE_ARB: 00467 if (!q->Ready) 00468 ctx->Driver.CheckQuery( ctx, q ); 00469 *params = q->Ready; 00470 break; 00471 default: 00472 _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryObjecti64vARB(pname)"); 00473 return; 00474 } 00475 } 00476 00477 00481 void GLAPIENTRY 00482 _mesa_GetQueryObjectui64vEXT(GLuint id, GLenum pname, GLuint64EXT *params) 00483 { 00484 struct gl_query_object *q = NULL; 00485 GET_CURRENT_CONTEXT(ctx); 00486 ASSERT_OUTSIDE_BEGIN_END(ctx); 00487 00488 if (id) 00489 q = lookup_query_object(ctx, id); 00490 00491 if (!q || q->Active) { 00492 _mesa_error(ctx, GL_INVALID_OPERATION, 00493 "glGetQueryObjectuui64vARB(id=%d is invalid or active)", id); 00494 return; 00495 } 00496 00497 switch (pname) { 00498 case GL_QUERY_RESULT_ARB: 00499 if (!q->Ready) 00500 ctx->Driver.WaitQuery(ctx, q); 00501 *params = q->Result; 00502 break; 00503 case GL_QUERY_RESULT_AVAILABLE_ARB: 00504 if (!q->Ready) 00505 ctx->Driver.CheckQuery( ctx, q ); 00506 *params = q->Ready; 00507 break; 00508 default: 00509 _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryObjectui64vARB(pname)"); 00510 return; 00511 } 00512 } 00513 00514 #endif /* FEATURE_EXT_timer_query */ 00515 00516 00520 void 00521 _mesa_init_query(GLcontext *ctx) 00522 { 00523 #if FEATURE_ARB_occlusion_query 00524 ctx->Query.QueryObjects = _mesa_NewHashTable(); 00525 ctx->Query.CurrentOcclusionObject = NULL; 00526 #endif 00527 } 00528 00529 00533 static void 00534 delete_queryobj_cb(GLuint id, void *data, void *userData) 00535 { 00536 struct gl_query_object *q= (struct gl_query_object *) data; 00537 GLcontext *ctx = (GLcontext *)userData; 00538 ctx->Driver.DeleteQuery(ctx, q); 00539 } 00540 00541 00545 void 00546 _mesa_free_query_data(GLcontext *ctx) 00547 { 00548 _mesa_HashDeleteAll(ctx->Query.QueryObjects, delete_queryobj_cb, ctx); 00549 _mesa_DeleteHashTable(ctx->Query.QueryObjects); 00550 } Generated on Sun May 27 2012 04:20:25 for ReactOS by
1.7.6.1
|