Mesa (master): r300g: move one flush from winsys to the context

Marek Olšák mareko at kemper.freedesktop.org
Tue Jun 29 15:20:27 PDT 2010


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

Author: Marek Olšák <maraeo at gmail.com>
Date:   Tue Jun 29 23:34:36 2010 +0200

r300g: move one flush from winsys to the context

This flush happens when changing the tiling flags, and it should really be
done in the context.

I hope this fixes FDO bug #28630.

---

 src/gallium/drivers/r300/r300_context.h           |    4 ++
 src/gallium/drivers/r300/r300_state.c             |   48 ++++++++++++--------
 src/gallium/winsys/radeon/drm/radeon_drm_buffer.c |   15 +------
 3 files changed, 34 insertions(+), 33 deletions(-)

diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index 50dcd0f..ac5ae23 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -365,6 +365,10 @@ struct r300_texture {
 
     /* Buffer tiling */
     enum r300_buffer_tiling microtile, macrotile;
+
+    /* This is the level tiling flags were last time set for.
+     * It's used to prevent redundant tiling-flags changes from happening.*/
+    unsigned surface_level;
 };
 
 struct r300_vertex_element_state {
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index 93cc0db..c1bac73 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -609,32 +609,42 @@ static void r300_set_stencil_ref(struct pipe_context* pipe,
     r300->dsa_state.dirty = TRUE;
 }
 
-/* This switcheroo is needed just because of goddamned MACRO_SWITCH. */
-static void r300_fb_set_tiling_flags(struct r300_context *r300,
-                               const struct pipe_framebuffer_state *old_state,
-                               const struct pipe_framebuffer_state *new_state)
+static void r300_tex_set_tiling_flags(struct r300_context *r300,
+                                      struct r300_texture *tex, unsigned level)
 {
-    struct r300_texture *tex;
-    unsigned i, level;
-
-    /* Set tiling flags for new surfaces. */
-    for (i = 0; i < new_state->nr_cbufs; i++) {
-        tex = r300_texture(new_state->cbufs[i]->texture);
-        level = new_state->cbufs[i]->level;
+    /* Check if the macrotile flag needs to be changed.
+     * Skip changing the flags otherwise. */
+    if (tex->mip_macrotile[tex->surface_level] != tex->mip_macrotile[level]) {
+        /* Tiling determines how DRM treats the buffer data.
+         * We must flush CS when changing it if the buffer is referenced. */
+        if (r300->rws->is_buffer_referenced(r300->rws, tex->buffer, R300_REF_CS))
+            r300->context.flush(&r300->context, 0, NULL);
 
         r300->rws->buffer_set_tiling(r300->rws, tex->buffer,
                 tex->pitch[0] * util_format_get_blocksize(tex->b.b.format),
                 tex->microtile,
                 tex->mip_macrotile[level]);
+
+        tex->surface_level = level;
     }
-    if (new_state->zsbuf) {
-        tex = r300_texture(new_state->zsbuf->texture);
-        level = new_state->zsbuf->level;
+}
 
-        r300->rws->buffer_set_tiling(r300->rws, tex->buffer,
-                tex->pitch[0] * util_format_get_blocksize(tex->b.b.format),
-                tex->microtile,
-                tex->mip_macrotile[level]);
+/* This switcheroo is needed just because of goddamned MACRO_SWITCH. */
+static void r300_fb_set_tiling_flags(struct r300_context *r300,
+                               const struct pipe_framebuffer_state *state)
+{
+    unsigned i;
+
+    /* Set tiling flags for new surfaces. */
+    for (i = 0; i < state->nr_cbufs; i++) {
+        r300_tex_set_tiling_flags(r300,
+                                  r300_texture(state->cbufs[i]->texture),
+                                  state->cbufs[i]->level);
+    }
+    if (state->zsbuf) {
+        r300_tex_set_tiling_flags(r300,
+                                  r300_texture(state->zsbuf->texture),
+                                  state->zsbuf->level);
     }
 }
 
@@ -704,7 +714,7 @@ static void
     }
 
     /* The tiling flags are dependent on the surface miplevel, unfortunately. */
-    r300_fb_set_tiling_flags(r300, r300->fb_state.state, state);
+    r300_fb_set_tiling_flags(r300, state);
 
     util_assign_framebuffer_state(r300->fb_state.state, state);
 
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c b/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c
index a4b6cff..cb4ec32 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c
@@ -22,8 +22,6 @@ struct radeon_drm_buffer {
 
     boolean flinked;
     uint32_t flink;
-    uint32_t tileflags;
-    uint32_t pitch;
 
     struct radeon_drm_buffer *next, *prev;
 };
@@ -297,9 +295,6 @@ void radeon_drm_bufmgr_get_tiling(struct pb_buffer *_buf,
 
     radeon_bo_get_tiling(buf->bo, &flags, &pitch);
 
-    buf->tileflags = flags;
-    buf->pitch = pitch;
-
     *microtiled = R300_BUFFER_LINEAR;
     *macrotiled = R300_BUFFER_LINEAR;
     if (flags & RADEON_BO_FLAGS_MICRO_TILE)
@@ -326,15 +321,7 @@ void radeon_drm_bufmgr_set_tiling(struct pb_buffer *_buf,
     if (macrotiled == R300_BUFFER_TILED)
         flags |= RADEON_BO_FLAGS_MACRO_TILE;
 
-    if (flags != buf->tileflags || pitch != buf->pitch) {
-        /* Tiling determines how DRM treats the buffer data.
-         * We must flush CS when changing it if the buffer is referenced. */
-        if (radeon_bo_is_referenced_by_cs(buf->bo,  buf->mgr->rws->cs)) {
-	    buf->mgr->rws->flush_cb(buf->mgr->rws->flush_data);
-        }
-
-        radeon_bo_set_tiling(buf->bo, flags, pitch);
-    }
+    radeon_bo_set_tiling(buf->bo, flags, pitch);
 }
 
 static uint32_t gem_domain(enum r300_buffer_domain dom)



More information about the mesa-commit mailing list