aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/radeon/r600_texture.c14
-rw-r--r--src/gallium/drivers/radeon/radeon_winsys.h6
-rw-r--r--src/gallium/drivers/radeonsi/si_blit.c4
-rw-r--r--src/gallium/drivers/radeonsi/si_descriptors.c4
-rw-r--r--src/gallium/drivers/radeonsi/si_state.c2
-rw-r--r--src/gallium/winsys/amdgpu/drm/amdgpu_surface.c4
6 files changed, 19 insertions, 15 deletions
diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c
index bc981da4bed..46281cbd0e5 100644
--- a/src/gallium/drivers/radeon/r600_texture.c
+++ b/src/gallium/drivers/radeon/r600_texture.c
@@ -73,8 +73,8 @@ bool r600_prepare_for_dma_blit(struct r600_common_context *rctx,
* src: Use the 3D path. DCC decompression is expensive.
* dst: Use the 3D path to compress the pixels with DCC.
*/
- if ((rsrc->dcc_offset && rsrc->surface.level[src_level].dcc_enabled) ||
- (rdst->dcc_offset && rdst->surface.level[dst_level].dcc_enabled))
+ if ((rsrc->dcc_offset && src_level < rsrc->surface.num_dcc_levels) ||
+ (rdst->dcc_offset && dst_level < rdst->surface.num_dcc_levels))
return false;
/* CMASK as:
@@ -940,7 +940,7 @@ void r600_print_texture_info(struct r600_texture *rtex, FILE *f)
for (i = 0; i <= rtex->resource.b.b.last_level; i++)
fprintf(f, " DCCLevel[%i]: enabled=%u, offset=%"PRIu64", "
"fast_clear_size=%"PRIu64"\n",
- i, rtex->surface.level[i].dcc_enabled,
+ i, i < rtex->surface.num_dcc_levels,
rtex->surface.level[i].dcc_offset,
rtex->surface.level[i].dcc_fast_clear_size);
}
@@ -1744,7 +1744,7 @@ void vi_dcc_disable_if_incompatible_format(struct r600_common_context *rctx,
struct r600_texture *rtex = (struct r600_texture *)tex;
if (rtex->dcc_offset &&
- rtex->surface.level[level].dcc_enabled &&
+ level < rtex->surface.num_dcc_levels &&
!vi_dcc_formats_compatible(tex->format, view_format))
if (!r600_texture_disable_dcc(rctx, (struct r600_texture*)tex))
rctx->decompress_dcc(&rctx->b, rtex);
@@ -2096,7 +2096,7 @@ static void vi_separate_dcc_try_enable(struct r600_common_context *rctx,
if (!vi_should_enable_separate_dcc(tex))
return; /* stats show that DCC decompression is too expensive */
- assert(tex->surface.level[0].dcc_enabled);
+ assert(tex->surface.num_dcc_levels);
assert(!tex->dcc_separate_buffer);
r600_texture_discard_cmask(rctx->screen, tex);
@@ -2311,7 +2311,7 @@ void vi_dcc_clear_level(struct r600_common_context *rctx,
struct pipe_resource *dcc_buffer;
uint64_t dcc_offset;
- assert(rtex->dcc_offset && rtex->surface.level[level].dcc_enabled);
+ assert(rtex->dcc_offset && level < rtex->surface.num_dcc_levels);
if (rtex->dcc_separate_buffer) {
dcc_buffer = &rtex->dcc_separate_buffer->b.b;
@@ -2483,7 +2483,7 @@ void evergreen_do_fast_color_clear(struct r600_common_context *rctx,
}
/* Try to clear DCC first, otherwise try CMASK. */
- if (tex->dcc_offset && tex->surface.level[0].dcc_enabled) {
+ if (tex->dcc_offset && tex->surface.num_dcc_levels) {
uint32_t reset_value;
bool clear_words_needed;
diff --git a/src/gallium/drivers/radeon/radeon_winsys.h b/src/gallium/drivers/radeon/radeon_winsys.h
index 2330cddf631..f5b9f105836 100644
--- a/src/gallium/drivers/radeon/radeon_winsys.h
+++ b/src/gallium/drivers/radeon/radeon_winsys.h
@@ -283,7 +283,6 @@ struct radeon_surf_level {
uint16_t nblk_y;
uint32_t pitch_bytes;
enum radeon_surf_mode mode;
- bool dcc_enabled;
};
struct radeon_surf {
@@ -291,6 +290,11 @@ struct radeon_surf {
unsigned blk_w:4;
unsigned blk_h:4;
unsigned bpe:5;
+ /* Number of mipmap levels where DCC is enabled starting from level 0.
+ * Non-zero levels may be disabled due to alignment constraints, but not
+ * the first level.
+ */
+ unsigned num_dcc_levels:4;
uint32_t flags;
/* These are return values. Some of them can be set by the caller, but
diff --git a/src/gallium/drivers/radeonsi/si_blit.c b/src/gallium/drivers/radeonsi/si_blit.c
index db41f565a94..0f46d71ddaf 100644
--- a/src/gallium/drivers/radeonsi/si_blit.c
+++ b/src/gallium/drivers/radeonsi/si_blit.c
@@ -429,7 +429,7 @@ static void si_blit_decompress_color(struct pipe_context *ctx,
/* disable levels without DCC */
for (int i = first_level; i <= last_level; i++) {
if (!rtex->dcc_offset ||
- !rtex->surface.level[i].dcc_enabled)
+ i >= rtex->surface.num_dcc_levels)
level_mask &= ~(1 << i);
}
} else if (rtex->fmask.size) {
@@ -1029,7 +1029,7 @@ static bool do_hardware_msaa_resolve(struct pipe_context *ctx,
* This is still the fastest codepath even with this clear.
*/
if (dst->dcc_offset &&
- dst->surface.level[info->dst.level].dcc_enabled) {
+ info->dst.level < dst->surface.num_dcc_levels) {
vi_dcc_clear_level(&sctx->b, dst, info->dst.level,
0xFFFFFFFF);
dst->dirty_level_mask &= ~(1 << info->dst.level);
diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c
index 19cae65e75e..9358542ac78 100644
--- a/src/gallium/drivers/radeonsi/si_descriptors.c
+++ b/src/gallium/drivers/radeonsi/si_descriptors.c
@@ -394,7 +394,7 @@ void si_set_mutable_tex_desc_fields(struct r600_texture *tex,
is_stencil));
state[4] |= S_008F20_PITCH(pitch - 1);
- if (tex->dcc_offset && tex->surface.level[first_level].dcc_enabled) {
+ if (tex->dcc_offset && first_level < tex->surface.num_dcc_levels) {
state[6] |= S_008F28_COMPRESSION_EN(1);
state[7] = ((!tex->dcc_separate_buffer ? tex->resource.gpu_address : 0) +
tex->dcc_offset +
@@ -669,7 +669,7 @@ static void si_set_shader_image(struct si_context *ctx,
unsigned level = view->u.tex.level;
unsigned width, height, depth;
bool uses_dcc = tex->dcc_offset &&
- tex->surface.level[level].dcc_enabled;
+ level < tex->surface.num_dcc_levels;
assert(!tex->is_depth);
assert(tex->fmask.size == 0);
diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
index 0633b64de33..bf89d8bf1f2 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -2500,7 +2500,7 @@ static void si_emit_framebuffer_state(struct si_context *sctx, struct r600_atom
cb_color_info = cb->cb_color_info | tex->cb_color_info;
- if (tex->dcc_offset && cb->level_info->dcc_enabled) {
+ if (tex->dcc_offset && cb->base.u.tex.level < tex->surface.num_dcc_levels) {
bool is_msaa_resolve_dst = state->cbufs[0] &&
state->cbufs[0]->texture->nr_samples > 1 &&
state->cbufs[1] == &cb->base &&
diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c b/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c
index 45edcc28734..8c57287f073 100644
--- a/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c
+++ b/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c
@@ -218,7 +218,6 @@ static int compute_level(struct amdgpu_winsys *ws,
/* Clear DCC fields at the beginning. */
surf_level->dcc_offset = 0;
- surf_level->dcc_enabled = false;
/* The previous level's flag tells us if we can use DCC for this level. */
if (AddrSurfInfoIn->flags.dccCompatible &&
@@ -236,7 +235,7 @@ static int compute_level(struct amdgpu_winsys *ws,
if (ret == ADDR_OK) {
surf_level->dcc_offset = surf->dcc_size;
surf_level->dcc_fast_clear_size = AddrDccOut->dccFastClearSize;
- surf_level->dcc_enabled = true;
+ surf->num_dcc_levels = level + 1;
surf->dcc_size = surf_level->dcc_offset + AddrDccOut->dccRamSize;
surf->dcc_alignment = MAX2(surf->dcc_alignment, AddrDccOut->dccRamBaseAlign);
}
@@ -488,6 +487,7 @@ static int amdgpu_surface_init(struct radeon_winsys *rws,
}
}
+ surf->num_dcc_levels = 0;
surf->surf_size = 0;
surf->dcc_size = 0;
surf->dcc_alignment = 1;