From 6a34287bb5147a3213e94d88c97db4ec403509ae Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Tue, 29 Jun 2010 23:34:36 +0200 Subject: [PATCH] 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 +++++++++++-------- .../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 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) -- 2.30.2