llvmpipe: Always swizzle/unswizzle whole tiles.
[mesa.git] / src / gallium / drivers / i965 / brw_pipe_query.c
index a2da1373bfd3c14be41875fdbc7dd70035016c8d..0745254c3cc66cdd2e10f2bff5594b65b5555484 100644 (file)
 #include "brw_reg.h"
 
 /** Waits on the query object's BO and totals the results for this query */
-static void
-brw_queryobj_get_results(struct brw_query_object *query)
+static boolean
+brw_query_get_result(struct pipe_context *pipe,
+                    struct pipe_query *q,
+                    boolean wait,
+                    void *vresult)
 {
-   int i;
-   uint64_t *results;
-
-   if (query->bo == NULL)
-      return;
+   struct brw_context *brw = brw_context(pipe);
+   struct brw_query_object *query = (struct brw_query_object *)q;
+   uint64_t *result = (uint64_t*)vresult;
 
    /* 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->bo) {
+      int i;
+      uint64_t *map;
+      
+      if (brw->sws->bo_is_busy(query->bo) && !wait)
+        return FALSE;
+      
+      map = bo_map_read(brw->sws, query->bo);
+      if (map == NULL)
+        return FALSE;
+      
+      for (i = query->first_index; i <= query->last_index; i++) {
+        query->result += map[i * 2 + 1] - map[i * 2];
+      }
+
+      brw->sws->bo_unmap(query->bo);
+      bo_reference(&query->bo, NULL);
    }
-   dri_bo_unmap(query->bo);
 
-   brw->sws->bo_unreference(query->bo);
-   query->bo = NULL;
+   *result = query->result;
+   return TRUE;
 }
 
 static struct pipe_query *
@@ -72,12 +85,12 @@ brw_query_create(struct pipe_context *pipe, unsigned type )
 {
    struct brw_query_object *query;
 
-   switch (query->type) {
+   switch (type) {
    case PIPE_QUERY_OCCLUSION_COUNTER:
       query = CALLOC_STRUCT( brw_query_object );
       if (query == NULL)
         return NULL;
-      return &query->Base;
+      return (struct pipe_query *)query;
       
    default:
       return NULL;
@@ -89,29 +102,29 @@ brw_query_destroy(struct pipe_context *pipe, struct pipe_query *q)
 {
    struct brw_query_object *query = (struct brw_query_object *)q;
 
-   brw->sws->bo_unreference(query->bo);
+   bo_reference(&query->bo, NULL);
    FREE(query);
 }
 
 static void
-brw_begin_query(struct pipe_context *pipe, struct pipe_query *q)
+brw_query_begin(struct pipe_context *pipe, struct pipe_query *q)
 {
    struct brw_context *brw = brw_context(pipe);
    struct brw_query_object *query = (struct brw_query_object *)q;
 
    /* Reset our driver's tracking of query state. */
-   brw->sws->bo_unreference(query->bo);
-   query->bo = NULL;
+   bo_reference(&query->bo, NULL);
+   query->result = 0;
    query->first_index = -1;
    query->last_index = -1;
 
    insert_at_head(&brw->query.active_head, query);
-   brw->stats_wm++;
-   brw->dirty.mesa |= PIPE_NEW_QUERY;
+   brw->query.stats_wm++;
+   brw->state.dirty.mesa |= PIPE_NEW_QUERY;
 }
 
 static void
-brw_end_query(struct pipe_context *pipe, struct pipe_query *q)
+brw_query_end(struct pipe_context *pipe, struct pipe_query *q)
 {
    struct brw_context *brw = brw_context(pipe);
    struct brw_query_object *query = (struct brw_query_object *)q;
@@ -122,54 +135,45 @@ brw_end_query(struct pipe_context *pipe, struct pipe_query *q)
     */
    if (query->bo) {
       brw_emit_query_end(brw);
-      brw_batchbuffer_flush(brw->batch);
+      brw_context_flush( brw );
 
-      brw->sws->bo_unreference(brw->query.bo);
-      brw->query.bo = NULL;
+      bo_reference(&brw->query.bo, NULL);
    }
 
    remove_from_list(query);
-   brw->stats_wm--;
-   brw->dirty.mesa |= PIPE_NEW_QUERY;
-}
-
-static void brw_wait_query(struct pipe_context *pipe, struct pipe_query *q)
-{
-   struct brw_query_object *query = (struct brw_query_object *)q;
-
-   brw_queryobj_get_results(query);
-   query->Base.Ready = GL_TRUE;
+   brw->query.stats_wm--;
+   brw->state.dirty.mesa |= PIPE_NEW_QUERY;
 }
 
-static void brw_check_query(struct pipe_context *pipe, struct pipe_query *q)
-{
-   struct brw_query_object *query = (struct brw_query_object *)q;
-
-   if (query->bo == NULL || !drm_intel_bo_busy(query->bo)) {
-      brw_queryobj_get_results(query);
-      query->Base.Ready = GL_TRUE;
-   }
-}
+/***********************************************************************
+ * Internal functions and callbacks to implement queries 
+ */
 
 /** Called to set up the query BO and account for its aperture space */
-void
+enum pipe_error
 brw_prepare_query_begin(struct brw_context *brw)
 {
+   enum pipe_error ret;
+
    /* Skip if we're not doing any queries. */
    if (is_empty_list(&brw->query.active_head))
-      return;
+      return PIPE_OK;
 
    /* Get a new query BO if we're going to need it. */
    if (brw->query.bo == NULL ||
        brw->query.index * 2 + 1 >= 4096 / sizeof(uint64_t)) {
-      brw->sws->bo_unreference(brw->query.bo);
-      brw->query.bo = NULL;
 
-      brw->query.bo = brw->sws->bo_alloc(brw->sws, BRW_BUFFER_TYPE_QUERY, 4096, 1);
+      ret = brw->sws->bo_alloc(brw->sws, BRW_BUFFER_TYPE_QUERY, 4096, 1,
+                               &brw->query.bo);
+      if (ret)
+         return ret;
+
       brw->query.index = 0;
    }
 
    brw_add_validated_bo(brw, brw->query.bo);
+
+   return PIPE_OK;
 }
 
 /** Called just before primitive drawing to get a beginning PS_DEPTH_COUNT. */
@@ -192,7 +196,7 @@ brw_emit_query_begin(struct brw_context *brw)
     * to pick up the results.
     */
    OUT_RELOC(brw->query.bo,
-            I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
+            BRW_USAGE_QUERY_RESULT,
             PIPE_CONTROL_GLOBAL_GTT_WRITE |
             ((brw->query.index * 2) * sizeof(uint64_t)));
    OUT_BATCH(0);
@@ -201,10 +205,18 @@ brw_emit_query_begin(struct brw_context *brw)
 
    foreach(query, &brw->query.active_head) {
       if (query->bo != brw->query.bo) {
+        uint64_t tmp;
+        
+        /* Propogate the results from this buffer to all of the
+         * active queries, as the bo is going away.
+         */
         if (query->bo != NULL)
-           brw_queryobj_get_results(query);
-        brw->sws->bo_reference(brw->query.bo);
-        query->bo = brw->query.bo;
+           brw_query_get_result( &brw->base, 
+                                 (struct pipe_query *)query,
+                                 FALSE,
+                                 &tmp );
+
+        bo_reference( &query->bo, brw->query.bo );
         query->first_index = brw->query.index;
       }
       query->last_index = brw->query.index;
@@ -224,7 +236,7 @@ brw_emit_query_end(struct brw_context *brw)
             PIPE_CONTROL_DEPTH_STALL |
             PIPE_CONTROL_WRITE_DEPTH_COUNT);
    OUT_RELOC(brw->query.bo,
-            I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
+            BRW_USAGE_QUERY_RESULT,
             PIPE_CONTROL_GLOBAL_GTT_WRITE |
             ((brw->query.index * 2 + 1) * sizeof(uint64_t)));
    OUT_BATCH(0);
@@ -235,12 +247,18 @@ brw_emit_query_end(struct brw_context *brw)
    brw->query.index++;
 }
 
-void brw_init_queryobj_functions(struct dd_function_table *functions)
+void brw_pipe_query_init( struct brw_context *brw )
+{
+   brw->base.create_query = brw_query_create;
+   brw->base.destroy_query = brw_query_destroy;
+   brw->base.begin_query = brw_query_begin;
+   brw->base.end_query = brw_query_end;
+   brw->base.get_query_result = brw_query_get_result;
+}
+
+
+void brw_pipe_query_cleanup( struct brw_context *brw )
 {
-   functions->NewQueryObject = brw_new_query_object;
-   functions->DeleteQuery = brw_delete_query;
-   functions->BeginQuery = brw_begin_query;
-   functions->EndQuery = brw_end_query;
-   functions->CheckQuery = brw_check_query;
-   functions->WaitQuery = brw_wait_query;
+   /* Unreference brw->query.bo ??
+    */
 }