From: Marek Olšák <marek.ol...@amd.com> GFX9 is more complicated and needs a compute shader that we should just copy from amdvlk. --- src/gallium/drivers/radeonsi/si_clear.c | 17 ++++++++++++----- src/gallium/drivers/radeonsi/si_state.c | 16 ++++++++++++---- 2 files changed, 24 insertions(+), 9 deletions(-)
diff --git a/src/gallium/drivers/radeonsi/si_clear.c b/src/gallium/drivers/radeonsi/si_clear.c index 4e05d9bf5b2..b08a9558b4d 100644 --- a/src/gallium/drivers/radeonsi/si_clear.c +++ b/src/gallium/drivers/radeonsi/si_clear.c @@ -362,33 +362,40 @@ static void si_do_fast_color_clear(struct si_context *sctx, unsigned clear_bit = PIPE_CLEAR_COLOR0 << i; if (!fb->cbufs[i]) continue; /* if this colorbuffer is not being cleared */ if (!(*buffers & clear_bit)) continue; unsigned level = fb->cbufs[i]->u.tex.level; + if (level > 0) + continue; + tex = (struct r600_texture *)fb->cbufs[i]->texture; + /* TODO: GFX9: Implement DCC fast clear for level 0 of + * mipmapped textures. Mipmapped DCC has to clear a rectangular + * area of DCC for level 0 (because the whole miptree is + * organized in a 2D plane). + */ + if (sctx->chip_class >= GFX9 && + tex->resource.b.b.last_level > 0) + continue; + /* the clear is allowed if all layers are bound */ if (fb->cbufs[i]->u.tex.first_layer != 0 || fb->cbufs[i]->u.tex.last_layer != util_max_layer(&tex->resource.b.b, 0)) { continue; } - /* cannot clear mipmapped textures */ - if (fb->cbufs[i]->texture->last_level != 0) { - continue; - } - /* only supported on tiled surfaces */ if (tex->surface.is_linear) { continue; } /* shared textures can't use fast clear without an explicit flush, * because there is no way to communicate the clear color among * all clients */ if (tex->resource.b.is_shared && diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c index 3faf36f2470..26f61afcab0 100644 --- a/src/gallium/drivers/radeonsi/si_state.c +++ b/src/gallium/drivers/radeonsi/si_state.c @@ -2956,21 +2956,21 @@ static void si_emit_framebuffer_state(struct si_context *sctx, struct r600_atom { struct radeon_winsys_cs *cs = sctx->gfx_cs; struct pipe_framebuffer_state *state = &sctx->framebuffer.state; unsigned i, nr_cbufs = state->nr_cbufs; struct r600_texture *tex = NULL; struct r600_surface *cb = NULL; unsigned cb_color_info = 0; /* Colorbuffers. */ for (i = 0; i < nr_cbufs; i++) { - uint64_t cb_color_base, cb_color_fmask, cb_dcc_base; + uint64_t cb_color_base, cb_color_fmask, cb_color_cmask, cb_dcc_base; unsigned cb_color_attrib; if (!(sctx->framebuffer.dirty_cbufs & (1 << i))) continue; cb = (struct r600_surface*)state->cbufs[i]; if (!cb) { radeon_set_context_reg(cs, R_028C70_CB_COLOR0_INFO + i * 0x3C, S_028C70_FORMAT(V_028C70_COLOR_INVALID)); continue; @@ -2991,24 +2991,28 @@ static void si_emit_framebuffer_state(struct si_context *sctx, struct r600_atom if (tex->dcc_separate_buffer) radeon_add_to_buffer_list(sctx, sctx->gfx_cs, tex->dcc_separate_buffer, RADEON_USAGE_READWRITE, RADEON_PRIO_DCC); /* Compute mutable surface parameters. */ cb_color_base = tex->resource.gpu_address >> 8; cb_color_fmask = 0; + cb_color_cmask = tex->cmask.base_address_reg; cb_dcc_base = 0; cb_color_info = cb->cb_color_info | tex->cb_color_info; cb_color_attrib = cb->cb_color_attrib; + if (cb->base.u.tex.level > 0) + cb_color_info &= C_028C70_FAST_CLEAR; + if (tex->fmask.size) { cb_color_fmask = (tex->resource.gpu_address + tex->fmask.offset) >> 8; cb_color_fmask |= tex->fmask.tile_swizzle; } /* Set up DCC. */ if (vi_dcc_enabled(tex, cb->base.u.tex.level)) { bool is_msaa_resolve_dst = state->cbufs[0] && state->cbufs[0]->texture->nr_samples > 1 && state->cbufs[1] == &cb->base && @@ -3028,35 +3032,37 @@ static void si_emit_framebuffer_state(struct si_context *sctx, struct r600_atom if (tex->dcc_offset) meta = tex->surface.u.gfx9.dcc; else meta = tex->surface.u.gfx9.cmask; /* Set mutable surface parameters. */ cb_color_base += tex->surface.u.gfx9.surf_offset >> 8; cb_color_base |= tex->surface.tile_swizzle; if (!tex->fmask.size) cb_color_fmask = cb_color_base; + if (cb->base.u.tex.level > 0) + cb_color_cmask = cb_color_base; cb_color_attrib |= S_028C74_COLOR_SW_MODE(tex->surface.u.gfx9.surf.swizzle_mode) | S_028C74_FMASK_SW_MODE(tex->surface.u.gfx9.fmask.swizzle_mode) | S_028C74_RB_ALIGNED(meta.rb_aligned) | S_028C74_PIPE_ALIGNED(meta.pipe_aligned); radeon_set_context_reg_seq(cs, R_028C60_CB_COLOR0_BASE + i * 0x3C, 15); radeon_emit(cs, cb_color_base); /* CB_COLOR0_BASE */ radeon_emit(cs, S_028C64_BASE_256B(cb_color_base >> 32)); /* CB_COLOR0_BASE_EXT */ radeon_emit(cs, cb->cb_color_attrib2); /* CB_COLOR0_ATTRIB2 */ radeon_emit(cs, cb->cb_color_view); /* CB_COLOR0_VIEW */ radeon_emit(cs, cb_color_info); /* CB_COLOR0_INFO */ radeon_emit(cs, cb_color_attrib); /* CB_COLOR0_ATTRIB */ radeon_emit(cs, cb->cb_dcc_control); /* CB_COLOR0_DCC_CONTROL */ - radeon_emit(cs, tex->cmask.base_address_reg); /* CB_COLOR0_CMASK */ - radeon_emit(cs, S_028C80_BASE_256B(tex->cmask.base_address_reg >> 32)); /* CB_COLOR0_CMASK_BASE_EXT */ + radeon_emit(cs, cb_color_cmask); /* CB_COLOR0_CMASK */ + radeon_emit(cs, S_028C80_BASE_256B(cb_color_cmask >> 32)); /* CB_COLOR0_CMASK_BASE_EXT */ radeon_emit(cs, cb_color_fmask); /* CB_COLOR0_FMASK */ radeon_emit(cs, S_028C88_BASE_256B(cb_color_fmask >> 32)); /* CB_COLOR0_FMASK_BASE_EXT */ radeon_emit(cs, tex->color_clear_value[0]); /* CB_COLOR0_CLEAR_WORD0 */ radeon_emit(cs, tex->color_clear_value[1]); /* CB_COLOR0_CLEAR_WORD1 */ radeon_emit(cs, cb_dcc_base); /* CB_COLOR0_DCC_BASE */ radeon_emit(cs, S_028C98_BASE_256B(cb_dcc_base >> 32)); /* CB_COLOR0_DCC_BASE_EXT */ radeon_set_context_reg(cs, R_0287A0_CB_MRT0_EPITCH + i * 4, S_0287A0_EPITCH(tex->surface.u.gfx9.surf.epitch)); } else { @@ -3066,20 +3072,22 @@ static void si_emit_framebuffer_state(struct si_context *sctx, struct r600_atom unsigned pitch_tile_max, slice_tile_max, tile_mode_index; unsigned cb_color_pitch, cb_color_slice, cb_color_fmask_slice; cb_color_base += level_info->offset >> 8; /* Only macrotiled modes can set tile swizzle. */ if (level_info->mode == RADEON_SURF_MODE_2D) cb_color_base |= tex->surface.tile_swizzle; if (!tex->fmask.size) cb_color_fmask = cb_color_base; + if (cb->base.u.tex.level > 0) + cb_color_cmask = cb_color_base; if (cb_dcc_base) cb_dcc_base += level_info->dcc_offset >> 8; pitch_tile_max = level_info->nblk_x / 8 - 1; slice_tile_max = level_info->nblk_x * level_info->nblk_y / 64 - 1; tile_mode_index = si_tile_mode_index(tex, cb->base.u.tex.level, false); cb_color_attrib |= S_028C74_TILE_MODE_INDEX(tile_mode_index); cb_color_pitch = S_028C64_TILE_MAX(pitch_tile_max); @@ -3100,21 +3108,21 @@ static void si_emit_framebuffer_state(struct si_context *sctx, struct r600_atom radeon_set_context_reg_seq(cs, R_028C60_CB_COLOR0_BASE + i * 0x3C, sctx->chip_class >= VI ? 14 : 13); radeon_emit(cs, cb_color_base); /* CB_COLOR0_BASE */ radeon_emit(cs, cb_color_pitch); /* CB_COLOR0_PITCH */ radeon_emit(cs, cb_color_slice); /* CB_COLOR0_SLICE */ radeon_emit(cs, cb->cb_color_view); /* CB_COLOR0_VIEW */ radeon_emit(cs, cb_color_info); /* CB_COLOR0_INFO */ radeon_emit(cs, cb_color_attrib); /* CB_COLOR0_ATTRIB */ radeon_emit(cs, cb->cb_dcc_control); /* CB_COLOR0_DCC_CONTROL */ - radeon_emit(cs, tex->cmask.base_address_reg); /* CB_COLOR0_CMASK */ + radeon_emit(cs, cb_color_cmask); /* CB_COLOR0_CMASK */ radeon_emit(cs, tex->cmask.slice_tile_max); /* CB_COLOR0_CMASK_SLICE */ radeon_emit(cs, cb_color_fmask); /* CB_COLOR0_FMASK */ radeon_emit(cs, cb_color_fmask_slice); /* CB_COLOR0_FMASK_SLICE */ radeon_emit(cs, tex->color_clear_value[0]); /* CB_COLOR0_CLEAR_WORD0 */ radeon_emit(cs, tex->color_clear_value[1]); /* CB_COLOR0_CLEAR_WORD1 */ if (sctx->chip_class >= VI) /* R_028C94_CB_COLOR0_DCC_BASE */ radeon_emit(cs, cb_dcc_base); } } -- 2.17.0 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev