Mesa (master): r300g: rewrite occlusion queries

Marek Olšák mareko at kemper.freedesktop.org
Mon Jun 14 10:47:41 UTC 2010


Module: Mesa
Branch: master
Commit: cf3778bae03460325960d2aec0cd4cdf325299eb
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=cf3778bae03460325960d2aec0cd4cdf325299eb

Author: Marek Olšák <maraeo at gmail.com>
Date:   Mon Jun 14 05:18:47 2010 +0200

r300g: rewrite occlusion queries

The previous implementation had issues with queries spanning over several
command streams as well as using a very large number of queries.

This fixes flickering in Enemy Territory: Quake Wars. The driver now renders
everything correctly in this game and the graphics is awesome.

---

 src/gallium/drivers/r300/r300_blit.c          |  130 ++++++++++++++----------
 src/gallium/drivers/r300/r300_context.c       |    8 +--
 src/gallium/drivers/r300/r300_context.h       |   29 ++++--
 src/gallium/drivers/r300/r300_defines.h       |    6 -
 src/gallium/drivers/r300/r300_emit.c          |   41 +++++---
 src/gallium/drivers/r300/r300_query.c         |  109 +++++++++------------
 src/gallium/drivers/r300/r300_screen_buffer.c |    4 -
 7 files changed, 168 insertions(+), 159 deletions(-)

diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c
index 3bb1cae..2a47701 100644
--- a/src/gallium/drivers/r300/r300_blit.c
+++ b/src/gallium/drivers/r300/r300_blit.c
@@ -25,8 +25,23 @@
 
 #include "util/u_format.h"
 
-static void r300_blitter_save_states(struct r300_context* r300)
+enum r300_blitter_op
 {
+    R300_CLEAR,
+    R300_CLEAR_SURFACE,
+    R300_COPY
+};
+
+static void r300_blitter_begin(struct r300_context* r300, enum r300_blitter_op op)
+{
+    if (r300->query_current) {
+        r300->blitter_saved_query = r300->query_current;
+        r300_stop_query(r300);
+    }
+
+    /* Yeah we have to save all those states to ensure the blitter operation
+     * is really transparent. The states will be restored by the blitter once
+     * copying is done. */
     util_blitter_save_blend(r300->blitter, r300->blend_state.state);
     util_blitter_save_depth_stencil_alpha(r300->blitter, r300->dsa_state.state);
     util_blitter_save_stencil_ref(r300->blitter, &(r300->stencil_ref));
@@ -38,6 +53,30 @@ static void r300_blitter_save_states(struct r300_context* r300)
     util_blitter_save_vertex_elements(r300->blitter, r300->velems);
     util_blitter_save_vertex_buffers(r300->blitter, r300->vertex_buffer_count,
                                      r300->vertex_buffer);
+
+    if (op & (R300_CLEAR_SURFACE | R300_COPY))
+        util_blitter_save_framebuffer(r300->blitter, r300->fb_state.state);
+
+    if (op & R300_COPY) {
+        struct r300_textures_state* state =
+            (struct r300_textures_state*)r300->textures_state.state;
+
+        util_blitter_save_fragment_sampler_states(
+            r300->blitter, state->sampler_state_count,
+            (void**)state->sampler_states);
+
+        util_blitter_save_fragment_sampler_views(
+            r300->blitter, state->sampler_view_count,
+            (struct pipe_sampler_view**)state->sampler_views);
+    }
+}
+
+static void r300_blitter_end(struct r300_context *r300)
+{
+    if (r300->blitter_saved_query) {
+        r300_resume_query(r300, r300->blitter_saved_query);
+        r300->blitter_saved_query = NULL;
+    }
 }
 
 /* Clear currently bound buffers. */
