From: Marek Olšák Date: Thu, 6 Mar 2014 01:14:42 +0000 (+0100) Subject: r600g,radeonsi: move CMASK register values from r600_surface to r600_texture X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=d3c1be530a9e13378b66fb1ff8760ba0faa1a260;p=mesa.git r600g,radeonsi: move CMASK register values from r600_surface to r600_texture When doing fast clear for single-sample color buffers for the first time, a CMASK buffer has to be allocated and the CMASK state in all pipe_surfaces referencing the color buffer must be updated. Updating all surfaces is kinda silly, so let's move the values to r600_texture instead. This is only for Evergreen and later. R600-R700 don't have fast clear. Reviewed-by: Michel Dänzer --- diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index d0291ff4843..dca7c58d415 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -964,8 +964,6 @@ void evergreen_init_color_surface_rat(struct r600_context *rctx, util_range_add(&r600_resource(pipe_buffer)->valid_buffer_range, 0, pipe_buffer->width0); - surf->cb_color_cmask = surf->cb_color_base; - surf->cb_color_cmask_slice = 0; surf->cb_color_fmask = surf->cb_color_base; surf->cb_color_fmask_slice = 0; } @@ -1133,9 +1131,6 @@ void evergreen_init_color_surface(struct r600_context *rctx, if (rtex->fmask.size) { color_info |= S_028C70_COMPRESSION(1); } - if (rtex->cmask.size) { - color_info |= S_028C70_FAST_CLEAR(1); - } base_offset = r600_resource_va(rctx->b.b.screen, pipe_tex); @@ -1152,14 +1147,7 @@ void evergreen_init_color_surface(struct r600_context *rctx, } else { surf->cb_color_fmask = surf->cb_color_base; } - if (rtex->cmask.size) { - uint64_t va = r600_resource_va(rctx->b.b.screen, &rtex->cmask_buffer->b.b); - surf->cb_color_cmask = (va + rtex->cmask.offset) >> 8; - } else { - surf->cb_color_cmask = surf->cb_color_base; - } surf->cb_color_fmask_slice = S_028C88_TILE_MAX(rtex->fmask.slice_tile_max); - surf->cb_color_cmask_slice = S_028C80_TILE_MAX(rtex->cmask.slice_tile_max); surf->color_initialized = true; } @@ -1547,6 +1535,8 @@ static void evergreen_emit_framebuffer_state(struct r600_context *rctx, struct r struct pipe_framebuffer_state *state = &rctx->framebuffer.state; unsigned nr_cbufs = state->nr_cbufs; unsigned i, tl, br; + struct r600_texture *tex = NULL; + struct r600_surface *cb = NULL; /* XXX support more colorbuffers once we need them */ assert(nr_cbufs <= 8); @@ -1555,10 +1545,9 @@ static void evergreen_emit_framebuffer_state(struct r600_context *rctx, struct r /* Colorbuffers. */ for (i = 0; i < nr_cbufs; i++) { - struct r600_surface *cb = (struct r600_surface*)state->cbufs[i]; - struct r600_texture *tex; unsigned reloc, cmask_reloc; + cb = (struct r600_surface*)state->cbufs[i]; if (!cb) { r600_write_context_reg(cs, R_028C70_CB_COLOR0_INFO + i * 0x3C, S_028C70_FORMAT(V_028C70_COLOR_INVALID)); @@ -1587,11 +1576,11 @@ static void evergreen_emit_framebuffer_state(struct r600_context *rctx, struct r radeon_emit(cs, cb->cb_color_pitch); /* R_028C64_CB_COLOR0_PITCH */ radeon_emit(cs, cb->cb_color_slice); /* R_028C68_CB_COLOR0_SLICE */ radeon_emit(cs, cb->cb_color_view); /* R_028C6C_CB_COLOR0_VIEW */ - radeon_emit(cs, cb->cb_color_info); /* R_028C70_CB_COLOR0_INFO */ + radeon_emit(cs, cb->cb_color_info | tex->cb_color_info); /* R_028C70_CB_COLOR0_INFO */ radeon_emit(cs, cb->cb_color_attrib); /* R_028C74_CB_COLOR0_ATTRIB */ radeon_emit(cs, cb->cb_color_dim); /* R_028C78_CB_COLOR0_DIM */ - radeon_emit(cs, cb->cb_color_cmask); /* R_028C7C_CB_COLOR0_CMASK */ - radeon_emit(cs, cb->cb_color_cmask_slice); /* R_028C80_CB_COLOR0_CMASK_SLICE */ + radeon_emit(cs, tex->cmask.base_address_reg); /* R_028C7C_CB_COLOR0_CMASK */ + radeon_emit(cs, tex->cmask.slice_tile_max); /* R_028C80_CB_COLOR0_CMASK_SLICE */ radeon_emit(cs, cb->cb_color_fmask); /* R_028C84_CB_COLOR0_FMASK */ radeon_emit(cs, cb->cb_color_fmask_slice); /* R_028C88_CB_COLOR0_FMASK_SLICE */ radeon_emit(cs, tex->color_clear_value[0]); /* R_028C8C_CB_COLOR0_CLEAR_WORD0 */ @@ -1617,7 +1606,7 @@ static void evergreen_emit_framebuffer_state(struct r600_context *rctx, struct r /* set CB_COLOR1_INFO for possible dual-src blending */ if (i == 1 && state->cbufs[0]) { r600_write_context_reg(cs, R_028C70_CB_COLOR0_INFO + 1 * 0x3C, - ((struct r600_surface*)state->cbufs[0])->cb_color_info); + cb->cb_color_info | tex->cb_color_info); if (!rctx->keep_tiling_flags) { unsigned reloc = r600_context_bo_reloc(&rctx->b, diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c index dc19b30bda2..e0f3373ce05 100644 --- a/src/gallium/drivers/r600/r600_blit.c +++ b/src/gallium/drivers/r600/r600_blit.c @@ -408,27 +408,6 @@ static void evergreen_set_clear_color(struct pipe_surface *cbuf, memcpy(clear_value, &uc, 2 * sizeof(uint32_t)); } -static void evergreen_check_alloc_cmask(struct pipe_context *ctx, - struct pipe_surface *cbuf) -{ - struct r600_context *rctx = (struct r600_context *)ctx; - struct r600_texture *tex = (struct r600_texture *)cbuf->texture; - struct r600_surface *surf = (struct r600_surface *)cbuf; - - if (tex->cmask_buffer) - return; - - r600_texture_init_cmask(&rctx->screen->b, tex); - - /* update colorbuffer state bits */ - if (tex->cmask_buffer != NULL) { - uint64_t va = r600_resource_va(rctx->b.b.screen, &tex->cmask_buffer->b.b); - surf->cb_color_cmask = va >> 8; - surf->cb_color_cmask_slice = S_028C80_TILE_MAX(tex->cmask.slice_tile_max); - surf->cb_color_info |= S_028C70_FAST_CLEAR(1); - } -} - static void r600_try_fast_color_clear(struct r600_context *rctx, unsigned *buffers, const union pipe_color_union *color) { @@ -470,7 +449,7 @@ static void r600_try_fast_color_clear(struct r600_context *rctx, unsigned *buffe } /* ensure CMASK is enabled */ - evergreen_check_alloc_cmask(&rctx->b.b, fb->cbufs[i]); + r600_texture_alloc_cmask_separate(&rctx->screen->b, tex); if (tex->cmask.size == 0) { continue; } diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h index 672097ddb90..5808ec30b6a 100644 --- a/src/gallium/drivers/radeon/r600_pipe_common.h +++ b/src/gallium/drivers/radeon/r600_pipe_common.h @@ -149,6 +149,7 @@ struct r600_cmask_info { unsigned size; unsigned alignment; unsigned slice_tile_max; + unsigned base_address_reg; }; struct r600_texture { @@ -166,6 +167,7 @@ struct r600_texture { struct r600_fmask_info fmask; struct r600_cmask_info cmask; struct r600_resource *cmask_buffer; + unsigned cb_color_info; /* fast clear enable bit */ unsigned color_clear_value[2]; /* Depth buffer compression and fast clear. */ @@ -197,8 +199,7 @@ struct r600_surface { unsigned cb_color_attrib; /* EG and later */ unsigned cb_color_fmask; /* CB_COLORn_FMASK (EG and later) or CB_COLORn_FRAG (r600) */ unsigned cb_color_fmask_slice; /* EG and later */ - unsigned cb_color_cmask; /* CB_COLORn_CMASK (EG and later) or CB_COLORn_TILE (r600) */ - unsigned cb_color_cmask_slice; /* EG and later */ + unsigned cb_color_cmask; /* CB_COLORn_TILE (r600 only) */ unsigned cb_color_mask; /* R600 only */ struct r600_resource *cb_buffer_fmask; /* Used for FMASK relocations. R600 only */ struct r600_resource *cb_buffer_cmask; /* Used for CMASK relocations. R600 only */ @@ -425,8 +426,8 @@ void r600_texture_get_fmask_info(struct r600_common_screen *rscreen, void r600_texture_get_cmask_info(struct r600_common_screen *rscreen, struct r600_texture *rtex, struct r600_cmask_info *out); -void r600_texture_init_cmask(struct r600_common_screen *rscreen, - struct r600_texture *rtex); +void r600_texture_alloc_cmask_separate(struct r600_common_screen *rscreen, + struct r600_texture *rtex); bool r600_init_flushed_depth_texture(struct pipe_context *ctx, struct pipe_resource *texture, struct r600_texture **staging); diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c index 81f32c0f4f3..011efb0442b 100644 --- a/src/gallium/drivers/radeon/r600_texture.c +++ b/src/gallium/drivers/radeon/r600_texture.c @@ -442,11 +442,19 @@ static void r600_texture_allocate_cmask(struct r600_common_screen *rscreen, rtex->cmask.offset = align(rtex->size, rtex->cmask.alignment); rtex->size = rtex->cmask.offset + rtex->cmask.size; + + if (rscreen->chip_class >= SI) + rtex->cb_color_info |= SI_S_028C70_FAST_CLEAR(1); + else + rtex->cb_color_info |= EG_S_028C70_FAST_CLEAR(1); } -void r600_texture_init_cmask(struct r600_common_screen *rscreen, - struct r600_texture *rtex) +void r600_texture_alloc_cmask_separate(struct r600_common_screen *rscreen, + struct r600_texture *rtex) { + if (rtex->cmask_buffer) + return; + assert(rtex->cmask.size == 0); r600_texture_get_cmask_info(rscreen, rtex, &rtex->cmask); @@ -456,7 +464,17 @@ void r600_texture_init_cmask(struct r600_common_screen *rscreen, PIPE_USAGE_DEFAULT, rtex->cmask.size); if (rtex->cmask_buffer == NULL) { rtex->cmask.size = 0; + return; } + + /* update colorbuffer state bits */ + rtex->cmask.base_address_reg = + r600_resource_va(&rscreen->b, &rtex->cmask_buffer->b.b) >> 8; + + if (rscreen->chip_class >= SI) + rtex->cb_color_info |= SI_S_028C70_FAST_CLEAR(1); + else + rtex->cb_color_info |= EG_S_028C70_FAST_CLEAR(1); } static unsigned si_texture_htile_alloc_size(struct r600_common_screen *rscreen, @@ -567,6 +585,7 @@ r600_texture_create_object(struct pipe_screen *screen, struct r600_texture *rtex; struct r600_resource *resource; struct r600_common_screen *rscreen = (struct r600_common_screen*)screen; + uint64_t va; rtex = CALLOC_STRUCT(r600_texture); if (rtex == NULL) @@ -633,6 +652,10 @@ r600_texture_create_object(struct pipe_screen *screen, rtex->cmask.offset, rtex->cmask.size, 0xCCCCCCCC); } + /* Initialize the CMASK base register value. */ + va = r600_resource_va(&rscreen->b, &rtex->resource.b.b); + rtex->cmask.base_address_reg = (va + rtex->cmask.offset) >> 8; + if (rscreen->debug_flags & DBG_VM) { fprintf(stderr, "VM start=0x%"PRIu64" end=0x%"PRIu64" | Texture %ix%ix%i, %i levels, %i samples, %s\n", r600_resource_va(screen, &rtex->resource.b.b), diff --git a/src/gallium/drivers/radeon/r600d_common.h b/src/gallium/drivers/radeon/r600d_common.h index cd311c22d1a..1172af040ad 100644 --- a/src/gallium/drivers/radeon/r600d_common.h +++ b/src/gallium/drivers/radeon/r600d_common.h @@ -189,6 +189,9 @@ #define CM_R_028C18_PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_0 0x28c18 #define CM_R_028C28_PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_0 0x28c28 +#define EG_S_028C70_FAST_CLEAR(x) (((x) & 0x1) << 17) +#define SI_S_028C70_FAST_CLEAR(x) (((x) & 0x1) << 13) + /*CIK+*/ #define R_0300FC_CP_STRMOUT_CNTL 0x0300FC diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c index 6cb898490b4..b95e1e20c8c 100644 --- a/src/gallium/drivers/radeonsi/si_state.c +++ b/src/gallium/drivers/radeonsi/si_state.c @@ -1655,10 +1655,6 @@ static void si_initialize_color_surface(struct si_context *sctx, } } - if (rtex->cmask.size) { - color_info |= S_028C70_FAST_CLEAR(1); - } - offset += r600_resource_va(sctx->b.b.screen, surf->base.texture); surf->cb_color_base = offset >> 8; @@ -1668,10 +1664,6 @@ static void si_initialize_color_surface(struct si_context *sctx, surf->cb_color_info = color_info; surf->cb_color_attrib = color_attrib; - if (rtex->cmask.size) { - surf->cb_color_cmask = (offset + rtex->cmask.offset) >> 8; - surf->cb_color_cmask_slice = S_028C80_TILE_MAX(rtex->cmask.slice_tile_max); - } if (rtex->fmask.size) { surf->cb_color_fmask = (offset + rtex->fmask.offset) >> 8; surf->cb_color_fmask_slice = S_028C88_TILE_MAX(rtex->fmask.slice_tile_max); @@ -1908,12 +1900,12 @@ static void si_emit_framebuffer_state(struct si_context *sctx, struct r600_atom struct radeon_winsys_cs *cs = sctx->b.rings.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; /* Colorbuffers. */ for (i = 0; i < nr_cbufs; i++) { - struct r600_surface *cb = (struct r600_surface*)state->cbufs[i]; - struct r600_texture *tex; - + cb = (struct r600_surface*)state->cbufs[i]; if (!cb) { r600_write_context_reg(cs, R_028C70_CB_COLOR0_INFO + i * 0x3C, S_028C70_FORMAT(V_028C70_COLOR_INVALID)); @@ -1938,11 +1930,11 @@ static void si_emit_framebuffer_state(struct si_context *sctx, struct r600_atom radeon_emit(cs, cb->cb_color_pitch); /* R_028C64_CB_COLOR0_PITCH */ radeon_emit(cs, cb->cb_color_slice); /* R_028C68_CB_COLOR0_SLICE */ radeon_emit(cs, cb->cb_color_view); /* R_028C6C_CB_COLOR0_VIEW */ - radeon_emit(cs, cb->cb_color_info); /* R_028C70_CB_COLOR0_INFO */ + radeon_emit(cs, cb->cb_color_info | tex->cb_color_info); /* R_028C70_CB_COLOR0_INFO */ radeon_emit(cs, cb->cb_color_attrib); /* R_028C74_CB_COLOR0_ATTRIB */ radeon_emit(cs, 0); /* R_028C78 unused */ - radeon_emit(cs, cb->cb_color_cmask); /* R_028C7C_CB_COLOR0_CMASK */ - radeon_emit(cs, cb->cb_color_cmask_slice); /* R_028C80_CB_COLOR0_CMASK_SLICE */ + radeon_emit(cs, tex->cmask.base_address_reg); /* R_028C7C_CB_COLOR0_CMASK */ + radeon_emit(cs, tex->cmask.slice_tile_max); /* R_028C80_CB_COLOR0_CMASK_SLICE */ radeon_emit(cs, cb->cb_color_fmask); /* R_028C84_CB_COLOR0_FMASK */ radeon_emit(cs, cb->cb_color_fmask_slice); /* R_028C88_CB_COLOR0_FMASK_SLICE */ radeon_emit(cs, tex->color_clear_value[0]); /* R_028C8C_CB_COLOR0_CLEAR_WORD0 */ @@ -1951,7 +1943,7 @@ static void si_emit_framebuffer_state(struct si_context *sctx, struct r600_atom /* set CB_COLOR1_INFO for possible dual-src blending */ if (i == 1 && state->cbufs[0]) { r600_write_context_reg(cs, R_028C70_CB_COLOR0_INFO + 1 * 0x3C, - ((struct r600_surface*)state->cbufs[0])->cb_color_info); + cb->cb_color_info | tex->cb_color_info); i++; } for (; i < 8 ; i++) {