radeonsi: allocate DCC in the same backing buffer as the texture
To allow sharing textures with DCC enabled. Reviewed-by: Michel Dänzer <michel.daenzer@amd.com> Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
This commit is contained in:
@@ -222,7 +222,7 @@ struct r600_texture {
|
|||||||
struct r600_fmask_info fmask;
|
struct r600_fmask_info fmask;
|
||||||
struct r600_cmask_info cmask;
|
struct r600_cmask_info cmask;
|
||||||
struct r600_resource *cmask_buffer;
|
struct r600_resource *cmask_buffer;
|
||||||
struct r600_resource *dcc_buffer;
|
unsigned dcc_offset; /* 0 = disabled */
|
||||||
unsigned cb_color_info; /* fast clear enable bit */
|
unsigned cb_color_info; /* fast clear enable bit */
|
||||||
unsigned color_clear_value[2];
|
unsigned color_clear_value[2];
|
||||||
|
|
||||||
|
@@ -346,7 +346,6 @@ static void r600_texture_destroy(struct pipe_screen *screen,
|
|||||||
if (rtex->cmask_buffer != &rtex->resource) {
|
if (rtex->cmask_buffer != &rtex->resource) {
|
||||||
pipe_resource_reference((struct pipe_resource**)&rtex->cmask_buffer, NULL);
|
pipe_resource_reference((struct pipe_resource**)&rtex->cmask_buffer, NULL);
|
||||||
}
|
}
|
||||||
pipe_resource_reference((struct pipe_resource**)&rtex->dcc_buffer, NULL);
|
|
||||||
pb_reference(&resource->buf, NULL);
|
pb_reference(&resource->buf, NULL);
|
||||||
FREE(rtex);
|
FREE(rtex);
|
||||||
}
|
}
|
||||||
@@ -569,25 +568,6 @@ static void r600_texture_alloc_cmask_separate(struct r600_common_screen *rscreen
|
|||||||
rtex->cb_color_info |= EG_S_028C70_FAST_CLEAR(1);
|
rtex->cb_color_info |= EG_S_028C70_FAST_CLEAR(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vi_texture_alloc_dcc_separate(struct r600_common_screen *rscreen,
|
|
||||||
struct r600_texture *rtex)
|
|
||||||
{
|
|
||||||
if (rscreen->debug_flags & DBG_NO_DCC)
|
|
||||||
return;
|
|
||||||
|
|
||||||
rtex->dcc_buffer = (struct r600_resource *)
|
|
||||||
r600_aligned_buffer_create(&rscreen->b, PIPE_BIND_CUSTOM,
|
|
||||||
PIPE_USAGE_DEFAULT, rtex->surface.dcc_size, rtex->surface.dcc_alignment);
|
|
||||||
if (rtex->dcc_buffer == NULL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
r600_screen_clear_buffer(rscreen, &rtex->dcc_buffer->b.b, 0, rtex->surface.dcc_size,
|
|
||||||
0xFFFFFFFF, true);
|
|
||||||
|
|
||||||
rtex->cb_color_info |= VI_S_028C70_DCC_ENABLE(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned r600_texture_get_htile_size(struct r600_common_screen *rscreen,
|
static unsigned r600_texture_get_htile_size(struct r600_common_screen *rscreen,
|
||||||
struct r600_texture *rtex)
|
struct r600_texture *rtex)
|
||||||
{
|
{
|
||||||
@@ -722,10 +702,10 @@ void r600_print_texture_info(struct r600_texture *rtex, FILE *f)
|
|||||||
rtex->htile_buffer->buf->alignment, rtex->htile.pitch,
|
rtex->htile_buffer->buf->alignment, rtex->htile.pitch,
|
||||||
rtex->htile.height, rtex->htile.xalign, rtex->htile.yalign);
|
rtex->htile.height, rtex->htile.xalign, rtex->htile.yalign);
|
||||||
|
|
||||||
if (rtex->dcc_buffer) {
|
if (rtex->dcc_offset) {
|
||||||
fprintf(f, " DCC: size=%u, alignment=%u\n",
|
fprintf(f, " DCC: offset=%u, size=%"PRIu64", alignment=%"PRIu64"\n",
|
||||||
rtex->dcc_buffer->b.b.width0,
|
rtex->dcc_offset, rtex->surface.dcc_size,
|
||||||
rtex->dcc_buffer->buf->alignment);
|
rtex->surface.dcc_alignment);
|
||||||
for (i = 0; i <= rtex->surface.last_level; i++)
|
for (i = 0; i <= rtex->surface.last_level; i++)
|
||||||
fprintf(f, " DCCLevel[%i]: offset=%"PRIu64"\n",
|
fprintf(f, " DCCLevel[%i]: offset=%"PRIu64"\n",
|
||||||
i, rtex->surface.level[i].dcc_offset);
|
i, rtex->surface.level[i].dcc_offset);
|
||||||
@@ -823,8 +803,14 @@ r600_texture_create_object(struct pipe_screen *screen,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (rtex->surface.dcc_size)
|
|
||||||
vi_texture_alloc_dcc_separate(rscreen, rtex);
|
if (!buf && rtex->surface.dcc_size &&
|
||||||
|
!(rscreen->debug_flags & DBG_NO_DCC)) {
|
||||||
|
/* Reserve space for the DCC buffer. */
|
||||||
|
rtex->dcc_offset = align(rtex->size, rtex->surface.dcc_alignment);
|
||||||
|
rtex->size = rtex->dcc_offset + rtex->surface.dcc_size;
|
||||||
|
rtex->cb_color_info |= VI_S_028C70_DCC_ENABLE(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now create the backing buffer. */
|
/* Now create the backing buffer. */
|
||||||
@@ -846,6 +832,12 @@ r600_texture_create_object(struct pipe_screen *screen,
|
|||||||
rtex->cmask.offset, rtex->cmask.size,
|
rtex->cmask.offset, rtex->cmask.size,
|
||||||
0xCCCCCCCC, true);
|
0xCCCCCCCC, true);
|
||||||
}
|
}
|
||||||
|
if (rtex->dcc_offset) {
|
||||||
|
r600_screen_clear_buffer(rscreen, &rtex->resource.b.b,
|
||||||
|
rtex->dcc_offset,
|
||||||
|
rtex->surface.dcc_size,
|
||||||
|
0xFFFFFFFF, true);
|
||||||
|
}
|
||||||
|
|
||||||
/* Initialize the CMASK base register value. */
|
/* Initialize the CMASK base register value. */
|
||||||
rtex->cmask.base_address_reg =
|
rtex->cmask.base_address_reg =
|
||||||
@@ -1553,7 +1545,7 @@ void evergreen_do_fast_color_clear(struct r600_common_context *rctx,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tex->dcc_buffer) {
|
if (tex->dcc_offset) {
|
||||||
uint32_t reset_value;
|
uint32_t reset_value;
|
||||||
bool clear_words_needed;
|
bool clear_words_needed;
|
||||||
|
|
||||||
@@ -1562,8 +1554,9 @@ void evergreen_do_fast_color_clear(struct r600_common_context *rctx,
|
|||||||
|
|
||||||
vi_get_fast_clear_parameters(fb->cbufs[i]->format, color, &reset_value, &clear_words_needed);
|
vi_get_fast_clear_parameters(fb->cbufs[i]->format, color, &reset_value, &clear_words_needed);
|
||||||
|
|
||||||
rctx->clear_buffer(&rctx->b, &tex->dcc_buffer->b.b,
|
rctx->clear_buffer(&rctx->b, &tex->resource.b.b,
|
||||||
0, tex->surface.dcc_size, reset_value, true);
|
tex->dcc_offset, tex->surface.dcc_size,
|
||||||
|
reset_value, true);
|
||||||
|
|
||||||
if (clear_words_needed)
|
if (clear_words_needed)
|
||||||
tex->dirty_level_mask |= 1 << fb->cbufs[i]->u.tex.level;
|
tex->dirty_level_mask |= 1 << fb->cbufs[i]->u.tex.level;
|
||||||
|
@@ -243,7 +243,7 @@ void cik_sdma_copy(struct pipe_context *ctx,
|
|||||||
if (src->format != dst->format ||
|
if (src->format != dst->format ||
|
||||||
rdst->surface.nsamples > 1 || rsrc->surface.nsamples > 1 ||
|
rdst->surface.nsamples > 1 || rsrc->surface.nsamples > 1 ||
|
||||||
(rdst->dirty_level_mask | rdst->stencil_dirty_level_mask) & (1 << dst_level) ||
|
(rdst->dirty_level_mask | rdst->stencil_dirty_level_mask) & (1 << dst_level) ||
|
||||||
rdst->dcc_buffer || rsrc->dcc_buffer) {
|
rdst->dcc_offset || rsrc->dcc_offset) {
|
||||||
goto fallback;
|
goto fallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -330,7 +330,7 @@ void si_decompress_color_textures(struct si_context *sctx,
|
|||||||
assert(view);
|
assert(view);
|
||||||
|
|
||||||
tex = (struct r600_texture *)view->texture;
|
tex = (struct r600_texture *)view->texture;
|
||||||
assert(tex->cmask.size || tex->fmask.size || tex->dcc_buffer);
|
assert(tex->cmask.size || tex->fmask.size || tex->dcc_offset);
|
||||||
|
|
||||||
si_blit_decompress_color(&sctx->b.b, tex,
|
si_blit_decompress_color(&sctx->b.b, tex,
|
||||||
view->u.tex.first_level, view->u.tex.last_level,
|
view->u.tex.first_level, view->u.tex.last_level,
|
||||||
@@ -483,7 +483,7 @@ static void si_decompress_subresource(struct pipe_context *ctx,
|
|||||||
si_blit_decompress_depth_in_place(sctx, rtex, true,
|
si_blit_decompress_depth_in_place(sctx, rtex, true,
|
||||||
level, level,
|
level, level,
|
||||||
first_layer, last_layer);
|
first_layer, last_layer);
|
||||||
} else if (rtex->fmask.size || rtex->cmask.size || rtex->dcc_buffer) {
|
} else if (rtex->fmask.size || rtex->cmask.size || rtex->dcc_offset) {
|
||||||
si_blit_decompress_color(ctx, rtex, level, level,
|
si_blit_decompress_color(ctx, rtex, level, level,
|
||||||
first_layer, last_layer);
|
first_layer, last_layer);
|
||||||
}
|
}
|
||||||
@@ -712,7 +712,7 @@ static bool do_hardware_msaa_resolve(struct pipe_context *ctx,
|
|||||||
dst->surface.level[info->dst.level].mode >= RADEON_SURF_MODE_1D &&
|
dst->surface.level[info->dst.level].mode >= RADEON_SURF_MODE_1D &&
|
||||||
!(dst->surface.flags & RADEON_SURF_SCANOUT) &&
|
!(dst->surface.flags & RADEON_SURF_SCANOUT) &&
|
||||||
(!dst->cmask.size || !dst->dirty_level_mask) && /* dst cannot be fast-cleared */
|
(!dst->cmask.size || !dst->dirty_level_mask) && /* dst cannot be fast-cleared */
|
||||||
!dst->dcc_buffer) {
|
!dst->dcc_offset) {
|
||||||
si_blitter_begin(ctx, SI_COLOR_RESOLVE |
|
si_blitter_begin(ctx, SI_COLOR_RESOLVE |
|
||||||
(info->render_condition_enable ? 0 : SI_DISABLE_RENDER_COND));
|
(info->render_condition_enable ? 0 : SI_DISABLE_RENDER_COND));
|
||||||
util_blitter_custom_resolve_color(sctx->blitter,
|
util_blitter_custom_resolve_color(sctx->blitter,
|
||||||
@@ -761,7 +761,7 @@ static void si_flush_resource(struct pipe_context *ctx,
|
|||||||
|
|
||||||
assert(res->target != PIPE_BUFFER);
|
assert(res->target != PIPE_BUFFER);
|
||||||
|
|
||||||
if (!rtex->is_depth && (rtex->cmask.size || rtex->dcc_buffer)) {
|
if (!rtex->is_depth && (rtex->cmask.size || rtex->dcc_offset)) {
|
||||||
si_blit_decompress_color(ctx, rtex, 0, res->last_level,
|
si_blit_decompress_color(ctx, rtex, 0, res->last_level,
|
||||||
0, util_max_layer(res, 0));
|
0, util_max_layer(res, 0));
|
||||||
}
|
}
|
||||||
|
@@ -158,12 +158,6 @@ static void si_sampler_view_add_buffers(struct si_context *sctx,
|
|||||||
rview->resource, RADEON_USAGE_READ,
|
rview->resource, RADEON_USAGE_READ,
|
||||||
r600_get_sampler_view_priority(rview->resource));
|
r600_get_sampler_view_priority(rview->resource));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rview->dcc_buffer && rview->dcc_buffer != rview->resource) {
|
|
||||||
radeon_add_to_buffer_list(&sctx->b, &sctx->b.gfx,
|
|
||||||
rview->dcc_buffer, RADEON_USAGE_READ,
|
|
||||||
RADEON_PRIO_DCC);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void si_sampler_views_begin_new_cs(struct si_context *sctx,
|
static void si_sampler_views_begin_new_cs(struct si_context *sctx,
|
||||||
@@ -263,7 +257,7 @@ static void si_set_sampler_views(struct pipe_context *ctx,
|
|||||||
samplers->depth_texture_mask &= ~(1 << slot);
|
samplers->depth_texture_mask &= ~(1 << slot);
|
||||||
}
|
}
|
||||||
if (rtex->cmask.size || rtex->fmask.size ||
|
if (rtex->cmask.size || rtex->fmask.size ||
|
||||||
(rtex->dcc_buffer && rtex->dirty_level_mask)) {
|
(rtex->dcc_offset && rtex->dirty_level_mask)) {
|
||||||
samplers->compressed_colortex_mask |= 1 << slot;
|
samplers->compressed_colortex_mask |= 1 << slot;
|
||||||
} else {
|
} else {
|
||||||
samplers->compressed_colortex_mask &= ~(1 << slot);
|
samplers->compressed_colortex_mask &= ~(1 << slot);
|
||||||
|
@@ -249,7 +249,7 @@ void si_dma_copy(struct pipe_context *ctx,
|
|||||||
(rdst->dirty_level_mask | rdst->stencil_dirty_level_mask) & (1 << dst_level) ||
|
(rdst->dirty_level_mask | rdst->stencil_dirty_level_mask) & (1 << dst_level) ||
|
||||||
rdst->cmask.size || rdst->fmask.size ||
|
rdst->cmask.size || rdst->fmask.size ||
|
||||||
rsrc->cmask.size || rsrc->fmask.size ||
|
rsrc->cmask.size || rsrc->fmask.size ||
|
||||||
rdst->dcc_buffer || rsrc->dcc_buffer) {
|
rdst->dcc_offset || rsrc->dcc_offset) {
|
||||||
goto fallback;
|
goto fallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -121,7 +121,6 @@ struct si_sampler_view {
|
|||||||
struct pipe_sampler_view base;
|
struct pipe_sampler_view base;
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
struct r600_resource *resource;
|
struct r600_resource *resource;
|
||||||
struct r600_resource *dcc_buffer;
|
|
||||||
/* [0..7] = image descriptor
|
/* [0..7] = image descriptor
|
||||||
* [4..7] = buffer descriptor */
|
* [4..7] = buffer descriptor */
|
||||||
uint32_t state[8];
|
uint32_t state[8];
|
||||||
|
@@ -2318,9 +2318,8 @@ static void si_initialize_color_surface(struct si_context *sctx,
|
|||||||
surf->cb_color_info = color_info;
|
surf->cb_color_info = color_info;
|
||||||
surf->cb_color_attrib = color_attrib;
|
surf->cb_color_attrib = color_attrib;
|
||||||
|
|
||||||
if (sctx->b.chip_class >= VI && rtex->dcc_buffer) {
|
if (sctx->b.chip_class >= VI && rtex->dcc_offset) {
|
||||||
unsigned max_uncompressed_block_size = 2;
|
unsigned max_uncompressed_block_size = 2;
|
||||||
uint64_t dcc_offset = rtex->surface.level[level].dcc_offset;
|
|
||||||
|
|
||||||
if (rtex->surface.nsamples > 1) {
|
if (rtex->surface.nsamples > 1) {
|
||||||
if (rtex->surface.bpe == 1)
|
if (rtex->surface.bpe == 1)
|
||||||
@@ -2331,7 +2330,9 @@ static void si_initialize_color_surface(struct si_context *sctx,
|
|||||||
|
|
||||||
surf->cb_dcc_control = S_028C78_MAX_UNCOMPRESSED_BLOCK_SIZE(max_uncompressed_block_size) |
|
surf->cb_dcc_control = S_028C78_MAX_UNCOMPRESSED_BLOCK_SIZE(max_uncompressed_block_size) |
|
||||||
S_028C78_INDEPENDENT_64B_BLOCKS(1);
|
S_028C78_INDEPENDENT_64B_BLOCKS(1);
|
||||||
surf->cb_dcc_base = (rtex->dcc_buffer->gpu_address + dcc_offset) >> 8;
|
surf->cb_dcc_base = (rtex->resource.gpu_address +
|
||||||
|
rtex->dcc_offset +
|
||||||
|
rtex->surface.level[level].dcc_offset) >> 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rtex->fmask.size) {
|
if (rtex->fmask.size) {
|
||||||
@@ -2670,12 +2671,6 @@ static void si_emit_framebuffer_state(struct si_context *sctx, struct r600_atom
|
|||||||
RADEON_PRIO_CMASK);
|
RADEON_PRIO_CMASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tex->dcc_buffer && tex->dcc_buffer != &tex->resource) {
|
|
||||||
radeon_add_to_buffer_list(&sctx->b, &sctx->b.gfx,
|
|
||||||
tex->dcc_buffer, RADEON_USAGE_READWRITE,
|
|
||||||
RADEON_PRIO_DCC);
|
|
||||||
}
|
|
||||||
|
|
||||||
radeon_set_context_reg_seq(cs, R_028C60_CB_COLOR0_BASE + i * 0x3C,
|
radeon_set_context_reg_seq(cs, R_028C60_CB_COLOR0_BASE + i * 0x3C,
|
||||||
sctx->b.chip_class >= VI ? 14 : 13);
|
sctx->b.chip_class >= VI ? 14 : 13);
|
||||||
radeon_emit(cs, cb->cb_color_base); /* R_028C60_CB_COLOR0_BASE */
|
radeon_emit(cs, cb->cb_color_base); /* R_028C60_CB_COLOR0_BASE */
|
||||||
@@ -3069,13 +3064,13 @@ si_create_sampler_view_custom(struct pipe_context *ctx,
|
|||||||
view->state[5] = (S_008F24_BASE_ARRAY(state->u.tex.first_layer) |
|
view->state[5] = (S_008F24_BASE_ARRAY(state->u.tex.first_layer) |
|
||||||
S_008F24_LAST_ARRAY(last_layer));
|
S_008F24_LAST_ARRAY(last_layer));
|
||||||
|
|
||||||
if (tmp->dcc_buffer) {
|
if (tmp->dcc_offset) {
|
||||||
uint64_t dcc_offset = surflevel[base_level].dcc_offset;
|
|
||||||
unsigned swap = r600_translate_colorswap(pipe_format);
|
unsigned swap = r600_translate_colorswap(pipe_format);
|
||||||
|
|
||||||
view->state[6] = S_008F28_COMPRESSION_EN(1) | S_008F28_ALPHA_IS_ON_MSB(swap <= 1);
|
view->state[6] = S_008F28_COMPRESSION_EN(1) | S_008F28_ALPHA_IS_ON_MSB(swap <= 1);
|
||||||
view->state[7] = (tmp->dcc_buffer->gpu_address + dcc_offset) >> 8;
|
view->state[7] = (tmp->resource.gpu_address +
|
||||||
view->dcc_buffer = tmp->dcc_buffer;
|
tmp->dcc_offset +
|
||||||
|
surflevel[base_level].dcc_offset) >> 8;
|
||||||
} else {
|
} else {
|
||||||
view->state[6] = 0;
|
view->state[6] = 0;
|
||||||
view->state[7] = 0;
|
view->state[7] = 0;
|
||||||
|
Reference in New Issue
Block a user