i965: Add support for EXT_timer_query on Ironlake.
authorEric Anholt <eric@anholt.net>
Tue, 25 May 2010 22:32:54 +0000 (15:32 -0700)
committerEric Anholt <eric@anholt.net>
Wed, 26 May 2010 19:14:44 +0000 (12:14 -0700)
We could potentially do this on G45 as well, though the units are
different.  On 965, the timestamp is tied to hclk, which would make
supporting it harder.

docs/relnotes-7.9.html
src/mesa/drivers/dri/i965/brw_queryobj.c
src/mesa/drivers/dri/intel/intel_extensions.c

index f7d5016..6122f8c 100644 (file)
@@ -34,6 +34,7 @@ tbd
 
 <h2>New features</h2>
 <ul>
+<li>GL_EXT_timer_query extension (i965 driver only)
 </ul>
 
 
index 3f47a68..7cb812b 100644 (file)
@@ -55,11 +55,15 @@ brw_queryobj_get_results(struct brw_query_object *query)
    if (query->bo == NULL)
       return;
 
-   /* Map and count the pixels from the current query BO */
    dri_bo_map(query->bo, GL_FALSE);
    results = query->bo->virtual;
-   for (i = query->first_index; i <= query->last_index; i++) {
-      query->Base.Result += results[i * 2 + 1] - results[i * 2];
+   if (query->Base.Target == GL_TIME_ELAPSED_EXT) {
+      query->Base.Result += 1000 * ((results[1] >> 32) - (results[0] >> 32));
+   } else {
+      /* Map and count the pixels from the current query BO */
+      for (i = query->first_index; i <= query->last_index; i++) {
+        query->Base.Result += results[i * 2 + 1] - results[i * 2];
+      }
    }
    dri_bo_unmap(query->bo);
 
@@ -98,14 +102,31 @@ brw_begin_query(GLcontext *ctx, struct gl_query_object *q)
    struct intel_context *intel = intel_context(ctx);
    struct brw_query_object *query = (struct brw_query_object *)q;
 
-   /* Reset our driver's tracking of query state. */
-   dri_bo_unreference(query->bo);
-   query->bo = NULL;
-   query->first_index = -1;
-   query->last_index = -1;
-
-   brw->query.obj = query;
-   intel->stats_wm++;
+   if (query->Base.Target == GL_TIME_ELAPSED_EXT) {
+      dri_bo_unreference(query->bo);
+      query->bo = drm_intel_bo_alloc(intel->bufmgr, "timer query",
+                                    4096, 4096);
+
+      BEGIN_BATCH(4);
+      OUT_BATCH(_3DSTATE_PIPE_CONTROL |
+               PIPE_CONTROL_WRITE_TIMESTAMP);
+      OUT_RELOC(query->bo,
+               I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
+               PIPE_CONTROL_GLOBAL_GTT_WRITE |
+               0);
+      OUT_BATCH(0);
+      OUT_BATCH(0);
+      ADVANCE_BATCH();
+   } else {
+      /* Reset our driver's tracking of query state. */
+      dri_bo_unreference(query->bo);
+      query->bo = NULL;
+      query->first_index = -1;
+      query->last_index = -1;
+
+      brw->query.obj = query;
+      intel->stats_wm++;
+   }
 }
 
 /**
@@ -118,21 +139,36 @@ brw_end_query(GLcontext *ctx, struct gl_query_object *q)
    struct intel_context *intel = intel_context(ctx);
    struct brw_query_object *query = (struct brw_query_object *)q;
 
-   /* Flush the batchbuffer in case it has writes to our query BO.
-    * Have later queries write to a new query BO so that further rendering
-    * doesn't delay the collection of our results.
-    */
-   if (query->bo) {
-      brw_emit_query_end(brw);
-      intel_batchbuffer_flush(intel->batch);
+   if (query->Base.Target == GL_TIME_ELAPSED_EXT) {
+      BEGIN_BATCH(4);
+      OUT_BATCH(_3DSTATE_PIPE_CONTROL |
+               PIPE_CONTROL_WRITE_TIMESTAMP);
+      OUT_RELOC(query->bo,
+               I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
+               PIPE_CONTROL_GLOBAL_GTT_WRITE |
+               8);
+      OUT_BATCH(0);
+      OUT_BATCH(0);
+      ADVANCE_BATCH();
 
-      dri_bo_unreference(brw->query.bo);
-      brw->query.bo = NULL;
+      intel_batchbuffer_flush(intel->batch);
+   } else {
+      /* Flush the batchbuffer in case it has writes to our query BO.
+       * Have later queries write to a new query BO so that further rendering
+       * doesn't delay the collection of our results.
+       */
+      if (query->bo) {
+        brw_emit_query_end(brw);
+        intel_batchbuffer_flush(intel->batch);
+
+        dri_bo_unreference(brw->query.bo);
+        brw->query.bo = NULL;
+      }
+
+      brw->query.obj = NULL;
+
+      intel->stats_wm--;
    }
-
-   brw->query.obj = NULL;
-
-   intel->stats_wm--;
 }
 
 static void brw_wait_query(GLcontext *ctx, struct gl_query_object *q)
index 9c20838..edba1fc 100644 (file)
@@ -57,6 +57,7 @@
 #define need_GL_EXT_provoking_vertex
 #define need_GL_EXT_secondary_color
 #define need_GL_EXT_stencil_two_side
+#define need_GL_EXT_timer_query
 #define need_GL_APPLE_vertex_array_object
 #define need_GL_APPLE_object_purgeable
 #define need_GL_ATI_separate_stencil
@@ -182,6 +183,9 @@ static const struct dri_extension brw_extensions[] = {
    { NULL,                                NULL }
 };
 
+static const struct dri_extension ironlake_extensions[] = {
+   { "GL_EXT_timer_query",                GL_EXT_timer_query_functions },
+};
 
 static const struct dri_extension arb_oq_extensions[] = {
    { "GL_ARB_occlusion_query",            GL_ARB_occlusion_query_functions },
@@ -207,6 +211,9 @@ intelInitExtensions(GLcontext *ctx)
     */
    driInitExtensions(ctx, card_extensions, GL_FALSE);
 
+   if (intel->gen >= 5)
+      driInitExtensions(ctx, ironlake_extensions, GL_FALSE);
+
    if (intel->gen >= 4)
       driInitExtensions(ctx, brw_extensions, GL_FALSE);