From: Grigori Goronzy Date: Tue, 10 Sep 2013 23:41:39 +0000 (+0200) Subject: r600g: add support for separately allocated CMASKs X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=56d9a397aa2dbee6b12e1bbe56be39f426e1e34d;p=mesa.git r600g: add support for separately allocated CMASKs v2: check for NULL cbufs Signed-off-by: Marek Olšák --- diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index 887f736a1c0..469b3a326e1 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -1555,8 +1555,11 @@ void evergreen_init_color_surface(struct r600_context *rctx, surf->export_16bpc = true; } - if (rtex->fmask_size && rtex->cmask_size) { - color_info |= S_028C70_COMPRESSION(1) | S_028C70_FAST_CLEAR(1); + if (rtex->fmask_size) { + color_info |= S_028C70_COMPRESSION(1); + } + if (rtex->cmask_size) { + color_info |= S_028C70_FAST_CLEAR(1); } base_offset = r600_resource_va(rctx->b.b.screen, pipe_tex); @@ -1574,11 +1577,15 @@ void evergreen_init_color_surface(struct r600_context *rctx, S_028C6C_SLICE_MAX(surf->base.u.tex.last_layer); } surf->cb_color_attrib = color_attrib; - if (rtex->fmask_size && rtex->cmask_size) { + if (rtex->fmask_size) { surf->cb_color_fmask = (base_offset + rtex->fmask_offset) >> 8; - surf->cb_color_cmask = (base_offset + rtex->cmask_offset) >> 8; } else { surf->cb_color_fmask = surf->cb_color_base; + } + if (rtex->cmask_size) { + uint64_t va = r600_resource_va(rctx->b.b.screen, &rtex->cmask->b.b); + surf->cb_color_cmask = (va + rtex->cmask_offset) >> 8; + } else { surf->cb_color_cmask = surf->cb_color_base; } surf->cb_color_fmask_slice = S_028C88_TILE_MAX(rtex->fmask_slice_tile_max); @@ -2180,6 +2187,13 @@ static void evergreen_emit_framebuffer_state(struct r600_context *rctx, struct r &rctx->b.rings.gfx, (struct r600_resource*)cb->base.texture, RADEON_USAGE_READWRITE); + unsigned cmask_reloc = 0; + if (tex->cmask && tex->cmask != &tex->resource) { + cmask_reloc = r600_context_bo_reloc(&rctx->b, &rctx->b.rings.gfx, + tex->cmask, RADEON_USAGE_READWRITE); + } else { + cmask_reloc = reloc; + } r600_write_context_reg_seq(cs, R_028C60_CB_COLOR0_BASE + i * 0x3C, 13); radeon_emit(cs, cb->cb_color_base); /* R_028C60_CB_COLOR0_BASE */ @@ -2208,7 +2222,7 @@ static void evergreen_emit_framebuffer_state(struct r600_context *rctx, struct r radeon_emit(cs, reloc); radeon_emit(cs, PKT3(PKT3_NOP, 0, 0)); /* R_028C7C_CB_COLOR0_CMASK */ - radeon_emit(cs, reloc); + radeon_emit(cs, cmask_reloc); radeon_emit(cs, PKT3(PKT3_NOP, 0, 0)); /* R_028C84_CB_COLOR0_FMASK */ radeon_emit(cs, reloc); diff --git a/src/gallium/drivers/r600/r600_hw_context.c b/src/gallium/drivers/r600/r600_hw_context.c index d985af9879f..9c0a78e0720 100644 --- a/src/gallium/drivers/r600/r600_hw_context.c +++ b/src/gallium/drivers/r600/r600_hw_context.c @@ -644,11 +644,15 @@ void r600_flag_resource_cache_flush(struct r600_context *rctx, /* Check colorbuffers. */ for (i = 0; i < rctx->framebuffer.state.nr_cbufs; i++) { - if (rctx->framebuffer.state.cbufs[i] && - rctx->framebuffer.state.cbufs[i]->texture == res) { - struct r600_texture *tex = - (struct r600_texture*)rctx->framebuffer.state.cbufs[i]->texture; + struct r600_texture *tex; + if (rctx->framebuffer.state.cbufs[i] == NULL) { + continue; + } + + tex = (struct r600_texture*)rctx->framebuffer.state.cbufs[i]->texture; + + if (rctx->framebuffer.state.cbufs[i]->texture == res) { rctx->b.flags |= R600_CONTEXT_FLUSH_AND_INV_CB | R600_CONTEXT_FLUSH_AND_INV | R600_CONTEXT_WAIT_3D_IDLE; @@ -658,6 +662,12 @@ void r600_flag_resource_cache_flush(struct r600_context *rctx, } break; } + + if (tex && tex->cmask && tex->cmask != &tex->resource && &tex->cmask->b.b == res) { + rctx->b.flags |= R600_CONTEXT_FLUSH_AND_INV_CB_META | + R600_CONTEXT_FLUSH_AND_INV | + R600_CONTEXT_WAIT_3D_IDLE; + } } /* Check a depth buffer. */ diff --git a/src/gallium/drivers/r600/r600_resource.h b/src/gallium/drivers/r600/r600_resource.h index 92b9cc50b98..92e57b6d1b4 100644 --- a/src/gallium/drivers/r600/r600_resource.h +++ b/src/gallium/drivers/r600/r600_resource.h @@ -71,6 +71,7 @@ struct r600_texture { /* use htile only for first level */ float depth_clear; + struct r600_resource *cmask; unsigned color_clear_value[2]; }; @@ -152,6 +153,8 @@ void r600_texture_get_fmask_info(struct r600_screen *rscreen, void r600_texture_get_cmask_info(struct r600_screen *rscreen, struct r600_texture *rtex, struct r600_cmask_info *out); +void r600_texture_init_cmask(struct r600_screen *rscreen, + struct r600_texture *rtex); struct pipe_resource *r600_texture_create(struct pipe_screen *screen, const struct pipe_resource *templ); struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen, diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c index 07e7c6ca384..8ba41d19efe 100644 --- a/src/gallium/drivers/r600/r600_texture.c +++ b/src/gallium/drivers/r600/r600_texture.c @@ -301,6 +301,9 @@ static void r600_texture_destroy(struct pipe_screen *screen, pipe_resource_reference((struct pipe_resource **)&rtex->flushed_depth_texture, NULL); pipe_resource_reference((struct pipe_resource**)&rtex->htile, NULL); + if (rtex->cmask != &rtex->resource) { + pipe_resource_reference((struct pipe_resource**)&rtex->cmask, NULL); + } pb_reference(&resource->buf, NULL); FREE(rtex); } @@ -431,6 +434,24 @@ static void r600_texture_allocate_cmask(struct r600_screen *rscreen, #endif } +void r600_texture_init_cmask(struct r600_screen *rscreen, + struct r600_texture *rtex) { + struct r600_cmask_info cmask; + + assert(rtex->cmask_size == 0); + + r600_texture_get_cmask_info(rscreen, rtex, &cmask); + rtex->cmask_slice_tile_max = cmask.slice_tile_max; + rtex->cmask_offset = 0; + rtex->cmask_size = cmask.size; + rtex->cmask = (struct r600_resource *)pipe_buffer_create(&rscreen->b.b, + PIPE_BIND_CUSTOM, PIPE_USAGE_STATIC, rtex->cmask_size); + + if (rtex->cmask == NULL) { + rtex->cmask_size = 0; + } +} + static struct r600_texture * r600_texture_create_object(struct pipe_screen *screen, const struct pipe_resource *base, @@ -464,9 +485,11 @@ r600_texture_create_object(struct pipe_screen *screen, return NULL; } + rtex->cmask = NULL; if (base->nr_samples > 1 && !rtex->is_depth && !buf) { r600_texture_allocate_fmask(rscreen, rtex); r600_texture_allocate_cmask(rscreen, rtex); + rtex->cmask = &rtex->resource; } if (!rtex->is_depth && base->nr_samples > 1 && @@ -532,7 +555,7 @@ r600_texture_create_object(struct pipe_screen *screen, if (rtex->cmask_size) { /* Initialize the cmask to 0xCC (= compressed state). */ - r600_screen_clear_buffer(rscreen, &rtex->resource.b.b, + r600_screen_clear_buffer(rscreen, &rtex->cmask->b.b, rtex->cmask_offset, rtex->cmask_size, 0xCC); }