--- src/gallium/drivers/r600/evergreen_state.c | 24 +++++++++++++++++++----- src/gallium/drivers/r600/r600_hw_context.c | 12 +++++++++--- src/gallium/drivers/r600/r600_resource.h | 3 +++ src/gallium/drivers/r600/r600_texture.c | 25 ++++++++++++++++++++++++- 4 files changed, 55 insertions(+), 9 deletions(-)
diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index 30f372d..16d40e0 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->context.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->context.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->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, &rctx->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); r600_write_value(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 r600_write_value(cs, reloc); r600_write_value(cs, PKT3(PKT3_NOP, 0, 0)); /* R_028C7C_CB_COLOR0_CMASK */ - r600_write_value(cs, reloc); + r600_write_value(cs, cmask_reloc); r600_write_value(cs, PKT3(PKT3_NOP, 0, 0)); /* R_028C84_CB_COLOR0_FMASK */ r600_write_value(cs, reloc); diff --git a/src/gallium/drivers/r600/r600_hw_context.c b/src/gallium/drivers/r600/r600_hw_context.c index 652329b..b1b711e 100644 --- a/src/gallium/drivers/r600/r600_hw_context.c +++ b/src/gallium/drivers/r600/r600_hw_context.c @@ -796,11 +796,11 @@ void r600_flag_resource_cache_flush(struct r600_context *rctx, /* Check colorbuffers. */ for (i = 0; i < rctx->framebuffer.state.nr_cbufs; i++) { + struct r600_texture *tex = + (struct r600_texture*)rctx->framebuffer.state.cbufs[i]->texture; + 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; - rctx->flags |= R600_CONTEXT_FLUSH_AND_INV_CB | R600_CONTEXT_FLUSH_AND_INV | R600_CONTEXT_WAIT_3D_IDLE; @@ -810,6 +810,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->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 4c55f66..f4aa021 100644 --- a/src/gallium/drivers/r600/r600_resource.h +++ b/src/gallium/drivers/r600/r600_resource.h @@ -92,6 +92,7 @@ struct r600_texture { /* use htile only for first level */ float depth_clear; + struct r600_resource *cmask; unsigned color_clear_value[2]; }; @@ -173,6 +174,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 36cca17..1e80ed9 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->screen, + 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, @@ -465,9 +486,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 && @@ -533,7 +556,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); } -- 1.8.1.2 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev