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

Marek Olšák maraeo at gmail.com
Tue Jun 26 18:49:59 PDT 2012


---
 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;
 };
 
 
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);
 }
+
+
+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). */
+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;
+
+   /* 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) */
+   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 */
-- 
1.7.9.5



More information about the mesa-dev mailing list