@@ -73,13 +112,45 @@ static void r300_clear(struct pipe_context* pipe,
     struct pipe_framebuffer_state* fb =
         (struct pipe_framebuffer_state*)r300->fb_state.state;
 
-    r300_blitter_save_states(r300);
-
+    r300_blitter_begin(r300, R300_CLEAR);
     util_blitter_clear(r300->blitter,
                        fb->width,
                        fb->height,
                        fb->nr_cbufs,
                        buffers, rgba, depth, stencil);
+    r300_blitter_end(r300);
+}
+
+/* Clear a region of a color surface to a constant value. */
+static void r300_clear_render_target(struct pipe_context *pipe,
+                                     struct pipe_surface *dst,
+                                     const float *rgba,
+                                     unsigned dstx, unsigned dsty,
+                                     unsigned width, unsigned height)
+{
+    struct r300_context *r300 = r300_context(pipe);
+
+    r300_blitter_begin(r300, R300_CLEAR_SURFACE);
+    util_blitter_clear_render_target(r300->blitter, dst, rgba,
+                                     dstx, dsty, width, height);
+    r300_blitter_end(r300);
+}
+
+/* Clear a region of a depth stencil surface. */
+static void r300_clear_depth_stencil(struct pipe_context *pipe,
+                                     struct pipe_surface *dst,
+                                     unsigned clear_flags,
+                                     double depth,
+                                     unsigned stencil,
+                                     unsigned dstx, unsigned dsty,
+                                     unsigned width, unsigned height)
+{
+    struct r300_context *r300 = r300_context(pipe);
+
+    r300_blitter_begin(r300, R300_CLEAR_SURFACE);
+    util_blitter_clear_depth_stencil(r300->blitter, dst, clear_flags, depth, stencil,
+                                     dstx, dsty, width, height);
+    r300_blitter_end(r300);
 }
 
 /* Copy a block of pixels from one surface to another using HW. */
@@ -93,27 +164,12 @@ static void r300_hw_copy_region(struct pipe_context* pipe,
                                 unsigned width, unsigned height)
 {
     struct r300_context* r300 = r300_context(pipe);
-    struct r300_textures_state* state =
-        (struct r300_textures_state*)r300->textures_state.state;
-
-    /* Yeah we have to save all those states to ensure this blitter operation
-     * is really transparent. The states will be restored by the blitter once
-     * copying is done. */
-    r300_blitter_save_states(r300);
-    util_blitter_save_framebuffer(r300->blitter, r300->fb_state.state);
-
-    util_blitter_save_fragment_sampler_states(
-        r300->blitter, state->sampler_state_count,
-        (void**)state->sampler_states);
 
-    util_blitter_save_fragment_sampler_views(
-        r300->blitter, state->sampler_view_count,
-        (struct pipe_sampler_view**)state->sampler_views);
-
-    /* Do a copy */
+    r300_blitter_begin(r300, R300_COPY);
     util_blitter_copy_region(r300->blitter, dst, subdst, dstx, dsty, dstz,
                              src, subsrc, srcx, srcy, srcz, width, height,
                              TRUE);
+    r300_blitter_end(r300);
 }
 
 /* Copy a block of pixels from one surface to another. */
@@ -187,40 +243,6 @@ static void r300_resource_copy_region(struct pipe_context *pipe,
     }
 }
 
-/* Clear a region of a color surface to a constant value. */
-static void r300_clear_render_target(struct pipe_context *pipe,
-                                     struct pipe_surface *dst,
-                                     const float *rgba,
-                                     unsigned dstx, unsigned dsty,
-                                     unsigned width, unsigned height)
-{
-    struct r300_context *r300 = r300_context(pipe);
-
-    r300_blitter_save_states(r300);
-    util_blitter_save_framebuffer(r300->blitter, r300->fb_state.state);
-
-    util_blitter_clear_render_target(r300->blitter, dst, rgba,
-                                     dstx, dsty, width, height);
-}
-
-/* Clear a region of a depth stencil surface. */
-static void r300_clear_depth_stencil(struct pipe_context *pipe,
-                                     struct pipe_surface *dst,
-                                     unsigned clear_flags,
-                                     double depth,
-                                     unsigned stencil,
-                                     unsigned dstx, unsigned dsty,
-                                     unsigned width, unsigned height)
-{
-    struct r300_context *r300 = r300_context(pipe);
-
-    r300_blitter_save_states(r300);
-    util_blitter_save_framebuffer(r300->blitter, r300->fb_state.state);
-
-    util_blitter_clear_depth_stencil(r300->blitter, dst, clear_flags, depth, stencil,
-                                     dstx, dsty, width, height);
-}
-
 void r300_init_blit_functions(struct r300_context *r300)
 {
     r300->context.clear = r300_clear;
diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c
index 57cf68f..1139426 100644
--- a/src/gallium/drivers/r300/r300_context.c
+++ b/src/gallium/drivers/r300/r300_context.c
@@ -39,7 +39,7 @@
 static void r300_destroy_context(struct pipe_context* context)
 {
     struct r300_context* r300 = r300_context(context);
-    struct r300_query* query, * temp;
+    struct r300_query *query, *temp;
     struct r300_atom *atom;
 
     util_blitter_destroy(r300->blitter);
@@ -55,9 +55,6 @@ static void r300_destroy_context(struct pipe_context* context)
         }
     }
 
