[Mesa-dev] [PATCH 4/7] mesa: implement glGet(GL_TIMESTAMP)

Brian Paul brianp at vmware.com
Wed Jun 27 07:39:33 PDT 2012


On 06/26/2012 07:49 PM, Marek Olšák wrote:
> ---
>   src/mesa/main/get.c      |   10 ++++++++
>   src/mesa/main/mtypes.h   |    1 +
>   src/mesa/main/queryobj.c |   61 ++++++++++++++++++++++++++++++++++++++++++++++
>   src/mesa/main/queryobj.h |    5 ++++
>   4 files changed, 77 insertions(+)
>
> diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c
> index 6773252..a53d2ee 100644
> --- a/src/mesa/main/get.c
> +++ b/src/mesa/main/get.c
> @@ -34,6 +34,7 @@
>   #include "state.h"
>   #include "texcompress.h"
>   #include "framebuffer.h"
> +#include "queryobj.h"
>
>   /* This is a table driven implemetation of the glGet*v() functions.
>    * The basic idea is that most getters just look up an int somewhere
> @@ -342,6 +343,7 @@ EXTRA_EXT(ARB_texture_buffer_object);
>   EXTRA_EXT(OES_EGL_image_external);
>   EXTRA_EXT(ARB_blend_func_extended);
>   EXTRA_EXT(ARB_uniform_buffer_object);
> +EXTRA_EXT(ARB_timer_query);
>
>   static const int
>   extra_ARB_vertex_program_ARB_fragment_program_NV_vertex_program[] = {
> @@ -1353,6 +1355,9 @@ static const struct value_desc values[] = {
>
>      { GL_UNIFORM_BUFFER_BINDING, LOC_CUSTOM, TYPE_INT, 0, extra_ARB_uniform_buffer_object },
>
> +   /* GL_ARB_timer_query */
> +   { GL_TIMESTAMP, LOC_CUSTOM, TYPE_INT64, 0, extra_ARB_timer_query }
> +
>   #endif /* FEATURE_GL */
>   };
>
> @@ -1807,6 +1812,11 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu
>      case GL_UNIFORM_BUFFER_BINDING:
>         v->value_int = ctx->UniformBuffer->Name;
>         break;
> +   /* GL_ARB_timer_query */
> +   case GL_TIMESTAMP:
> +      v->value_int64 =
> +         _mesa_get_cpu_timestamp() - ctx->Query.CpuGpuTimestampDiff;
> +      break;
>      }
>   }
>
> diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
> index f18b81e..c5ec89e 100644
> --- a/src/mesa/main/mtypes.h
> +++ b/src/mesa/main/mtypes.h
> @@ -2464,6 +2464,7 @@ struct gl_query_state
>      struct gl_query_object *TimeElapsed;
>
>      GLenum CondRenderMode;
> +   GLuint64 CpuGpuTimestampDiff;

What are the time units?  (comment needed)


>   };
>
>
> diff --git a/src/mesa/main/queryobj.c b/src/mesa/main/queryobj.c
> index cb50784..c3c23c5 100644
> --- a/src/mesa/main/queryobj.c
> +++ b/src/mesa/main/queryobj.c
> @@ -32,6 +32,9 @@
>   #include "mfeatures.h"
>   #include "mtypes.h"
>   #include "main/dispatch.h"
> +#ifndef _WIN32
> +#include<sys/time.h>
> +#endif
>
>
>   #if FEATURE_queryobj
> @@ -688,3 +691,61 @@ _mesa_free_queryobj_data(struct gl_context *ctx)
>      _mesa_HashDeleteAll(ctx->Query.QueryObjects, delete_queryobj_cb, ctx);
>      _mesa_DeleteHashTable(ctx->Query.QueryObjects);
>   }
> +
> +


And a comment for this function indicating the units of the returned 
time value.

> +GLuint64
> +_mesa_get_cpu_timestamp(void)
> +{
> +#ifndef _WIN32
> +   struct timeval tv;
> +
> +   gettimeofday(&tv, 0);
> +   return (GLuint64)tv.tv_sec * 1000000000ull + (GLuint64)tv.tv_usec * 1000;
> +#else
> +   return 0; /* XXX */
> +#endif
> +}
> +
> +
> +/**
> + * Compute the difference that needs to be subtracted from CPU time
> + * (as returned by _mesa_get_cpu_timestamp) to get the internal GPU time
> + * without having to ask the GPU (which might not be possible without having
> + * to wait until the GPU is idle, for example). */

Minor nit: put the closing */ on the next line.


> +void
> +_mesa_init_cpu_gpu_timestamp_diff(struct gl_context *ctx)
> +{
> +   struct gl_query_object *q;
> +   GLuint64 time1, time2;
> +
> +   if (!ctx->Extensions.ARB_timer_query) {
> +      return;
> +   }
> +
> +   q = ctx->Driver.NewQueryObject(ctx, 1);
> +   if (!q) {
> +      return;
> +   }
> +   q->Target = GL_TIMESTAMP;
> +

I know there's a comment in queryobj.c, but you might mention that 
ctx->Driver.BeginQuery() isn't needed here.  At first glance, it seems 
like that's missing/wrong.


> +   /* Get two timestamps. */
> +   q->Ready = GL_FALSE;
> +   ctx->Driver.EndQuery(ctx, q);
> +   ctx->Driver.WaitQuery(ctx, q);
> +   time1 = q->Result;
> +
> +   q->Ready = GL_FALSE;
> +   ctx->Driver.EndQuery(ctx, q);
> +   ctx->Driver.WaitQuery(ctx, q);
> +   time2 = q->Result;
> +
> +   /* Guess the difference.
> +    *
> +    * current GPU time = time2 + overhead of querying/2
> +    * (assuming half of the overhead is issuing the query and the other
> +    *  half is reading the result) */

*/ on next line again.


> +   ctx->Query.CpuGpuTimestampDiff =
> +      _mesa_get_cpu_timestamp() - (time2 + (time2 - time1)/2);
> +
> +   ctx->Driver.DeleteQuery(ctx, q);
> +}
> diff --git a/src/mesa/main/queryobj.h b/src/mesa/main/queryobj.h
> index e7a133b..9fa0cd7 100644
> --- a/src/mesa/main/queryobj.h
> +++ b/src/mesa/main/queryobj.h
> @@ -74,5 +74,10 @@ _mesa_init_queryobj(struct gl_context *ctx);
>   extern void
>   _mesa_free_queryobj_data(struct gl_context *ctx);
>
> +extern GLuint64
> +_mesa_get_cpu_timestamp(void);
> +
> +extern void
> +_mesa_init_cpu_gpu_timestamp_diff(struct gl_context *ctx);
>
>   #endif /* QUERYOBJ_H */



More information about the mesa-dev mailing list