diff options
author | Marek Olšák <[email protected]> | 2016-06-21 16:16:15 +0200 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2016-06-29 20:12:00 +0200 |
commit | 9124457bff70686ea804d7e35fb63bea5db5a8a2 (patch) | |
tree | 9e9b1bdd9e42caab06096e6c446bb41632f5b1be | |
parent | fa7c927625ec1904a659edfdd677b5752165590a (diff) |
gallium/radeon: add state setup for a separate DCC buffer
Reviewed-by: Nicolai Hähnle <[email protected]>
-rw-r--r-- | src/gallium/drivers/radeon/r600_pipe_common.h | 8 | ||||
-rw-r--r-- | src/gallium/drivers/radeon/r600_texture.c | 18 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/si_descriptors.c | 11 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/si_state.c | 9 |
4 files changed, 41 insertions, 5 deletions
diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h index 75dc5acc247..b411b23ba87 100644 --- a/src/gallium/drivers/radeon/r600_pipe_common.h +++ b/src/gallium/drivers/radeon/r600_pipe_common.h @@ -265,6 +265,14 @@ struct r600_texture { bool non_disp_tiling; /* R600-Cayman only */ + /* Whether the texture is a displayable back buffer and needs DCC + * decompression, which is expensive. Therefore, it's enabled only + * if statistics suggest that it will pay off and it's allocated + * separately. Limited to target == 2D and last_level == 0. If enabled, + * dcc_offset contains the absolute GPUVM address, not the relative one. + */ + struct r600_resource *dcc_separate_buffer; + /* Counter that should be non-zero if the texture is bound to a * framebuffer. Implemented in radeonsi only. */ diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c index 50f50257ebf..c45c5f29fb8 100644 --- a/src/gallium/drivers/radeon/r600_texture.c +++ b/src/gallium/drivers/radeon/r600_texture.c @@ -387,6 +387,8 @@ static bool r600_texture_discard_dcc(struct r600_common_screen *rscreen, if (!r600_can_disable_dcc(rtex)) return false; + assert(rtex->dcc_separate_buffer == NULL); + /* Disable DCC. */ rtex->dcc_offset = 0; @@ -564,6 +566,7 @@ static void r600_texture_destroy(struct pipe_screen *screen, r600_resource_reference(&rtex->cmask_buffer, NULL); } pb_reference(&resource->buf, NULL); + r600_resource_reference(&rtex->dcc_separate_buffer, NULL); FREE(rtex); } @@ -1800,12 +1803,21 @@ void vi_dcc_clear_level(struct r600_common_context *rctx, struct r600_texture *rtex, unsigned level, unsigned clear_value) { - struct pipe_resource *dcc_buffer = &rtex->resource.b.b; - uint64_t dcc_offset = rtex->dcc_offset + - rtex->surface.level[level].dcc_offset; + struct pipe_resource *dcc_buffer; + uint64_t dcc_offset; assert(rtex->dcc_offset && rtex->surface.level[level].dcc_enabled); + if (rtex->dcc_separate_buffer) { + dcc_buffer = &rtex->dcc_separate_buffer->b.b; + dcc_offset = 0; + } else { + dcc_buffer = &rtex->resource.b.b; + dcc_offset = rtex->dcc_offset; + } + + dcc_offset += rtex->surface.level[level].dcc_offset; + rctx->clear_buffer(&rctx->b, dcc_buffer, dcc_offset, rtex->surface.level[level].dcc_fast_clear_size, clear_value, R600_COHERENCY_CB_META); diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c index 78d14afe406..d1cd3c4449a 100644 --- a/src/gallium/drivers/radeonsi/si_descriptors.c +++ b/src/gallium/drivers/radeonsi/si_descriptors.c @@ -304,6 +304,15 @@ static void si_sampler_view_add_buffer(struct si_context *sctx, radeon_add_to_buffer_list(&sctx->b, &sctx->b.gfx, rres, usage, r600_get_sampler_view_priority(rres)); + + if (resource->target != PIPE_BUFFER) { + struct r600_texture *rtex = (struct r600_texture*)resource; + + if (rtex->dcc_separate_buffer) + radeon_add_to_buffer_list(&sctx->b, &sctx->b.gfx, + rtex->dcc_separate_buffer, usage, + RADEON_PRIO_DCC); + } } static void si_sampler_views_begin_new_cs(struct si_context *sctx, @@ -352,7 +361,7 @@ void si_set_mutable_tex_desc_fields(struct r600_texture *tex, if (tex->dcc_offset && tex->surface.level[first_level].dcc_enabled) { state[6] |= S_008F28_COMPRESSION_EN(1); - state[7] = (tex->resource.gpu_address + + state[7] = ((!tex->dcc_separate_buffer ? tex->resource.gpu_address : 0) + tex->dcc_offset + base_level_info->dcc_offset) >> 8; } diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c index 6db65be382f..5aed352f55c 100644 --- a/src/gallium/drivers/radeonsi/si_state.c +++ b/src/gallium/drivers/radeonsi/si_state.c @@ -2420,6 +2420,12 @@ static void si_emit_framebuffer_state(struct si_context *sctx, struct r600_atom RADEON_PRIO_CMASK); } + if (tex->dcc_separate_buffer) + radeon_add_to_buffer_list(&sctx->b, &sctx->b.gfx, + tex->dcc_separate_buffer, + RADEON_USAGE_READWRITE, + RADEON_PRIO_DCC); + /* Compute mutable surface parameters. */ pitch_tile_max = cb->level_info->nblk_x / 8 - 1; slice_tile_max = cb->level_info->nblk_x * @@ -2476,7 +2482,7 @@ static void si_emit_framebuffer_state(struct si_context *sctx, struct r600_atom radeon_emit(cs, tex->color_clear_value[1]); /* R_028C90_CB_COLOR0_CLEAR_WORD1 */ if (sctx->b.chip_class >= VI) /* R_028C94_CB_COLOR0_DCC_BASE */ - radeon_emit(cs, (tex->resource.gpu_address + + radeon_emit(cs, ((!tex->dcc_separate_buffer ? tex->resource.gpu_address : 0) + tex->dcc_offset + tex->surface.level[cb->base.u.tex.level].dcc_offset) >> 8); } @@ -3447,6 +3453,7 @@ static void si_query_opaque_metadata(struct r600_common_screen *rscreen, if (rscreen->info.drm_major != 3) return; + assert(rtex->dcc_separate_buffer == NULL); assert(rtex->fmask.size == 0); /* Metadata image format format version 1: |