gallium/draw: initial code to properly support llvm in the draw module
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_queryobj.c
index 7eef4faaf610c1b7bcd91b788995c48ab14b0a37..04ce12493e6f1108ad5e791eadf615e4d4748334 100644 (file)
  */
 #include "radeon_common.h"
 #include "radeon_queryobj.h"
+#include "radeon_debug.h"
 
 #include "main/imports.h"
 #include "main/simple_list.h"
 
-#define DDEBUG 0
-
-static int radeonQueryIsFlushed(GLcontext *ctx, struct gl_query_object *q)
-{
-       radeonContextPtr radeon = RADEON_CONTEXT(ctx);
-       struct radeon_query_object *tmp, *query = (struct radeon_query_object *)q;
-
-       foreach(tmp, &radeon->query.not_flushed_head) {
-               if (tmp == query) {
-                       return 0;
-               }
-       }
-
-       return 1;
-}
-
 static void radeonQueryGetResult(GLcontext *ctx, struct gl_query_object *q)
 {
+       radeonContextPtr radeon = RADEON_CONTEXT(ctx);
        struct radeon_query_object *query = (struct radeon_query_object *)q;
-       uint32_t *result;
+        uint32_t *result;
        int i;
 
-       if (DDEBUG) fprintf(stderr, "%s: query id %d, result %d\n", __FUNCTION__, query->Base.Id, (int) query->Base.Result);
+       radeon_print(RADEON_STATE, RADEON_VERBOSE,
+                       "%s: query id %d, result %d\n",
+                       __FUNCTION__, query->Base.Id, (int) query->Base.Result);
 
        radeon_bo_map(query->bo, GL_FALSE);
-
-       result = query->bo->ptr;
+        result = query->bo->ptr;
 
        query->Base.Result = 0;
-       for (i = 0; i < query->curr_offset/sizeof(uint32_t); ++i) {
-               query->Base.Result += result[i];
-               if (DDEBUG) fprintf(stderr, "result[%d] = %d\n", i, result[i]);
+       if (IS_R600_CLASS(radeon->radeonScreen)) {
+               /* ZPASS EVENT writes alternating qwords
+                * At query start we set the start offset to 0 and
+                * hw writes zpass start counts to qwords 0, 2, 4, 6.
+                * At query end we set the start offset to 8 and
+                * hw writes zpass end counts to qwords 1, 3, 5, 7.
+                * then we substract. MSB is the valid bit.
+                */
+               for (i = 0; i < 16; i += 4) {
+                       uint64_t start = (uint64_t)LE32_TO_CPU(result[i]) |
+                                        (uint64_t)LE32_TO_CPU(result[i + 1]) << 32;
+                       uint64_t end = (uint64_t)LE32_TO_CPU(result[i + 2]) |
+                                      (uint64_t)LE32_TO_CPU(result[i + 3]) << 32;
+                       if ((start & 0x8000000000000000) && (end & 0x8000000000000000)) {
+                               uint64_t query_count = end - start;
+                               query->Base.Result += query_count;
+
+                       }
+                       radeon_print(RADEON_STATE, RADEON_TRACE,
+                                    "%d start: %llx, end: %llx %lld\n", i, start, end, end - start);
+               }
+       } else {
+               for (i = 0; i < query->curr_offset/sizeof(uint32_t); ++i) {
+                       query->Base.Result += LE32_TO_CPU(result[i]);
+                       radeon_print(RADEON_STATE, RADEON_TRACE, "result[%d] = %d\n", i, LE32_TO_CPU(result[i]));
+               }
        }
 
        radeon_bo_unmap(query->bo);
@@ -71,14 +81,14 @@ static struct gl_query_object * radeonNewQueryObject(GLcontext *ctx, GLuint id)
 {
        struct radeon_query_object *query;
 
-       query = _mesa_calloc(sizeof(struct radeon_query_object));
+       query = calloc(1, sizeof(struct radeon_query_object));
 
        query->Base.Id = id;
        query->Base.Result = 0;
        query->Base.Active = GL_FALSE;
        query->Base.Ready = GL_TRUE;
 
-       if (DDEBUG) fprintf(stderr, "%s: query id %d\n", __FUNCTION__, query->Base.Id);
+       radeon_print(RADEON_STATE, RADEON_VERBOSE,"%s: query id %d\n", __FUNCTION__, query->Base.Id);
 
        return &query->Base;
 }
@@ -87,24 +97,25 @@ static void radeonDeleteQuery(GLcontext *ctx, struct gl_query_object *q)
 {
        struct radeon_query_object *query = (struct radeon_query_object *)q;
 
-       if (DDEBUG) fprintf(stderr, "%s: query id %d\n", __FUNCTION__, q->Id);
+       radeon_print(RADEON_STATE, RADEON_NORMAL, "%s: query id %d\n", __FUNCTION__, q->Id);
 
        if (query->bo) {
                radeon_bo_unref(query->bo);
        }
 
-       _mesa_free(query);
+       free(query);
 }
 
 static void radeonWaitQuery(GLcontext *ctx, struct gl_query_object *q)
 {
+       radeonContextPtr radeon = RADEON_CONTEXT(ctx);
        struct radeon_query_object *query = (struct radeon_query_object *)q;
 
        /* If the cmdbuf with packets for this query hasn't been flushed yet, do it now */
-       if (!radeonQueryIsFlushed(ctx, q))
+       if (radeon_bo_is_referenced_by_cs(query->bo, radeon->cmdbuf.cs))
                ctx->Driver.Flush(ctx);
 
-       if (DDEBUG) fprintf(stderr, "%s: query id %d, bo %p, offset %d\n", __FUNCTION__, q->Id, query->bo, query->curr_offset);
+       radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s: query id %d, bo %p, offset %d\n", __FUNCTION__, q->Id, query->bo, query->curr_offset);
 
        radeonQueryGetResult(ctx, q);
 
@@ -117,7 +128,7 @@ static void radeonBeginQuery(GLcontext *ctx, struct gl_query_object *q)
        radeonContextPtr radeon = RADEON_CONTEXT(ctx);
        struct radeon_query_object *query = (struct radeon_query_object *)q;
 
-       if (DDEBUG) fprintf(stderr, "%s: query id %d\n", __FUNCTION__, q->Id);
+       radeon_print(RADEON_STATE, RADEON_NORMAL, "%s: query id %d\n", __FUNCTION__, q->Id);
 
        assert(radeon->query.current == NULL);
 
@@ -132,8 +143,7 @@ static void radeonBeginQuery(GLcontext *ctx, struct gl_query_object *q)
        radeon->query.current = query;
 
        radeon->query.queryobj.dirty = GL_TRUE;
-       insert_at_tail(&radeon->query.not_flushed_head, query);
-
+       radeon->hw.is_dirty = GL_TRUE;
 }
 
 void radeonEmitQueryEnd(GLcontext *ctx)
@@ -147,7 +157,7 @@ void radeonEmitQueryEnd(GLcontext *ctx)
        if (query->emitted_begin == GL_FALSE)
                return;
 
-       if (DDEBUG) fprintf(stderr, "%s: query id %d, bo %p, offset %d\n", __FUNCTION__, query->Base.Id, query->bo, query->curr_offset);
+       radeon_print(RADEON_STATE, RADEON_NORMAL, "%s: query id %d, bo %p, offset %d\n", __FUNCTION__, query->Base.Id, query->bo, query->curr_offset);
 
        radeon_cs_space_check_with_bo(radeon->cmdbuf.cs,
                                      query->bo,
@@ -160,7 +170,7 @@ static void radeonEndQuery(GLcontext *ctx, struct gl_query_object *q)
 {
        radeonContextPtr radeon = RADEON_CONTEXT(ctx);
 
-       if (DDEBUG) fprintf(stderr, "%s: query id %d\n", __FUNCTION__, q->Id);
+       radeon_print(RADEON_STATE, RADEON_NORMAL, "%s: query id %d\n", __FUNCTION__, q->Id);
 
        if (radeon->dma.flush)
                radeon->dma.flush(radeon->glCtx);
@@ -171,7 +181,7 @@ static void radeonEndQuery(GLcontext *ctx, struct gl_query_object *q)
 
 static void radeonCheckQuery(GLcontext *ctx, struct gl_query_object *q)
 {
-       if (DDEBUG) fprintf(stderr, "%s: query id %d\n", __FUNCTION__, q->Id);
+       radeon_print(RADEON_STATE, RADEON_TRACE, "%s: query id %d\n", __FUNCTION__, q->Id);
 
 #ifdef DRM_RADEON_GEM_BUSY
        radeonContextPtr radeon = RADEON_CONTEXT(ctx);
@@ -181,7 +191,7 @@ static void radeonCheckQuery(GLcontext *ctx, struct gl_query_object *q)
                uint32_t domain;
 
                /* Need to perform a flush, as per ARB_occlusion_query spec */
-               if (!radeonQueryIsFlushed(ctx, q)) {
+               if (radeon_bo_is_referenced_by_cs(query->bo, radeon->cmdbuf.cs)) {
                        ctx->Driver.Flush(ctx);
                }