diff --git a/src/gallium/drivers/radeonsi/si_blit.c b/src/gallium/drivers/radeonsi/si_blit.c index 3ad24c1f978..7ed27a0e892 100644 --- a/src/gallium/drivers/radeonsi/si_blit.c +++ b/src/gallium/drivers/radeonsi/si_blit.c @@ -852,11 +852,10 @@ static void si_use_compute_copy_for_float_formats(struct si_context *sctx, * lost so we need to disable DCC as well. * * This makes KHR-GL45.texture_view.view_classes pass on gfx9. - * gfx10 has the same issue, but the test doesn't use a large enough texture - * to enable DCC and fail, so it always passes. */ if (vi_dcc_enabled(tex, level) && - util_format_is_float(texture->format)) { + util_format_is_float(texture->format) && + sctx->chip_class < GFX10) { si_texture_disable_dcc(sctx, tex); } } @@ -885,7 +884,8 @@ void si_resource_copy_region(struct pipe_context *ctx, struct pipe_resource *dst if (!util_format_is_compressed(src->format) && !util_format_is_compressed(dst->format) && !util_format_is_depth_or_stencil(src->format) && src->nr_samples <= 1 && - !vi_dcc_enabled(sdst, dst_level) && + /* DCC compression from image store is enabled for GFX10+. */ + (!vi_dcc_enabled(sdst, dst_level) || sctx->chip_class >= GFX10) && !(dst->target != src->target && (src->target == PIPE_TEXTURE_1D_ARRAY || dst->target == PIPE_TEXTURE_1D_ARRAY))) { si_compute_copy_image(sctx, dst, dst_level, src, src_level, dstx, dsty, dstz, diff --git a/src/gallium/drivers/radeonsi/si_compute_blit.c b/src/gallium/drivers/radeonsi/si_compute_blit.c index f06f1209a80..dc28f1067ad 100644 --- a/src/gallium/drivers/radeonsi/si_compute_blit.c +++ b/src/gallium/drivers/radeonsi/si_compute_blit.c @@ -537,6 +537,8 @@ void si_compute_copy_image(struct si_context *sctx, struct pipe_resource *dst, u if (is_dcc_decompress) image[1].access |= SI_IMAGE_ACCESS_DCC_OFF; + else if (sctx->chip_class >= GFX10) + image[1].access |= SI_IMAGE_ACCESS_DCC_WRITE; ctx->set_shader_images(ctx, PIPE_SHADER_COMPUTE, 0, 2, 0, image); diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c index 8c8ce9e7d38..0c071f2c75d 100644 --- a/src/gallium/drivers/radeonsi/si_descriptors.c +++ b/src/gallium/drivers/radeonsi/si_descriptors.c @@ -296,7 +296,7 @@ static void si_set_buf_desc_address(struct si_resource *buf, uint64_t offset, ui void si_set_mutable_tex_desc_fields(struct si_screen *sscreen, struct si_texture *tex, const struct legacy_surf_level *base_level_info, unsigned base_level, unsigned first_level, unsigned block_width, - bool is_stencil, bool force_dcc_off, uint32_t *state) + bool is_stencil, uint16_t access, uint32_t *state) { uint64_t va, meta_va = 0; @@ -330,7 +330,7 @@ void si_set_mutable_tex_desc_fields(struct si_screen *sscreen, struct si_texture if (sscreen->info.chip_class >= GFX8) { state[6] &= C_008F28_COMPRESSION_EN; - if (!force_dcc_off && vi_dcc_enabled(tex, first_level)) { + if (!(access & SI_IMAGE_ACCESS_DCC_OFF) && vi_dcc_enabled(tex, first_level)) { meta_va = (!tex->dcc_separate_buffer ? tex->buffer.gpu_address : 0) + tex->surface.dcc_offset; @@ -363,7 +363,8 @@ void si_set_mutable_tex_desc_fields(struct si_screen *sscreen, struct si_texture state[3] |= S_00A00C_SW_MODE(tex->surface.u.gfx9.surf.swizzle_mode); } - state[6] &= C_00A018_META_DATA_ADDRESS_LO & C_00A018_META_PIPE_ALIGNED; + state[6] &= C_00A018_META_DATA_ADDRESS_LO & C_00A018_META_PIPE_ALIGNED & + C_00A018_WRITE_COMPRESS_ENABLE; if (meta_va) { struct gfx9_surf_meta_flags meta = { @@ -375,7 +376,8 @@ void si_set_mutable_tex_desc_fields(struct si_screen *sscreen, struct si_texture meta = tex->surface.u.gfx9.dcc; state[6] |= S_00A018_META_PIPE_ALIGNED(meta.pipe_aligned) | - S_00A018_META_DATA_ADDRESS_LO(meta_va >> 8); + S_00A018_META_DATA_ADDRESS_LO(meta_va >> 8) | + S_00A018_WRITE_COMPRESS_ENABLE((access & SI_IMAGE_ACCESS_DCC_WRITE) != 0); } state[7] = meta_va >> 16; @@ -465,7 +467,7 @@ static void si_set_sampler_view_desc(struct si_context *sctx, struct si_sampler_ si_set_mutable_tex_desc_fields(sctx->screen, tex, sview->base_level_info, sview->base_level, sview->base.u.tex.first_level, sview->block_width, - is_separate_stencil, false, desc); + is_separate_stencil, 0, desc); } if (!is_buffer && tex->surface.fmask_size) { @@ -716,7 +718,7 @@ static void si_set_shader_image_desc(struct si_context *ctx, const struct pipe_i if (uses_dcc && !skip_decompress && !(access & SI_IMAGE_ACCESS_DCC_OFF) && - (access & PIPE_IMAGE_ACCESS_WRITE || + ((!(access & SI_IMAGE_ACCESS_DCC_WRITE) && (access & PIPE_IMAGE_ACCESS_WRITE)) || !vi_dcc_formats_compatible(screen, res->b.b.format, view->format))) { /* If DCC can't be disabled, at least decompress it. * The decompression is relatively cheap if the surface @@ -751,8 +753,8 @@ static void si_set_shader_image_desc(struct si_context *ctx, const struct pipe_i screen, tex, false, res->b.b.target, view->format, swizzle, hw_level, hw_level, view->u.tex.first_layer, view->u.tex.last_layer, width, height, depth, desc, fmask_desc); si_set_mutable_tex_desc_fields(screen, tex, &tex->surface.u.legacy.level[level], level, level, - util_format_get_blockwidth(view->format), false, - view->access & SI_IMAGE_ACCESS_DCC_OFF, desc); + util_format_get_blockwidth(view->format), + false, view->access, desc); } } diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index 3c1b7885865..3cfa56c1d8d 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -163,6 +163,7 @@ enum si_clear_code #define SI_IMAGE_ACCESS_AS_BUFFER (1 << 7) #define SI_IMAGE_ACCESS_DCC_OFF (1 << 8) +#define SI_IMAGE_ACCESS_DCC_WRITE (1 << 9) /* Debug flags. */ enum diff --git a/src/gallium/drivers/radeonsi/si_shader_llvm_resources.c b/src/gallium/drivers/radeonsi/si_shader_llvm_resources.c index 260fafff5a2..95b389c4030 100644 --- a/src/gallium/drivers/radeonsi/si_shader_llvm_resources.c +++ b/src/gallium/drivers/radeonsi/si_shader_llvm_resources.c @@ -171,7 +171,7 @@ static LLVMValueRef si_load_image_desc(struct si_shader_context *ctx, LLVMValueR else rsrc = ac_build_load_to_sgpr(&ctx->ac, list, index); - if (desc_type == AC_DESC_IMAGE && uses_store) + if (desc_type == AC_DESC_IMAGE && uses_store && ctx->ac.chip_class <= GFX9) rsrc = force_dcc_off(ctx, rsrc); return rsrc; } diff --git a/src/gallium/drivers/radeonsi/si_state.h b/src/gallium/drivers/radeonsi/si_state.h index e77d0917a48..bbe765579b7 100644 --- a/src/gallium/drivers/radeonsi/si_state.h +++ b/src/gallium/drivers/radeonsi/si_state.h @@ -490,7 +490,7 @@ struct si_buffer_resources { void si_set_mutable_tex_desc_fields(struct si_screen *sscreen, struct si_texture *tex, const struct legacy_surf_level *base_level_info, unsigned base_level, unsigned first_level, unsigned block_width, - bool is_stencil, bool force_dcc_off, uint32_t *state); + bool is_stencil, uint16_t access, uint32_t *state); void si_update_ps_colorbuf0_slot(struct si_context *sctx); void si_get_pipe_constant_buffer(struct si_context *sctx, uint shader, uint slot, struct pipe_constant_buffer *cbuf); diff --git a/src/gallium/drivers/radeonsi/si_texture.c b/src/gallium/drivers/radeonsi/si_texture.c index 6a78ce62648..9c8c1bc4b2a 100644 --- a/src/gallium/drivers/radeonsi/si_texture.c +++ b/src/gallium/drivers/radeonsi/si_texture.c @@ -516,7 +516,7 @@ static void si_set_tex_bo_metadata(struct si_screen *sscreen, struct si_texture res->last_level, 0, is_array ? res->array_size - 1 : 0, res->width0, res->height0, res->depth0, desc, NULL); si_set_mutable_tex_desc_fields(sscreen, tex, &tex->surface.u.legacy.level[0], 0, 0, - tex->surface.blk_w, false, false, desc); + tex->surface.blk_w, false, 0, desc); ac_surface_get_umd_metadata(&sscreen->info, &tex->surface, tex->buffer.b.b.last_level + 1,