[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