radeonsi: program tile swizzle for color and FMASK surfaces for GFX & SDMA
authorMarek Olšák <marek.olsak@amd.com>
Fri, 28 Jul 2017 23:35:46 +0000 (01:35 +0200)
committerMarek Olšák <marek.olsak@amd.com>
Fri, 4 Aug 2017 00:10:04 +0000 (02:10 +0200)
Reviewed-by: Dave Airlie <airlied@redhat.com>
Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
src/gallium/drivers/radeon/r600_pipe_common.h
src/gallium/drivers/radeon/r600_texture.c
src/gallium/drivers/radeonsi/cik_sdma.c
src/gallium/drivers/radeonsi/si_descriptors.c
src/gallium/drivers/radeonsi/si_state.c

index b391cbb82a6a476aa4894811aedd6cab0a4f0558..fb52dfb529772c58dcca30b29e9e3a751a9c13bf 100644 (file)
@@ -202,6 +202,7 @@ struct r600_fmask_info {
        unsigned bank_height;
        unsigned slice_tile_max;
        unsigned tile_mode_index;
+       unsigned tile_swizzle;
 };
 
 struct r600_cmask_info {
index 07df2d43017a3b6a6567b49a79c93d2f4b4f34bb..e3d462ea80a8c33e597e2b33131b367964a4bc31 100644 (file)
@@ -757,6 +757,7 @@ void r600_texture_get_fmask_info(struct r600_common_screen *rscreen,
        out->tile_mode_index = fmask.u.legacy.tiling_index[0];
        out->pitch_in_pixels = fmask.u.legacy.level[0].nblk_x;
        out->bank_height = fmask.u.legacy.bankh;
+       out->tile_swizzle = fmask.tile_swizzle;
        out->alignment = MAX2(256, fmask.surf_alignment);
        out->size = fmask.surf_size;
 }
@@ -1447,7 +1448,7 @@ static struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen
        struct pb_buffer *buf = NULL;
        unsigned stride = 0, offset = 0;
        unsigned array_mode;
-       struct radeon_surf surface;
+       struct radeon_surf surface = {};
        int r;
        struct radeon_bo_metadata metadata = {};
        struct r600_texture *rtex;
@@ -1511,6 +1512,7 @@ static struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen
                assert(metadata.u.gfx9.swizzle_mode == surface.u.gfx9.surf.swizzle_mode);
        }
 
+       assert(rtex->surface.tile_swizzle == 0);
        return &rtex->resource.b.b;
 }
 
index 99285a6de17687786be5aacb4444d45a87d1424f..8154d720dc24736e110201c42d175b42a5074bfb 100644 (file)
@@ -162,6 +162,10 @@ static bool cik_sdma_copy_texture(struct si_context *sctx,
        unsigned src_tile_mode = info->si_tile_mode_array[src_tile_index];
        unsigned dst_micro_mode = G_009910_MICRO_TILE_MODE_NEW(dst_tile_mode);
        unsigned src_micro_mode = G_009910_MICRO_TILE_MODE_NEW(src_tile_mode);
+       unsigned dst_tile_swizzle = dst_mode == RADEON_SURF_MODE_2D ?
+                                           rdst->surface.tile_swizzle : 0;
+       unsigned src_tile_swizzle = src_mode == RADEON_SURF_MODE_2D ?
+                                           rsrc->surface.tile_swizzle : 0;
        unsigned dst_pitch = rdst->surface.u.legacy.level[dst_level].nblk_x;
        unsigned src_pitch = rsrc->surface.u.legacy.level[src_level].nblk_x;
        uint64_t dst_slice_pitch = rdst->surface.u.legacy.level[dst_level].slice_size / bpp;
@@ -205,6 +209,9 @@ static bool cik_sdma_copy_texture(struct si_context *sctx,
            dstz >= (1 << 11))
                return false;
 
+       dst_address |= dst_tile_swizzle << 8;
+       src_address |= src_tile_swizzle << 8;
+
        /* Linear -> linear sub-window copy. */
        if (dst_mode == RADEON_SURF_MODE_LINEAR_ALIGNED &&
            src_mode == RADEON_SURF_MODE_LINEAR_ALIGNED &&
index 26a8d815183d24be1b7136d94664faf9e9c79bfe..02f921e5be1f2f46cdd75c33232235f9074676a7 100644 (file)
@@ -422,6 +422,13 @@ void si_set_mutable_tex_desc_fields(struct si_screen *sscreen,
        state[1] &= C_008F14_BASE_ADDRESS_HI;
        state[1] |= S_008F14_BASE_ADDRESS_HI(va >> 40);
 
+       /* Only macrotiled modes can set tile swizzle.
+        * GFX9 doesn't use (legacy) base_level_info.
+        */
+       if (sscreen->b.chip_class >= GFX9 ||
+           base_level_info->mode == RADEON_SURF_MODE_2D)
+               state[0] |= tex->surface.tile_swizzle;
+
        if (sscreen->b.chip_class >= VI) {
                state[6] &= C_008F28_COMPRESSION_EN;
                state[7] = 0;
@@ -430,8 +437,12 @@ void si_set_mutable_tex_desc_fields(struct si_screen *sscreen,
                        meta_va = (!tex->dcc_separate_buffer ? tex->resource.gpu_address : 0) +
                                  tex->dcc_offset;
 
-                       if (sscreen->b.chip_class <= VI)
+                       if (sscreen->b.chip_class == VI) {
                                meta_va += base_level_info->dcc_offset;
+                               assert(base_level_info->mode == RADEON_SURF_MODE_2D);
+                       }
+
+                       meta_va |= (uint32_t)tex->surface.tile_swizzle << 8;
                } else if (tex->tc_compatible_htile && first_level == 0) {
                        meta_va = tex->resource.gpu_address + tex->htile_offset;
                }
index 6e678242a2c2ab6fc1a95b7a87664ad7a0466b57..c9bb108cc16cdcb4f59b8f6da84d10ad13d03d62 100644 (file)
@@ -2767,8 +2767,10 @@ static void si_emit_framebuffer_state(struct si_context *sctx, struct r600_atom
                cb_color_info = cb->cb_color_info | tex->cb_color_info;
                cb_color_attrib = cb->cb_color_attrib;
 
-               if (tex->fmask.size)
+               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)) {
@@ -2782,6 +2784,7 @@ static void si_emit_framebuffer_state(struct si_context *sctx, struct r600_atom
 
                        cb_dcc_base = ((!tex->dcc_separate_buffer ? tex->resource.gpu_address : 0) +
                                       tex->dcc_offset) >> 8;
+                       cb_dcc_base |= tex->surface.tile_swizzle;
                }
 
                if (sctx->b.chip_class >= GFX9) {
@@ -2794,6 +2797,7 @@ static void si_emit_framebuffer_state(struct si_context *sctx, struct r600_atom
 
                        /* 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;
                        cb_color_attrib |= S_028C74_COLOR_SW_MODE(tex->surface.u.gfx9.surf.swizzle_mode) |
@@ -2828,6 +2832,10 @@ static void si_emit_framebuffer_state(struct si_context *sctx, struct r600_atom
                        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_dcc_base)
@@ -3416,7 +3424,7 @@ si_make_texture_descriptor(struct si_screen *screen,
                        num_format = V_008F14_IMG_NUM_FORMAT_UINT;
                }
 
-               fmask_state[0] = va >> 8;
+               fmask_state[0] = (va >> 8) | tex->fmask.tile_swizzle;
                fmask_state[1] = S_008F14_BASE_ADDRESS_HI(va >> 40) |
                                 S_008F14_DATA_FORMAT_GFX6(data_format) |
                                 S_008F14_NUM_FORMAT_GFX6(num_format);