summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Olšák <maraeo@gmail.com>2013-04-11 14:54:40 +0200
committerMarek Olšák <maraeo@gmail.com>2013-05-15 20:19:45 +0200
commit61c995bc47b838317a4a62fba2ff2031bcb0c23e (patch)
treece944ced016e5fbca14b36dcaf225efc3f758ad3
parent61506257f68c18cc927a44f25344ee0584fdbd0e (diff)
r600g: rewrite FMASK allocation, fix FMASK texturing with 2 and 4 samples
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. v2: require libdrm_radeon 2.4.45 Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--configure.ac2
-rw-r--r--src/gallium/drivers/r600/evergreen_state.c17
-rw-r--r--src/gallium/drivers/r600/evergreend.h3
-rw-r--r--src/gallium/drivers/r600/r600_blit.c6
-rw-r--r--src/gallium/drivers/r600/r600_pipe.c3
-rw-r--r--src/gallium/drivers/r600/r600_resource.h5
-rw-r--r--src/gallium/drivers/r600/r600_state.c4
-rw-r--r--src/gallium/drivers/r600/r600_texture.c40
8 files changed, 43 insertions, 37 deletions
diff --git a/configure.ac b/configure.ac
index 5bc8c94a2ec..eef4327804c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -33,3 +33,3 @@ dnl Versions for external dependencies
LIBDRM_REQUIRED=2.4.24
-LIBDRM_RADEON_REQUIRED=2.4.44
+LIBDRM_RADEON_REQUIRED=2.4.45
LIBDRM_INTEL_REQUIRED=2.4.38
diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c
index 6797b223742..4eb976849c5 100644
--- a/src/gallium/drivers/r600/evergreen_state.c
+++ b/src/gallium/drivers/r600/evergreen_state.c
@@ -1103,3 +1103,3 @@ evergreen_create_sampler_view_custom(struct pipe_context *ctx,
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;
@@ -1190,2 +1190,3 @@ evergreen_create_sampler_view_custom(struct pipe_context *ctx,
bankh = eg_bank_wh(bankh);
+ fmask_bankh = eg_bank_wh(tmp->fmask_bank_height);
@@ -1221,4 +1222,3 @@ evergreen_create_sampler_view_custom(struct pipe_context *ctx,
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) */
@@ -1241,2 +1241,4 @@ evergreen_create_sampler_view_custom(struct pipe_context *ctx,
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) {
@@ -1248,2 +1250,3 @@ evergreen_create_sampler_view_custom(struct pipe_context *ctx,
view->tex_resource_words[5] |= S_030014_LAST_LEVEL(log_samples);
+ view->tex_resource_words[6] |= S_030018_FMASK_BANK_HEIGHT(fmask_bankh);
} else {
@@ -1251,6 +1254,6 @@ evergreen_create_sampler_view_custom(struct pipe_context *ctx,
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) |
@@ -1578,3 +1581,3 @@ void evergreen_init_color_surface(struct r600_context *rctx,
}
- 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);
diff --git a/src/gallium/drivers/r600/evergreend.h b/src/gallium/drivers/r600/evergreend.h
index 757c9512e5f..8990d6c3fad 100644
--- a/src/gallium/drivers/r600/evergreend.h
+++ b/src/gallium/drivers/r600/evergreend.h
@@ -1142,2 +1142,4 @@
#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)
@@ -1145,2 +1147,3 @@
#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)
diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c
index afe43896568..7d32eef89ee 100644
--- a/src/gallium/drivers/r600/r600_blit.c
+++ b/src/gallium/drivers/r600/r600_blit.c
@@ -302,7 +302,3 @@ static void r600_blit_decompress_color(struct pipe_context *ctx,
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;
diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c
index 47cdb9e4926..efb45010a19 100644
--- a/src/gallium/drivers/r600/r600_pipe.c
+++ b/src/gallium/drivers/r600/r600_pipe.c
@@ -1273,4 +1273,3 @@ struct pipe_screen *r600_screen_create(struct radeon_winsys *ws)
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;
diff --git a/src/gallium/drivers/r600/r600_resource.h b/src/gallium/drivers/r600/r600_resource.h
index e20e9421205..d5df63396cc 100644
--- a/src/gallium/drivers/r600/r600_resource.h
+++ b/src/gallium/drivers/r600/r600_resource.h
@@ -86,3 +86,5 @@ struct r600_texture {
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;
@@ -99,2 +101,3 @@ struct r600_fmask_info {
unsigned bank_height;
+ unsigned slice_tile_max;
};
diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c
index 4e0e4a6de69..f0e36753d2b 100644
--- a/src/gallium/drivers/r600/r600_state.c
+++ b/src/gallium/drivers/r600/r600_state.c
@@ -1406,3 +1406,3 @@ static void r600_init_color_surface(struct r600_context *rctx,
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 */
@@ -1457,3 +1457,3 @@ static void r600_init_color_surface(struct r600_context *rctx,
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);
}
diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c
index 3a1f2fea831..19afd65e2c8 100644
--- a/src/gallium/drivers/r600/r600_texture.c
+++ b/src/gallium/drivers/r600/r600_texture.c
@@ -286,22 +286,20 @@ void r600_texture_get_fmask_info(struct r600_screen *rscreen,
{
- /* 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;
@@ -312,3 +310,5 @@ void r600_texture_get_fmask_info(struct r600_screen *rscreen,
- /* 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) {
@@ -317,6 +317,2 @@ void r600_texture_get_fmask_info(struct r600_screen *rscreen,
- if (rscreen->chip_class >= EVERGREEN) {
- fmask.bankh = nr_samples <= 4 ? 4 : 1;
- }
-
if (rscreen->ws->surface_init(rscreen->ws, &fmask)) {
@@ -325,7 +321,12 @@ void r600_texture_get_fmask_info(struct r600_screen *rscreen,
}
+
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;
}
@@ -341,2 +342,3 @@ static void r600_texture_allocate_fmask(struct r600_screen *rscreen,
rtex->fmask_bank_height = fmask.bank_height;
+ rtex->fmask_slice_tile_max = fmask.slice_tile_max;
rtex->fmask_offset = align(rtex->size, fmask.alignment);