summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2010-06-29 23:34:36 +0200
committerMarek Olšák <[email protected]>2010-06-30 00:03:04 +0200
commit6a34287bb5147a3213e94d88c97db4ec403509ae (patch)
tree50e9a21abc519ceb8c017e0fddc6702bdc669efb /src
parent3d6101245b2726721a26931e0491c61286ca29c6 (diff)
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.
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/r300/r300_context.h4
-rw-r--r--src/gallium/drivers/r300/r300_state.c48
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_drm_buffer.c15
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 50dcd0fc67c..ac5ae23cb5a 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 93cc0dbe985..c1bac7328e7 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 a4b6cff33d1..cb4ec32feae 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)