-    /* Free the OQ BO. */
-    context->screen->resource_destroy(context->screen, r300->oqbo);
-
     /* If there are any queries pending or not destroyed, remove them now. */
     foreach_s(query, temp, &r300->query_list) {
         remove_from_list(query);
@@ -221,9 +218,6 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
 
     r300_setup_atoms(r300);
 
-    /* Open up the OQ BO. */
-    r300->oqbo = pipe_buffer_create(screen,
-				    R300_BIND_OQBO, 4096);
     make_empty_list(&r300->query_list);
 
     r300_init_blit_functions(r300);
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index 4869083..90de53e 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -241,14 +241,23 @@ struct r300_constant_buffer {
 struct r300_query {
     /* The kind of query. Currently only OQ is supported. */
     unsigned type;
-    /* The current count of this query. Required to be at least 32 bits. */
-    unsigned int count;
-    /* The offset of this query into the query buffer, in bytes. */
-    unsigned offset;
+    /* The number of pipes where query results are stored. */
+    unsigned num_pipes;
+    /* How many results have been written, in dwords. It's incremented
+     * after end_query and flush. */
+    unsigned num_results;
     /* if we've flushed the query */
     boolean flushed;
     /* if begin has been emitted */
     boolean begin_emitted;
+
+    /* The buffer where query results are stored. */
+    struct r300_winsys_buffer *buffer;
+    /* The size of the buffer. */
+    unsigned buffer_size;
+    /* The domain of the buffer. */
+    enum r300_buffer_domain domain;
+
     /* Linked list members. */
     struct r300_query* prev;
     struct r300_query* next;
@@ -388,10 +397,11 @@ struct r300_context {
     /* Offset into the VBO. */
     size_t vbo_offset;
 
-    /* Occlusion query buffer. */
-    struct pipe_resource* oqbo;
-    /* Query list. */
+    /* The currently active query. */
     struct r300_query *query_current;
+    /* The saved query for blitter operations. */
+    struct r300_query *blitter_saved_query;
+    /* Query list. */
     struct r300_query query_list;
 
     /* Various CSO state objects. */
@@ -522,6 +532,11 @@ void r300_init_render_functions(struct r300_context *r300);
 void r300_init_state_functions(struct r300_context* r300);
 void r300_init_resource_functions(struct r300_context* r300);
 
+/* r300_query.c */
+void r300_resume_query(struct r300_context *r300,
+                       struct r300_query *query);
+void r300_stop_query(struct r300_context *r300);
+
 /* r300_render_translate.c */
 void r300_begin_vertex_translate(struct r300_context *r300);
 void r300_end_vertex_translate(struct r300_context *r300);
diff --git a/src/gallium/drivers/r300/r300_defines.h b/src/gallium/drivers/r300/r300_defines.h
index 565a2f3..d510d80 100644
--- a/src/gallium/drivers/r300/r300_defines.h
+++ b/src/gallium/drivers/r300/r300_defines.h
@@ -32,12 +32,6 @@
 
 #define R300_INVALID_FORMAT 0xffff
 
-/* XXX: this is just a bandaid on larger problems in
- * r300_screen_buffer.h which doesn't seem to be fully ported to
- * gallium-resources.
- */
-#define R300_BIND_OQBO  (1<<21)
-
 /* Tiling flags. */
 enum r300_buffer_tiling {
     R300_BUFFER_LINEAR = 0,
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index 96caf46..46b958b 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -353,13 +353,14 @@ void r300_emit_query_start(struct r300_context *r300, unsigned size, void*state)
     OUT_CS_REG(R300_ZB_ZPASS_DATA, 0);
     END_CS;
     query->begin_emitted = TRUE;
+    query->flushed = FALSE;
 }
 
-
 static void r300_emit_query_end_frag_pipes(struct r300_context *r300,
                                            struct r300_query *query)
 {
     struct r300_capabilities* caps = &r300->screen->caps;
+    struct r300_winsys_buffer *buf = r300->query_current->buffer;
     CS_LOCALS(r300);
 
     assert(caps->num_frag_pipes);
@@ -378,28 +379,28 @@ static void r300_emit_query_end_frag_pipes(struct r300_context *r300,
             /* pipe 3 only */
             OUT_CS_REG(R300_SU_REG_DEST, 1 << 3);
             OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
-            OUT_CS_BUF_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 3),
-                    0, r300_buffer(r300->oqbo)->domain, 0);
+            OUT_CS_RELOC(buf, (query->num_results + 3) * 4,
+                    0, query->domain, 0);
         case 3:
             /* pipe 2 only */
             OUT_CS_REG(R300_SU_REG_DEST, 1 << 2);
             OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
-            OUT_CS_BUF_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 2),
-                    0, r300_buffer(r300->oqbo)->domain, 0);
+            OUT_CS_RELOC(buf, (query->num_results + 2) * 4,
+                    0, query->domain, 0);
         case 2:
             /* pipe 1 only */
             /* As mentioned above, accomodate RV380 and older. */
             OUT_CS_REG(R300_SU_REG_DEST,
                     1 << (caps->high_second_pipe ? 3 : 1));
             OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
-            OUT_CS_BUF_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 1),
-                    0, r300_buffer(r300->oqbo)->domain, 0);
+            OUT_CS_RELOC(buf, (query->num_results + 1) * 4,
+                    0, query->domain, 0);
         case 1:
             /* pipe 0 only */
             OUT_CS_REG(R300_SU_REG_DEST, 1 << 0);
             OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
-            OUT_CS_BUF_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 0),
-                    0, r300_buffer(r300->oqbo)->domain, 0);
+            OUT_CS_RELOC(buf, (query->num_results + 0) * 4,
+                    0, query->domain, 0);
             break;
         default:
             fprintf(stderr, "r300: Implementation error: Chipset reports %d"
@@ -415,12 +416,13 @@ static void r300_emit_query_end_frag_pipes(struct r300_context *r300,
 static void rv530_emit_query_end_single_z(struct r300_context *r300,
                                           struct r300_query *query)
 {
+    struct r300_winsys_buffer *buf = r300->query_current->buffer;
     CS_LOCALS(r300);
 
     BEGIN_CS(8);
     OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_0);
     OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
-    OUT_CS_BUF_RELOC(r300->oqbo, query->offset, 0, r300_buffer(r300->oqbo)->domain, 0);
+    OUT_CS_RELOC(buf, query->num_results * 4, 0, query->domain, 0);
     OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_ALL);
     END_CS;
 }
@@ -428,15 +430,16 @@ static void rv530_emit_query_end_single_z(struct r300_context *r300,
 static void rv530_emit_query_end_double_z(struct r300_context *r300,
                                           struct r300_query *query)
 {
+    struct r300_winsys_buffer *buf = r300->query_current->buffer;
     CS_LOCALS(r300);
 
     BEGIN_CS(14);
     OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_0);
     OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
-    OUT_CS_BUF_RELOC(r300->oqbo, query->offset, 0, r300_buffer(r300->oqbo)->domain, 0);
+    OUT_CS_RELOC(buf, (query->num_results + 0) * 4, 0, query->domain, 0);
     OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_1);
     OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
-    OUT_CS_BUF_RELOC(r300->oqbo, query->offset + sizeof(uint32_t), 0, r300_buffer(r300->oqbo)->domain, 0);
+    OUT_CS_RELOC(buf, (query->num_results + 1) * 4, 0, query->domain, 0);
     OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_ALL);
     END_CS;
 }
@@ -461,6 +464,13 @@ void r300_emit_query_end(struct r300_context* r300)
         r300_emit_query_end_frag_pipes(r300, query);
 
     query->begin_emitted = FALSE;
+    query->num_results += query->num_pipes;
+
+    /* XXX grab all the results and reset the counter. */
+    if (query->num_results >= query->buffer_size / 4 - 4) {
+        query->num_results = (query->buffer_size / 4) / 2;
+        fprintf(stderr, "r300: Rewinding OQBO...\n");
+    }
 }
 
 void r300_emit_rs_state(struct r300_context* r300, unsigned size, void* state)
