[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