r300-gallium: More query stuff.
authorCorbin Simpson <MostAwesomeDude@gmail.com>
Tue, 17 Mar 2009 18:42:13 +0000 (11:42 -0700)
committerCorbin Simpson <MostAwesomeDude@gmail.com>
Tue, 17 Mar 2009 18:51:14 +0000 (11:51 -0700)
Should work, but doesn't. At least it doesn't hardlock.

src/gallium/drivers/r300/r300_query.c
src/gallium/drivers/r300/r300_query.h

index e09af2cfcee874678cf7642eaf2a2eb48154b195..5f5f4c4dbd40cee10b74dc50049431e033f312c4 100644 (file)
@@ -30,38 +30,75 @@ static struct pipe_query* r300_create_query(struct pipe_context* pipe,
     q->type = query_type;
     assert(q->type == PIPE_QUERY_OCCLUSION_COUNTER);
 
+    /* XXX this is to force winsys to give us a GTT buffer */
+    q->buf = pipe->screen->buffer_create(pipe->screen, 64,
+            PIPE_BUFFER_USAGE_VERTEX, 64);
+
     return (struct pipe_query*)q;
 }
 
 static void r300_destroy_query(struct pipe_context* pipe,
-                               struct pipe_query* q)
+                               struct pipe_query* query)
 {
-    FREE(q);
+    FREE(query);
 }
 
 static void r300_begin_query(struct pipe_context* pipe,
-                             struct pipe_query* q)
+                             struct pipe_query* query)
 {
     struct r300_context* r300 = r300_context(pipe);
+    struct r300_query* q = (struct r300_query*)query;
     CS_LOCALS(r300);
 
+    uint32_t* map = pipe_buffer_map(pipe->screen, q->buf,
+            PIPE_BUFFER_USAGE_CPU_WRITE);
+    *map = ~0;
+    pipe_buffer_unmap(pipe->screen, q->buf);
+
     BEGIN_CS(2);
     OUT_CS_REG(R300_ZB_ZPASS_DATA, 0);
     END_CS;
 }
 
 static void r300_end_query(struct pipe_context* pipe,
-                           struct pipe_query* q)
+                           struct pipe_query* query)
 {
     struct r300_context* r300 = r300_context(pipe);
+    struct r300_query* q = (struct r300_query*)query;
+    CS_LOCALS(r300);
+
+    BEGIN_CS(4);
+    OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
+    OUT_CS_RELOC(q->buf, 0, 0, RADEON_GEM_DOMAIN_GTT, 0);
+    END_CS;
 }
 
 static boolean r300_get_query_result(struct pipe_context* pipe,
-                                     struct pipe_query* q,
+                                     struct pipe_query* query,
                                      boolean wait,
                                      uint64_t* result)
 {
-    *result = 0;
+    struct r300_query* q = (struct r300_query*)query;
+    uint32_t temp;
+
+    if (wait) {
+        /* Well, we're expected to just sit here and spin, so let's go ahead
+         * and flush so we can be sure that the card's spinning... */
+        /* XXX double-check these params */
+        pipe->flush(pipe, 0, NULL);
+    }
+
+    uint32_t* map = pipe_buffer_map(pipe->screen, q->buf,
+            PIPE_BUFFER_USAGE_CPU_READ);
+    temp = *map;
+    pipe_buffer_unmap(pipe->screen, q->buf);
+
+    if (temp < 0) {
+        /* Our results haven't been written yet... */
+        return FALSE;
+    }
+
+    *result = temp;
     return TRUE;
 }
 
index 00978702874379ad2da4c812d80a037a610542e6..4f447ea45b85f6c8c31d98cd03ea3d63b947ad40 100644 (file)
 #include "r300_reg.h"
 
 struct r300_query {
+    /* The kind of query. Currently only OQ is supported. */
     unsigned type;
+    /* Buffer object where we want our results to reside. */
+    struct pipe_buffer* buf;
 };
 
 static INLINE struct r300_query* r300_query(struct pipe_query* q)