From 27b102e7fdbcd2beedc815996e1b5fcb2b612206 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sun, 6 Sep 2015 17:37:38 +0200 Subject: r600g: only do depth-only or stencil-only in-place decompression MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit instead of always doing both. Usually, only depth is needed, so stencil decompression is useless. Reviewed-by: Michel Dänzer --- src/gallium/drivers/r600/evergreen_state.c | 12 +++++++++--- src/gallium/drivers/r600/r600_blit.c | 27 ++++++++++++++++++++++----- src/gallium/drivers/r600/r600_pipe.h | 4 +++- src/gallium/drivers/r600/r600_state.c | 12 +++++++++--- 4 files changed, 43 insertions(+), 12 deletions(-) diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index 6169c5b719b..c6702a9ca34 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -783,6 +783,12 @@ evergreen_create_sampler_view_custom(struct pipe_context *ctx, va = tmp->resource.gpu_address; + if (state->format == PIPE_FORMAT_X24S8_UINT || + state->format == PIPE_FORMAT_S8X24_UINT || + state->format == PIPE_FORMAT_X32_S8X24_UINT || + state->format == PIPE_FORMAT_S8_UINT) + view->is_stencil_sampler = true; + view->tex_resource = &tmp->resource; view->tex_resource_words[0] = (S_030000_DIM(r600_tex_dim(texture->target, texture->nr_samples)) | S_030000_PITCH((pitch / 8) - 1) | @@ -1823,9 +1829,9 @@ static void evergreen_emit_db_misc_state(struct r600_context *rctx, struct r600_ S_028000_STENCIL_COPY_ENABLE(a->copy_stencil) | S_028000_COPY_CENTROID(1) | S_028000_COPY_SAMPLE(a->copy_sample); - } else if (a->flush_depthstencil_in_place) { - db_render_control |= S_028000_DEPTH_COMPRESS_DISABLE(1) | - S_028000_STENCIL_COMPRESS_DISABLE(1); + } else if (a->flush_depth_inplace || a->flush_stencil_inplace) { + db_render_control |= S_028000_DEPTH_COMPRESS_DISABLE(a->flush_depth_inplace) | + S_028000_STENCIL_COMPRESS_DISABLE(a->flush_stencil_inplace); db_render_override |= S_02800C_DISABLE_PIXEL_RATE_TILES(1); } if (a->htile_clear) { diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c index d1370cd8f26..aede8408446 100644 --- a/src/gallium/drivers/r600/r600_blit.c +++ b/src/gallium/drivers/r600/r600_blit.c @@ -202,20 +202,28 @@ static void r600_blit_decompress_depth(struct pipe_context *ctx, static void r600_blit_decompress_depth_in_place(struct r600_context *rctx, struct r600_texture *texture, + bool is_stencil_sampler, unsigned first_level, unsigned last_level, unsigned first_layer, unsigned last_layer) { struct pipe_surface *zsurf, surf_tmpl = {{0}}; unsigned layer, max_layer, checked_last_layer, level; + unsigned *dirty_level_mask; /* Enable decompression in DB_RENDER_CONTROL */ - rctx->db_misc_state.flush_depthstencil_in_place = true; + if (is_stencil_sampler) { + rctx->db_misc_state.flush_stencil_inplace = true; + dirty_level_mask = &texture->stencil_dirty_level_mask; + } else { + rctx->db_misc_state.flush_depth_inplace = true; + dirty_level_mask = &texture->dirty_level_mask; + } r600_mark_atom_dirty(rctx, &rctx->db_misc_state.atom); surf_tmpl.format = texture->resource.b.b.format; for (level = first_level; level <= last_level; level++) { - if (!(texture->dirty_level_mask & (1 << level))) + if (!(*dirty_level_mask & (1 << level))) continue; surf_tmpl.u.tex.level = level; @@ -242,12 +250,13 @@ static void r600_blit_decompress_depth_in_place(struct r600_context *rctx, /* The texture will always be dirty if some layers or samples aren't flushed. * I don't think this case occurs often though. */ if (first_layer == 0 && last_layer == max_layer) { - texture->dirty_level_mask &= ~(1 << level); + *dirty_level_mask &= ~(1 << level); } } /* Disable decompression in DB_RENDER_CONTROL */ - rctx->db_misc_state.flush_depthstencil_in_place = false; + rctx->db_misc_state.flush_depth_inplace = false; + rctx->db_misc_state.flush_stencil_inplace = false; r600_mark_atom_dirty(rctx, &rctx->db_misc_state.atom); } @@ -259,12 +268,14 @@ void r600_decompress_depth_textures(struct r600_context *rctx, while (depth_texture_mask) { struct pipe_sampler_view *view; + struct r600_pipe_sampler_view *rview; struct r600_texture *tex; i = u_bit_scan(&depth_texture_mask); view = &textures->views[i]->base; assert(view); + rview = (struct r600_pipe_sampler_view*)view; tex = (struct r600_texture *)view->texture; assert(tex->is_depth && !tex->is_flushing_texture); @@ -272,6 +283,7 @@ void r600_decompress_depth_textures(struct r600_context *rctx, if (rctx->b.chip_class >= EVERGREEN || r600_can_read_depth(tex)) { r600_blit_decompress_depth_in_place(rctx, tex, + rview->is_stencil_sampler, view->u.tex.first_level, view->u.tex.last_level, 0, util_max_layer(&tex->resource.b.b, view->u.tex.first_level)); } else { @@ -367,9 +379,14 @@ static bool r600_decompress_subresource(struct pipe_context *ctx, if (rtex->is_depth && !rtex->is_flushing_texture) { if (rctx->b.chip_class >= EVERGREEN || r600_can_read_depth(rtex)) { - r600_blit_decompress_depth_in_place(rctx, rtex, + r600_blit_decompress_depth_in_place(rctx, rtex, false, level, level, first_layer, last_layer); + if (rtex->surface.flags & RADEON_SURF_SBUFFER) { + r600_blit_decompress_depth_in_place(rctx, rtex, true, + level, level, + first_layer, last_layer); + } } else { if (!r600_init_flushed_depth_texture(ctx, tex, NULL)) return false; /* error */ diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h index d0774de8573..520b03f605d 100644 --- a/src/gallium/drivers/r600/r600_pipe.h +++ b/src/gallium/drivers/r600/r600_pipe.h @@ -109,7 +109,8 @@ struct r600_db_misc_state { struct r600_atom atom; bool occlusion_query_enabled; bool flush_depthstencil_through_cb; - bool flush_depthstencil_in_place; + bool flush_depth_inplace; + bool flush_stencil_inplace; bool copy_depth, copy_stencil; unsigned copy_sample; unsigned log_samples; @@ -253,6 +254,7 @@ struct r600_pipe_sampler_view { struct r600_resource *tex_resource; uint32_t tex_resource_words[8]; bool skip_mip_address_reloc; + bool is_stencil_sampler; }; struct r600_rasterizer_state { diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index 4b171894f5c..1be3e1b4de5 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -710,6 +710,12 @@ r600_create_sampler_view_custom(struct pipe_context *ctx, break; } + if (state->format == PIPE_FORMAT_X24S8_UINT || + state->format == PIPE_FORMAT_S8X24_UINT || + state->format == PIPE_FORMAT_X32_S8X24_UINT || + state->format == PIPE_FORMAT_S8_UINT) + view->is_stencil_sampler = true; + view->tex_resource = &tmp->resource; view->tex_resource_words[0] = (S_038000_DIM(r600_tex_dim(texture->target, texture->nr_samples)) | S_038000_TILE_MODE(array_mode) | @@ -1659,9 +1665,9 @@ static void r600_emit_db_misc_state(struct r600_context *rctx, struct r600_atom if (rctx->b.family == CHIP_RV610 || rctx->b.family == CHIP_RV630 || rctx->b.family == CHIP_RV620 || rctx->b.family == CHIP_RV635) db_render_override |= S_028D10_FORCE_HIZ_ENABLE(V_028D10_FORCE_DISABLE); - } else if (a->flush_depthstencil_in_place) { - db_render_control |= S_028D0C_DEPTH_COMPRESS_DISABLE(1) | - S_028D0C_STENCIL_COMPRESS_DISABLE(1); + } else if (a->flush_depth_inplace || a->flush_stencil_inplace) { + db_render_control |= S_028D0C_DEPTH_COMPRESS_DISABLE(a->flush_depth_inplace) | + S_028D0C_STENCIL_COMPRESS_DISABLE(a->flush_stencil_inplace); db_render_override |= S_028D10_NOOP_CULL_DISABLE(1); } if (a->htile_clear) { -- cgit v1.2.3