radeonsi/gfx10: implement hardware MSAA resolve
authorNicolai Hähnle <nicolai.haehnle@amd.com>
Mon, 2 Jul 2018 16:50:48 +0000 (18:50 +0200)
committerMarek Olšák <marek.olsak@amd.com>
Wed, 3 Jul 2019 19:51:13 +0000 (15:51 -0400)
MSAA is only supported for 64KB_{R,Z}_X modes, so the micro tile
optimization that we use on gfx9 and earlier does not work.

Be very explicit about how the swizzle mode of the temporary surface is
selected.

Acked-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
src/amd/common/ac_surface.c
src/amd/common/ac_surface.h
src/gallium/drivers/radeonsi/si_blit.c
src/gallium/drivers/radeonsi/si_clear.c
src/gallium/drivers/radeonsi/si_texture.c

index d1ff060a17e88555c2a3d5b5050b5b16160482a5..80ea6915d0a9eff2a6737304e9288f9e42e5a90f 100644 (file)
@@ -1510,7 +1510,7 @@ static int gfx9_compute_surface(ADDR_HANDLE addrlib,
 
        case RADEON_SURF_MODE_1D:
        case RADEON_SURF_MODE_2D:
-               if (surf->flags & RADEON_SURF_IMPORTED) {
+               if (surf->flags & (RADEON_SURF_IMPORTED | RADEON_SURF_FORCE_SWIZZLE_MODE)) {
                        AddrSurfInfoIn.swizzleMode = surf->u.gfx9.surf.swizzle_mode;
                        break;
                }
index 9fb09326d12ebd7ddc54d967c5a909b1d04d95ec..0c8a7b11380ba35ea07a7f789ea43dab4ca2fff1 100644 (file)
@@ -70,6 +70,7 @@ enum radeon_micro_mode {
 #define RADEON_SURF_OPTIMIZE_FOR_SPACE          (1 << 25)
 #define RADEON_SURF_SHAREABLE                   (1 << 26)
 #define RADEON_SURF_NO_RENDER_TARGET            (1 << 27)
+#define RADEON_SURF_FORCE_SWIZZLE_MODE          (1 << 28)
 
 struct legacy_surf_level {
     uint64_t                    offset;
index 638f2ee4d24196690fabb22808da08cb61a0a82e..9c6e3bc2c5465a3a1019ea71b5d195b86516a040 100644 (file)
@@ -1109,6 +1109,12 @@ static bool do_hardware_msaa_resolve(struct pipe_context *ctx,
                        /* The next fast clear will switch to this mode to
                         * get direct hw resolve next time if the mode is
                         * different now.
+                        *
+                        * TODO-GFX10: This does not work in GFX10 because MSAA
+                        * is restricted to 64KB_R_X and 64KB_Z_X swizzle modes.
+                        * In some cases we could change the swizzle of the
+                        * destination texture instead, but the more general
+                        * solution is to implement compute shader resolve.
                         */
                        src->last_msaa_resolve_target_micro_mode =
                                dst->surface.micro_tile_mode;
index 60daff383cbba113064d008df986ffa943c65be1..fa8ae5d2566df999af5fe01475c3cc6ce6dc84be 100644 (file)
@@ -277,7 +277,8 @@ void vi_dcc_clear_level(struct si_context *sctx,
 static void si_set_optimal_micro_tile_mode(struct si_screen *sscreen,
                                           struct si_texture *tex)
 {
-       if (tex->buffer.b.is_shared ||
+       if (sscreen->info.chip_class >= GFX10 ||
+           tex->buffer.b.is_shared ||
            tex->buffer.b.b.nr_samples <= 1 ||
            tex->surface.micro_tile_mode == tex->last_msaa_resolve_target_micro_mode)
                return;
index 37641c4a102f484419df5ccf1867073774c9670c..6e96b66f8a4760df53045fd7568fe307b68ec6f6 100644 (file)
@@ -37,6 +37,7 @@
 #include <inttypes.h>
 #include "state_tracker/drm_driver.h"
 #include "sid.h"
+#include "amd/addrlib/inc/addrinterface.h"
 
 static enum radeon_surf_mode
 si_choose_tiling(struct si_screen *sscreen,
@@ -310,6 +311,12 @@ static int si_init_surface(struct si_screen *sscreen,
        if (!(ptex->flags & SI_RESOURCE_FLAG_FORCE_MSAA_TILING))
                flags |= RADEON_SURF_OPTIMIZE_FOR_SPACE;
 
+       if (sscreen->info.chip_class >= GFX10 &&
+           (ptex->flags & SI_RESOURCE_FLAG_FORCE_MSAA_TILING)) {
+               flags |= RADEON_SURF_FORCE_SWIZZLE_MODE;
+               surface->u.gfx9.surf.swizzle_mode = ADDR_SW_64KB_R_X;
+       }
+
        r = sscreen->ws->surface_init(sscreen->ws, ptex, flags, bpe,
                                      array_mode, surface);
        if (r) {