@@ -895,10 +905,9 @@ validate:
         }
     }
     /* ...occlusion query buffer... */
-    if (r300->query_start.dirty ||
-        (r300->query_current && r300->query_current->begin_emitted)) {
-        if (!r300_add_buffer(r300->rws, r300->oqbo,
-			     0, r300_buffer(r300->oqbo)->domain)) {
+    if (r300->query_current) {
+        if (!r300->rws->add_buffer(r300->rws, r300->query_current->buffer,
+                                   0, r300->query_current->domain)) {
             r300->context.flush(&r300->context, 0, NULL);
             goto validate;
         }
diff --git a/src/gallium/drivers/r300/r300_query.c b/src/gallium/drivers/r300/r300_query.c
index 7c08806..42cb6ad 100644
--- a/src/gallium/drivers/r300/r300_query.c
+++ b/src/gallium/drivers/r300/r300_query.c
@@ -26,6 +26,7 @@
 #include "r300_context.h"
 #include "r300_screen.h"
 #include "r300_emit.h"
+#include "r300_winsys.h"
 
 #include <stdio.h>
 
@@ -34,30 +35,27 @@ static struct pipe_query *r300_create_query(struct pipe_context *pipe,
 {
     struct r300_context *r300 = r300_context(pipe);
     struct r300_screen *r300screen = r300->screen;
-    unsigned query_size;
-    struct r300_query *q, *qptr;
+    struct r300_query *q;
+
+    assert(query_type == PIPE_QUERY_OCCLUSION_COUNTER);
 
     q = CALLOC_STRUCT(r300_query);
+    if (!q)
+        return NULL;
 
     q->type = query_type;
-    assert(q->type == PIPE_QUERY_OCCLUSION_COUNTER);
+    q->domain = R300_DOMAIN_GTT;
+    q->buffer_size = 4096;
 
     if (r300screen->caps.family == CHIP_FAMILY_RV530)
-        query_size = r300screen->caps.num_z_pipes * sizeof(uint32_t);
+        q->num_pipes = r300screen->caps.num_z_pipes;
     else
-        query_size = r300screen->caps.num_frag_pipes * sizeof(uint32_t);
+        q->num_pipes = r300screen->caps.num_frag_pipes;
 
-    if (!is_empty_list(&r300->query_list)) {
-        qptr = last_elem(&r300->query_list);
-        q->offset = qptr->offset + query_size;
-    }
     insert_at_tail(&r300->query_list, q);
 
-    /* XXX */
-    if (q->offset >= 4096) {
-        q->offset = 0;
-        fprintf(stderr, "r300: Rewinding OQBO...\n");
-    }
+    /* Open up the occlusion query buffer. */
+    q->buffer = r300->rws->buffer_create(r300->rws, 4096, 0, q->domain, q->buffer_size);
 
     return (struct pipe_query*)q;
 }
@@ -65,18 +63,26 @@ static struct pipe_query *r300_create_query(struct pipe_context *pipe,
 static void r300_destroy_query(struct pipe_context* pipe,
                                struct pipe_query* query)
 {
-    struct r300_query* q = (struct r300_query*)query;
+    struct r300_context *r300 = r300_context(pipe);
+    struct r300_query* q = r300_query(query);
 
+    r300->rws->buffer_reference(r300->rws, &q->buffer, NULL);
     remove_from_list(q);
     FREE(query);
 }
 
+void r300_resume_query(struct r300_context *r300,
+                       struct r300_query *query)
+{
+    r300->query_current = query;
+    r300->query_start.dirty = TRUE;
+}
+
 static void r300_begin_query(struct pipe_context* pipe,
                              struct pipe_query* query)
 {
-    uint32_t value = ~0U;
     struct r300_context* r300 = r300_context(pipe);
-    struct r300_query* q = (struct r300_query*)query;
+    struct r300_query* q = r300_query(query);
 
     if (r300->query_current != NULL) {
         fprintf(stderr, "r300: begin_query: "
@@ -85,30 +91,29 @@ static void r300_begin_query(struct pipe_context* pipe,
         return;
     }
 
-    pipe_buffer_write(pipe,
-		      r300->oqbo,
-		      q->offset,
-		      sizeof value,
-		      &value);
+    q->num_results = 0;
+    r300_resume_query(r300, q);
+}
 
-    q->flushed = FALSE;
-    r300->query_current = q;
-    r300->query_start.dirty = TRUE;
+void r300_stop_query(struct r300_context *r300)
+{
+    r300_emit_query_end(r300);
+    r300->query_current = NULL;
 }
 
 static void r300_end_query(struct pipe_context* pipe,
 	                   struct pipe_query* query)
 {
     struct r300_context* r300 = r300_context(pipe);
+    struct r300_query *q = r300_query(query);
 
-    if ((struct r300_query*)query != r300->query_current) {
+    if (q != r300->query_current) {
         fprintf(stderr, "r300: end_query: Got invalid query.\n");
         assert(0);
         return;
     }
 
-    r300_emit_query_end(r300);
-    r300->query_current = NULL;
+    r300_stop_query(r300);
 }
 
 static boolean r300_get_query_result(struct pipe_context* pipe,
@@ -117,54 +122,28 @@ static boolean r300_get_query_result(struct pipe_context* pipe,
                                      void* vresult)
 {
     struct r300_context* r300 = r300_context(pipe);
-    struct r300_screen* r300screen = r300->screen;
-    struct r300_query *q = (struct r300_query*)query;
-    struct pipe_transfer *transfer;
-    unsigned flags = PIPE_TRANSFER_READ;
-    uint32_t* map;
-    uint32_t temp = 0;
-    unsigned i, num_results;
+    struct r300_query *q = r300_query(query);
+    unsigned flags, i;
+    uint32_t temp, *map;
     uint64_t *result = (uint64_t*)vresult;
 
-    if (q->flushed == FALSE)
+    if (!q->flushed)
         pipe->flush(pipe, 0, NULL);
-    if (!wait) {
-        flags |= PIPE_TRANSFER_DONTBLOCK;
-    }
 
-    map = pipe_buffer_map(pipe, r300->oqbo, flags, &transfer);
+    flags = PIPE_TRANSFER_READ | (!wait ? PIPE_TRANSFER_DONTBLOCK : 0);
+
+    map = r300->rws->buffer_map(r300->rws, q->buffer, flags);
     if (!map)
         return FALSE;
-    map += q->offset / 4;
 
-    if (r300screen->caps.family == CHIP_FAMILY_RV530)
-        num_results = r300screen->caps.num_z_pipes;
-    else
-        num_results = r300screen->caps.num_frag_pipes;
-
-    for (i = 0; i < num_results; i++) {
-        if (*map == ~0U) {
-            /* Looks like our results aren't ready yet. */
-            if (wait) {
-                fprintf(stderr, "r300: Despite waiting, OQ results haven't "
-                                "come in yet. This is a driver bug.\n"
-                                "r300: Returning bogus results to avoid "
-                                "a possible infinite loop...\n");
-                temp = 987654321;
-            } else {
-                temp = ~0U;
-            }
-            break;
-        }
+    /* Sum up the results. */
+    temp = 0;
+    for (i = 0; i < q->num_results; i++) {
         temp += *map;
         map++;
     }
-    pipe_buffer_unmap(pipe, r300->oqbo, transfer);
 
-    if (temp == ~0U) {
-        /* Our results haven't been written yet... */
-        return FALSE;
-    }
+    r300->rws->buffer_unmap(r300->rws, q->buffer);
 
     *result = temp;
     return TRUE;
diff --git a/src/gallium/drivers/r300/r300_screen_buffer.c b/src/gallium/drivers/r300/r300_screen_buffer.c
index fe53f30..7959e6a 100644
--- a/src/gallium/drivers/r300/r300_screen_buffer.c
+++ b/src/gallium/drivers/r300/r300_screen_buffer.c
@@ -264,10 +264,6 @@ struct pipe_resource *r300_buffer_create(struct pipe_screen *screen,
     rbuf->b.vtbl = &r300_buffer_vtbl;
     pipe_reference_init(&rbuf->b.b.reference, 1);
     rbuf->b.b.screen = screen;
-
-    if (rbuf->b.b.bind & R300_BIND_OQBO)
-        alignment = 4096;
-
     rbuf->domain = R300_DOMAIN_GTT;
 
     rbuf->buf = r300screen->rws->buffer_create(r300screen->rws,




More information about the mesa-commit mailing list