diff options
author | Marek Olšák <[email protected]> | 2012-08-12 20:06:33 +0200 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2012-08-27 04:31:00 +0200 |
commit | a3d9d7ec79d6f7205fab2324e47d8ea185431de0 (patch) | |
tree | 3aa8b27b500d9e7535053e01c5345f025ab4f86a /src/gallium/drivers/r600/evergreen_state.c | |
parent | 48edfe0505ee79d35f770f53b9c9b7ca3c69fd2b (diff) |
r600g: implement compression for MSAA colorbuffers for evergreen
This adds the FMASK and CMASK buffers. They share the same resource
with color data.
COMPRESSION and FAST_CLEAR are always enabled if both FMASK and CMASK are
allocated. We initialize the CMASK to a "compressed" state (not "fast cleared"),
so that we can keep FAST_CLEAR enabled all the time.
Both FMASK and CMASK must be present at the moment. If either one is missing,
the other one is not used.
v2: add cayman regs in the list
Reviewed-by: Jerome Glisse <[email protected]>
Diffstat (limited to 'src/gallium/drivers/r600/evergreen_state.c')
-rw-r--r-- | src/gallium/drivers/r600/evergreen_state.c | 54 |
1 files changed, 48 insertions, 6 deletions
diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index e12706e856b..35bc391fe80 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -1250,8 +1250,8 @@ void evergreen_init_color_surface(struct r600_context *rctx, unsigned pitch, slice; unsigned color_info, color_attrib, color_dim = 0; unsigned format, swap, ntype, endian; - uint64_t offset; - unsigned tile_type, macro_aspect, tile_split, bankh, bankw, nbanks; + uint64_t offset, base_offset; + unsigned tile_type, macro_aspect, tile_split, bankh, bankw, fmask_bankh, nbanks; const struct util_format_description *desc; int i; bool blend_clamp = 0, blend_bypass = 0; @@ -1296,10 +1296,12 @@ void evergreen_init_color_surface(struct r600_context *rctx, macro_aspect = rtex->surface.mtilea; bankw = rtex->surface.bankw; bankh = rtex->surface.bankh; + fmask_bankh = rtex->fmask_bank_height; tile_split = eg_tile_split(tile_split); macro_aspect = eg_macro_tile_aspect(macro_aspect); bankw = eg_bank_wh(bankw); bankh = eg_bank_wh(bankh); + fmask_bankh = eg_bank_wh(fmask_bankh); /* 128 bit formats require tile type = 1 */ if (rscreen->chip_class == CAYMAN) { @@ -1319,7 +1321,8 @@ void evergreen_init_color_surface(struct r600_context *rctx, S_028C74_BANK_WIDTH(bankw) | S_028C74_BANK_HEIGHT(bankh) | S_028C74_MACRO_TILE_ASPECT(macro_aspect) | - S_028C74_NON_DISP_TILING_ORDER(tile_type); + S_028C74_NON_DISP_TILING_ORDER(tile_type) | + S_028C74_FMASK_BANK_HEIGHT(fmask_bankh); ntype = V_028C70_NUMBER_UNORM; if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) @@ -1393,11 +1396,14 @@ void evergreen_init_color_surface(struct r600_context *rctx, surf->export_16bpc = true; } - offset += r600_resource_va(rctx->context.screen, pipe_tex); - offset >>= 8; + if (rtex->fmask_size && rtex->cmask_size) { + color_info |= S_028C70_COMPRESSION(1) | S_028C70_FAST_CLEAR(1); + } + + base_offset = r600_resource_va(rctx->context.screen, pipe_tex); /* XXX handle enabling of CB beyond BASE8 which has different offset */ - surf->cb_color_base = offset; + surf->cb_color_base = (base_offset + offset) >> 8; surf->cb_color_dim = color_dim; surf->cb_color_info = color_info; surf->cb_color_pitch = S_028C64_PITCH_TILE_MAX(pitch); @@ -1409,6 +1415,15 @@ void evergreen_init_color_surface(struct r600_context *rctx, S_028C6C_SLICE_MAX(surf->base.u.tex.last_layer); } surf->cb_color_attrib = color_attrib; + if (rtex->fmask_size && rtex->cmask_size) { + surf->cb_color_fmask = (base_offset + rtex->fmask_offset) >> 8; + surf->cb_color_cmask = (base_offset + rtex->cmask_offset) >> 8; + } else { + surf->cb_color_fmask = surf->cb_color_base; + surf->cb_color_cmask = surf->cb_color_base; + } + surf->cb_color_fmask_slice = S_028C88_TILE_MAX(slice); + surf->cb_color_cmask_slice = S_028C80_TILE_MAX(rtex->cmask_slice_tile_max); surf->color_initialized = true; } @@ -1631,6 +1646,7 @@ static void evergreen_set_framebuffer_state(struct pipe_context *ctx, struct r600_pipe_state *rstate = CALLOC_STRUCT(r600_pipe_state); struct r600_surface *surf; struct r600_resource *res; + struct r600_texture *rtex; uint32_t tl, br, i, nr_samples; if (rstate == NULL) @@ -1648,10 +1664,12 @@ static void evergreen_set_framebuffer_state(struct pipe_context *ctx, rctx->nr_cbufs = state->nr_cbufs; rctx->cb0_is_integer = state->nr_cbufs && util_format_is_pure_integer(state->cbufs[0]->format); + rctx->compressed_cb_mask = 0; for (i = 0; i < state->nr_cbufs; i++) { surf = (struct r600_surface*)state->cbufs[i]; res = (struct r600_resource*)surf->base.texture; + rtex = (struct r600_texture*)res; if (!surf->color_initialized) { evergreen_init_color_surface(rctx, surf); @@ -1675,6 +1693,18 @@ static void evergreen_set_framebuffer_state(struct pipe_context *ctx, surf->cb_color_view); r600_pipe_state_add_reg_bo(rstate, R_028C74_CB_COLOR0_ATTRIB + i * 0x3C, surf->cb_color_attrib, res, RADEON_USAGE_READWRITE); + r600_pipe_state_add_reg_bo(rstate, R_028C7C_CB_COLOR0_CMASK + i * 0x3c, + surf->cb_color_cmask, res, RADEON_USAGE_READWRITE); + r600_pipe_state_add_reg(rstate, R_028C80_CB_COLOR0_CMASK_SLICE + i * 0x3c, + surf->cb_color_cmask_slice); + r600_pipe_state_add_reg_bo(rstate, R_028C84_CB_COLOR0_FMASK + i * 0x3c, + surf->cb_color_fmask, res, RADEON_USAGE_READWRITE); + r600_pipe_state_add_reg(rstate, R_028C88_CB_COLOR0_FMASK_SLICE + i * 0x3c, + surf->cb_color_fmask_slice); + + if (rtex->fmask_size && rtex->cmask_size) { + rctx->compressed_cb_mask |= 1 << i; + } } /* set CB_COLOR1_INFO for possible dual-src blending */ if (i == 1 && !((struct r600_texture*)res)->is_rat) { @@ -3080,6 +3110,18 @@ void *evergreen_create_resolve_blend(struct r600_context *rctx) return rstate; } +void *evergreen_create_decompress_blend(struct r600_context *rctx) +{ + struct pipe_blend_state blend; + struct r600_pipe_state *rstate; + + memset(&blend, 0, sizeof(blend)); + blend.independent_blend_enable = true; + blend.rt[0].colormask = 0xf; + rstate = evergreen_create_blend_state_mode(&rctx->context, &blend, V_028808_CB_DECOMPRESS); + return rstate; +} + void *evergreen_create_db_flush_dsa(struct r600_context *rctx) { struct pipe_depth_stencil_alpha_state dsa = {{0}}; |