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

Author: Marek Olšák <[email protected]>
Date:   Sat Mar 13 06:07:33 2010 +0100

r300g: refrain from using immediate mode if it causes slowdown

E.g. when mapping buffers could flush CS or cause waiting
for a busy buffer.

The side effect of this is it also fixes progs/demos/arbocclude however
a separate fix should be proposed to address this issue in other cases
it might occur.

---

 src/gallium/drivers/r300/r300_render.c             |   33 ++++++++++++++++++-
 src/gallium/winsys/drm/radeon/core/radeon_buffer.c |   14 ++++++++
 src/gallium/winsys/drm/radeon/core/radeon_winsys.h |    3 ++
 3 files changed, 48 insertions(+), 2 deletions(-)

diff --git a/src/gallium/drivers/r300/r300_render.c 
b/src/gallium/drivers/r300/r300_render.c
index ccf3987..971e7f3 100644
--- a/src/gallium/drivers/r300/r300_render.c
+++ b/src/gallium/drivers/r300/r300_render.c
@@ -131,9 +131,38 @@ static boolean r300_reserve_cs_space(struct r300_context 
*r300,
 }
 
 static boolean immd_is_good_idea(struct r300_context *r300,
-                                      unsigned count)
+                                 unsigned count)
 {
-    return count <= 4;
+    struct pipe_vertex_element* velem;
+    struct pipe_vertex_buffer* vbuf;
+    boolean checked[PIPE_MAX_ATTRIBS] = {0};
+    unsigned vertex_element_count = r300->velems->count;
+    unsigned i, vbi;
+
+    if (count > 4) {
+        return FALSE;
+    }
+
+    /* We shouldn't map buffers referenced by CS, busy buffers,
+     * and ones placed in VRAM. */
+    /* XXX Check for VRAM buffers. */
+    for (i = 0; i < vertex_element_count; i++) {
+        velem = &r300->velems->velem[i];
+        vbi = velem->vertex_buffer_index;
+
+        if (!checked[vbi]) {
+            vbuf = &r300->vertex_buffer[vbi];
+
+            if (r300->winsys->is_buffer_referenced(r300->winsys,
+                                                   vbuf->buffer)) {
+                /* It's a very bad idea to map it... */
+                return FALSE;
+            }
+            checked[vbi] = TRUE;
+        }
+    }
+
+    return TRUE;
 }
 
 static void r300_emit_draw_arrays_immediate(struct r300_context *r300,
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c 
b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c
index daa032a..25b58b2 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c
+++ b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c
@@ -213,6 +213,18 @@ static void radeon_buffer_unmap(struct pipe_winsys *ws,
     }
 }
 
+static boolean radeon_is_buffer_referenced(struct radeon_winsys *ws,
+                                           struct pipe_buffer *buffer)
+{
+    struct radeon_pipe_buffer *radeon_buffer =
+        (struct radeon_pipe_buffer*)buffer;
+    uint32_t domain;
+
+    /* Referenced by CS or HW. */
+    return radeon_bo_is_referenced_by_cs(radeon_buffer->bo, ws->priv->cs) ||
+           radeon_bo_is_busy(radeon_buffer->bo, &domain);
+}
+
 static void radeon_buffer_set_tiling(struct radeon_winsys *ws,
                                      struct pipe_buffer *buffer,
                                      uint32_t pitch,
@@ -370,5 +382,7 @@ struct radeon_winsys* radeon_pipe_winsys(int fd)
     radeon_ws->buffer_from_handle = radeon_buffer_from_handle;
     radeon_ws->buffer_get_handle = radeon_buffer_get_handle;
 
+    radeon_ws->is_buffer_referenced = radeon_is_buffer_referenced;
+
     return radeon_ws;
 }
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_winsys.h 
b/src/gallium/winsys/drm/radeon/core/radeon_winsys.h
index 37eeb45..887a381 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_winsys.h
+++ b/src/gallium/winsys/drm/radeon/core/radeon_winsys.h
@@ -118,6 +118,9 @@ struct radeon_winsys {
                               uint32_t pitch,
                               boolean microtiled,
                               boolean macrotiled);
+
+    boolean (*is_buffer_referenced)(struct radeon_winsys *winsys,
+                                    struct pipe_buffer *buffer);
 };
 
 #endif

_______________________________________________
mesa-commit mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/mesa-commit

Reply via email to