On Thu, May 9, 2013 at 5:33 PM, Marek Olšák <mar...@gmail.com> wrote: > This fixes and enables texturing with compressed MSAA colorbuffers > on Evergreen and Cayman. For the first time, multisample textures work > on Cayman. > > This requires the libdrm flag RADEON_SURF_FMASK.
Maybe bump the libdrm requirement when you commit? Other than that: Reviewed-by: Alex Deucher <alexander.deuc...@amd.com> > --- > src/gallium/drivers/r600/evergreen_state.c | 17 +++++++----- > src/gallium/drivers/r600/evergreend.h | 3 +++ > src/gallium/drivers/r600/r600_blit.c | 6 +---- > src/gallium/drivers/r600/r600_pipe.c | 3 +-- > src/gallium/drivers/r600/r600_resource.h | 5 +++- > src/gallium/drivers/r600/r600_state.c | 4 +-- > src/gallium/drivers/r600/r600_texture.c | 40 > +++++++++++++++------------- > 7 files changed, 42 insertions(+), 36 deletions(-) > > diff --git a/src/gallium/drivers/r600/evergreen_state.c > b/src/gallium/drivers/r600/evergreen_state.c > index 6797b22..4eb9768 100644 > --- a/src/gallium/drivers/r600/evergreen_state.c > +++ b/src/gallium/drivers/r600/evergreen_state.c > @@ -1101,7 +1101,7 @@ evergreen_create_sampler_view_custom(struct > pipe_context *ctx, > uint32_t word4 = 0, yuv_format = 0, pitch = 0; > unsigned char swizzle[4], array_mode = 0, non_disp_tiling = 0; > unsigned height, depth, width; > - unsigned macro_aspect, tile_split, bankh, bankw, nbanks; > + unsigned macro_aspect, tile_split, bankh, bankw, nbanks, fmask_bankh; > enum pipe_format pipe_format = state->format; > struct radeon_surface_level *surflevel; > > @@ -1188,6 +1188,7 @@ evergreen_create_sampler_view_custom(struct > pipe_context *ctx, > macro_aspect = eg_macro_tile_aspect(macro_aspect); > bankw = eg_bank_wh(bankw); > bankh = eg_bank_wh(bankh); > + fmask_bankh = eg_bank_wh(tmp->fmask_bank_height); > > /* 128 bit formats require tile type = 1 */ > if (rscreen->chip_class == CAYMAN) { > @@ -1219,8 +1220,7 @@ evergreen_create_sampler_view_custom(struct > pipe_context *ctx, > > /* TEX_RESOURCE_WORD3.MIP_ADDRESS */ > if (texture->nr_samples > 1 && rscreen->msaa_texture_support == > MSAA_TEXTURE_COMPRESSED) { > - /* XXX the 2x and 4x cases are broken. */ > - if (tmp->is_depth || tmp->resource.b.b.nr_samples != 8) { > + if (tmp->is_depth) { > /* disable FMASK (0 = disabled) */ > view->tex_resource_words[3] = 0; > view->skip_mip_address_reloc = true; > @@ -1239,6 +1239,8 @@ evergreen_create_sampler_view_custom(struct > pipe_context *ctx, > S_030010_ENDIAN_SWAP(endian)); > view->tex_resource_words[5] = > S_030014_BASE_ARRAY(state->u.tex.first_layer) | > > S_030014_LAST_ARRAY(state->u.tex.last_layer); > + view->tex_resource_words[6] = S_030018_TILE_SPLIT(tile_split); > + > if (texture->nr_samples > 1) { > unsigned log_samples = util_logbase2(texture->nr_samples); > if (rscreen->chip_class == CAYMAN) { > @@ -1246,13 +1248,14 @@ evergreen_create_sampler_view_custom(struct > pipe_context *ctx, > } > /* LAST_LEVEL holds log2(nr_samples) for multisample textures > */ > view->tex_resource_words[5] |= > S_030014_LAST_LEVEL(log_samples); > + view->tex_resource_words[6] |= > S_030018_FMASK_BANK_HEIGHT(fmask_bankh); > } else { > view->tex_resource_words[4] |= > S_030010_BASE_LEVEL(state->u.tex.first_level); > view->tex_resource_words[5] |= > S_030014_LAST_LEVEL(state->u.tex.last_level); > + /* aniso max 16 samples */ > + view->tex_resource_words[6] |= S_030018_MAX_ANISO(4); > } > - /* aniso max 16 samples */ > - view->tex_resource_words[6] = (S_030018_MAX_ANISO(4)) | > - (S_030018_TILE_SPLIT(tile_split)); > + > view->tex_resource_words[7] = S_03001C_DATA_FORMAT(format) | > > S_03001C_TYPE(V_03001C_SQ_TEX_VTX_VALID_TEXTURE) | > S_03001C_BANK_WIDTH(bankw) | > @@ -1576,7 +1579,7 @@ void evergreen_init_color_surface(struct r600_context > *rctx, > 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_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; > diff --git a/src/gallium/drivers/r600/evergreend.h > b/src/gallium/drivers/r600/evergreend.h > index 757c951..8990d6c 100644 > --- a/src/gallium/drivers/r600/evergreend.h > +++ b/src/gallium/drivers/r600/evergreend.h > @@ -1140,9 +1140,12 @@ > #define G_030014_LAST_ARRAY(x) (((x) >> 17) & 0x1FFF) > #define C_030014_LAST_ARRAY 0xC001FFFF > #define R_030018_SQ_TEX_RESOURCE_WORD6_0 0x030018 > +/* FMASK_BANK_HEIGHT and MAX_ANISO share the first two bits. > + * The former is only used with MSAA textures. */ > #define S_030018_MAX_ANISO(x) (((x) & 0x7) << 0) > #define G_030018_MAX_ANISO(x) (((x) >> 0) & 0x7) > #define C_030018_MAX_ANISO 0xFFFFFFF8 > +#define S_030018_FMASK_BANK_HEIGHT(x) (((x) & 0x3) << 0) > #define S_030018_PERF_MODULATION(x) (((x) & 0x7) << 3) > #define G_030018_PERF_MODULATION(x) (((x) >> 3) & 0x7) > #define C_030018_PERF_MODULATION 0xFFFFFFC7 > diff --git a/src/gallium/drivers/r600/r600_blit.c > b/src/gallium/drivers/r600/r600_blit.c > index afe4389..7d32eef 100644 > --- a/src/gallium/drivers/r600/r600_blit.c > +++ b/src/gallium/drivers/r600/r600_blit.c > @@ -300,11 +300,7 @@ static void r600_blit_decompress_color(struct > pipe_context *ctx, > blend_decompress = rctx->custom_blend_decompress; > break; > case MSAA_TEXTURE_COMPRESSED: > - /* XXX the 2x and 4x cases are broken. */ > - if (rtex->resource.b.b.nr_samples == 8) > - blend_decompress = > rctx->custom_blend_fmask_decompress; > - else > - blend_decompress = rctx->custom_blend_decompress; > + blend_decompress = rctx->custom_blend_fmask_decompress; > break; > case MSAA_TEXTURE_SAMPLE_ZERO: > default: > diff --git a/src/gallium/drivers/r600/r600_pipe.c > b/src/gallium/drivers/r600/r600_pipe.c > index e7b5152..533e0c0 100644 > --- a/src/gallium/drivers/r600/r600_pipe.c > +++ b/src/gallium/drivers/r600/r600_pipe.c > @@ -1268,8 +1268,7 @@ struct pipe_screen *r600_screen_create(struct > radeon_winsys *ws) > break; > case CAYMAN: > rscreen->has_msaa = rscreen->info.drm_minor >= 19; > - /* We should be able to read compressed MSAA textures, but it > doesn't work. */ > - rscreen->msaa_texture_support = MSAA_TEXTURE_SAMPLE_ZERO; > + rscreen->msaa_texture_support = MSAA_TEXTURE_COMPRESSED; > break; > default: > rscreen->has_msaa = FALSE; > diff --git a/src/gallium/drivers/r600/r600_resource.h > b/src/gallium/drivers/r600/r600_resource.h > index e20e942..d5df633 100644 > --- a/src/gallium/drivers/r600/r600_resource.h > +++ b/src/gallium/drivers/r600/r600_resource.h > @@ -84,7 +84,9 @@ struct r600_texture { > /* FMASK and CMASK can only be used with MSAA textures for now. > * MSAA textures cannot have mipmaps. */ > unsigned fmask_offset, fmask_size, > fmask_bank_height; > - unsigned cmask_offset, cmask_size, > cmask_slice_tile_max; > + unsigned fmask_slice_tile_max; > + unsigned cmask_offset, cmask_size; > + unsigned cmask_slice_tile_max; > > struct r600_resource *htile; > /* use htile only for first level */ > @@ -97,6 +99,7 @@ struct r600_fmask_info { > unsigned size; > unsigned alignment; > unsigned bank_height; > + unsigned slice_tile_max; > }; > > struct r600_cmask_info { > diff --git a/src/gallium/drivers/r600/r600_state.c > b/src/gallium/drivers/r600/r600_state.c > index 4e0e4a6..f0e3675 100644 > --- a/src/gallium/drivers/r600/r600_state.c > +++ b/src/gallium/drivers/r600/r600_state.c > @@ -1404,7 +1404,7 @@ static void r600_init_color_surface(struct r600_context > *rctx, > if (rtex->fmask_size) { > color_info |= > S_0280A0_TILE_MODE(V_0280A0_FRAG_ENABLE); > surf->cb_color_fmask = rtex->fmask_offset >> 8; > - surf->cb_color_mask |= S_028100_FMASK_TILE_MAX(slice); > + surf->cb_color_mask |= > S_028100_FMASK_TILE_MAX(rtex->fmask_slice_tile_max); > } else { /* cmask only */ > color_info |= > S_0280A0_TILE_MODE(V_0280A0_CLEAR_ENABLE); > } > @@ -1455,7 +1455,7 @@ static void r600_init_color_surface(struct r600_context > *rctx, > surf->cb_color_cmask = 0; > surf->cb_color_fmask = 0; > surf->cb_color_mask = > S_028100_CMASK_BLOCK_MAX(cmask.slice_tile_max) | > - S_028100_FMASK_TILE_MAX(slice); > + > S_028100_FMASK_TILE_MAX(fmask.slice_tile_max); > } > > surf->cb_color_info = color_info; > diff --git a/src/gallium/drivers/r600/r600_texture.c > b/src/gallium/drivers/r600/r600_texture.c > index 3a1f2fe..19afd65 100644 > --- a/src/gallium/drivers/r600/r600_texture.c > +++ b/src/gallium/drivers/r600/r600_texture.c > @@ -284,50 +284,51 @@ void r600_texture_get_fmask_info(struct r600_screen > *rscreen, > unsigned nr_samples, > struct r600_fmask_info *out) > { > - /* FMASK is allocated pretty much like an ordinary texture. > - * Here we use bpe in the units of bits, not bytes. */ > + /* FMASK is allocated like an ordinary texture. */ > struct radeon_surface fmask = rtex->surface; > > + memset(out, 0, sizeof(*out)); > + > + fmask.bo_alignment = 0; > + fmask.bo_size = 0; > + fmask.nsamples = 1; > + fmask.flags |= RADEON_SURF_FMASK; > + > switch (nr_samples) { > case 2: > - /* This should be 8,1, but we should set nsamples > 1 > - * for the allocator to treat it as a multisample surface. > - * Let's set 4,2 then. */ > case 4: > - fmask.bpe = 4; > - fmask.nsamples = 2; > + fmask.bpe = 1; > + fmask.bankh = 4; > break; > case 8: > - fmask.bpe = 8; > - fmask.nsamples = 4; > - break; > - case 16: > - fmask.bpe = 16; > - fmask.nsamples = 4; > + fmask.bpe = 4; > break; > default: > R600_ERR("Invalid sample count for FMASK allocation.\n"); > return; > } > > - /* R600-R700 errata? Anyway, this fixes colorbuffer corruption. */ > + /* Overallocate FMASK on R600-R700 to fix colorbuffer corruption. > + * This can be fixed by writing a separate FMASK allocator > specifically > + * for R600-R700 asics. */ > if (rscreen->chip_class <= R700) { > fmask.bpe *= 2; > } > > - if (rscreen->chip_class >= EVERGREEN) { > - fmask.bankh = nr_samples <= 4 ? 4 : 1; > - } > - > if (rscreen->ws->surface_init(rscreen->ws, &fmask)) { > R600_ERR("Got error in surface_init while allocating > FMASK.\n"); > return; > } > + > assert(fmask.level[0].mode == RADEON_SURF_MODE_2D); > > + out->slice_tile_max = (fmask.level[0].nblk_x * fmask.level[0].nblk_y) > / 64; > + if (out->slice_tile_max) > + out->slice_tile_max -= 1; > + > out->bank_height = fmask.bankh; > out->alignment = MAX2(256, fmask.bo_alignment); > - out->size = (fmask.bo_size + 7) / 8; > + out->size = fmask.bo_size; > } > > static void r600_texture_allocate_fmask(struct r600_screen *rscreen, > @@ -339,6 +340,7 @@ static void r600_texture_allocate_fmask(struct > r600_screen *rscreen, > rtex->resource.b.b.nr_samples, &fmask); > > rtex->fmask_bank_height = fmask.bank_height; > + rtex->fmask_slice_tile_max = fmask.slice_tile_max; > rtex->fmask_offset = align(rtex->size, fmask.alignment); > rtex->fmask_size = fmask.size; > rtex->size = rtex->fmask_offset + rtex->fmask_size; > -- > 1.7.10.4 > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev