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.
*/
if (!r600_can_disable_dcc(rtex))
return false;
+ assert(rtex->dcc_separate_buffer == NULL);
+
/* Disable DCC. */
rtex->dcc_offset = 0;
r600_resource_reference(&rtex->cmask_buffer, NULL);
}
pb_reference(&resource->buf, NULL);
+ r600_resource_reference(&rtex->dcc_separate_buffer, NULL);
FREE(rtex);
}
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);
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,
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;
}
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 *
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);
}
if (rscreen->info.drm_major != 3)
return;
+ assert(rtex->dcc_separate_buffer == NULL);
assert(rtex->fmask.size == 0);
/* Metadata image format format version 1: