ac/surface: compute tile swizzle for GFX9
authorMarek Olšák <marek.olsak@amd.com>
Fri, 28 Jul 2017 23:40:48 +0000 (01:40 +0200)
committerMarek Olšák <marek.olsak@amd.com>
Wed, 21 Mar 2018 17:40:06 +0000 (13:40 -0400)
Tested-by: Dieter Nützel <Dieter@nuetzel-hh.de>
src/amd/common/ac_surface.c
src/amd/common/ac_surface.h
src/gallium/drivers/radeon/r600_texture.c
src/gallium/winsys/amdgpu/drm/amdgpu_surface.c

index 590920ee2b6b1338ca9d85ebbc9331b5d1736462..92bdf1dedec40d18b5d37be902541ad4dfc68bd3 100644 (file)
@@ -849,6 +849,7 @@ gfx9_get_preferred_swizzle_mode(ADDR_HANDLE addrlib,
 }
 
 static int gfx9_compute_miptree(ADDR_HANDLE addrlib,
+                               const struct ac_surf_config *config,
                                struct radeon_surf *surf, bool compressed,
                                ADDR2_COMPUTE_SURFACE_INFO_INPUT *in)
 {
@@ -923,6 +924,37 @@ static int gfx9_compute_miptree(ADDR_HANDLE addrlib,
                surf->htile_slice_size = hout.sliceSize;
                surf->htile_alignment = hout.baseAlign;
        } else {
+               /* Compute tile swizzle for the color surface.
+                * All *_X and *_T modes can use the swizzle.
+                */
+               if (config->info.surf_index &&
+                   in->swizzleMode >= ADDR_SW_64KB_Z_T &&
+                   !out.mipChainInTail &&
+                   !(surf->flags & RADEON_SURF_SHAREABLE) &&
+                   (in->numSamples > 1 || !(surf->flags & RADEON_SURF_SCANOUT))) {
+                       ADDR2_COMPUTE_PIPEBANKXOR_INPUT xin = {0};
+                       ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT xout = {0};
+
+                       xin.size = sizeof(ADDR2_COMPUTE_PIPEBANKXOR_INPUT);
+                       xout.size = sizeof(ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT);
+
+                       xin.surfIndex = p_atomic_inc_return(config->info.surf_index) - 1;
+                       xin.flags = in->flags;
+                       xin.swizzleMode = in->swizzleMode;
+                       xin.resourceType = in->resourceType;
+                       xin.format = in->format;
+                       xin.numSamples = in->numSamples;
+                       xin.numFrags = in->numFrags;
+
+                       ret = Addr2ComputePipeBankXor(addrlib, &xin, &xout);
+                       if (ret != ADDR_OK)
+                               return ret;
+
+                       assert(xout.pipeBankXor <=
+                              u_bit_consecutive(0, sizeof(surf->tile_swizzle) * 8));
+                       surf->tile_swizzle = xout.pipeBankXor;
+               }
+
                /* DCC */
                if (!(surf->flags & RADEON_SURF_DISABLE_DCC) &&
                    !compressed &&
@@ -1018,6 +1050,34 @@ static int gfx9_compute_miptree(ADDR_HANDLE addrlib,
                        surf->u.gfx9.fmask.epitch = fout.pitch - 1;
                        surf->u.gfx9.fmask_size = fout.fmaskBytes;
                        surf->u.gfx9.fmask_alignment = fout.baseAlign;
+
+                       /* Compute tile swizzle for the FMASK surface. */
+                       if (config->info.fmask_surf_index &&
+                           fin.swizzleMode >= ADDR_SW_64KB_Z_T &&
+                           !(surf->flags & RADEON_SURF_SHAREABLE)) {
+                               ADDR2_COMPUTE_PIPEBANKXOR_INPUT xin = {0};
+                               ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT xout = {0};
+
+                               xin.size = sizeof(ADDR2_COMPUTE_PIPEBANKXOR_INPUT);
+                               xout.size = sizeof(ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT);
+
+                               /* This counter starts from 1 instead of 0. */
+                               xin.surfIndex = p_atomic_inc_return(config->info.fmask_surf_index);
+                               xin.flags = in->flags;
+                               xin.swizzleMode = in->swizzleMode;
+                               xin.resourceType = in->resourceType;
+                               xin.format = in->format;
+                               xin.numSamples = in->numSamples;
+                               xin.numFrags = in->numFrags;
+
+                               ret = Addr2ComputePipeBankXor(addrlib, &xin, &xout);
+                               if (ret != ADDR_OK)
+                                       return ret;
+
+                               assert(xout.pipeBankXor <=
+                                      u_bit_consecutive(0, sizeof(surf->u.gfx9.fmask_tile_swizzle) * 8));
+                               surf->u.gfx9.fmask_tile_swizzle = xout.pipeBankXor;
+                       }
                }
 
                /* CMASK */
@@ -1084,6 +1144,25 @@ static int gfx9_compute_surface(ADDR_HANDLE addrlib,
                        assert(0);
                }
        } else {
+               switch (surf->bpe) {
+               case 1:
+                       AddrSurfInfoIn.format = ADDR_FMT_8;
+                       break;
+               case 2:
+                       AddrSurfInfoIn.format = ADDR_FMT_16;
+                       break;
+               case 4:
+                       AddrSurfInfoIn.format = ADDR_FMT_32;
+                       break;
+               case 8:
+                       AddrSurfInfoIn.format = ADDR_FMT_32_32;
+                       break;
+               case 16:
+                       AddrSurfInfoIn.format = ADDR_FMT_32_32_32_32;
+                       break;
+               default:
+                       assert(0);
+               }
                AddrSurfInfoIn.bpp = surf->bpe * 8;
        }
 
@@ -1155,7 +1234,8 @@ static int gfx9_compute_surface(ADDR_HANDLE addrlib,
        surf->u.gfx9.cmask_size = 0;
 
        /* Calculate texture layout information. */
-       r = gfx9_compute_miptree(addrlib, surf, compressed, &AddrSurfInfoIn);
+       r = gfx9_compute_miptree(addrlib, config, surf, compressed,
+                                &AddrSurfInfoIn);
        if (r)
                return r;
 
@@ -1172,7 +1252,8 @@ static int gfx9_compute_surface(ADDR_HANDLE addrlib,
                } else
                        AddrSurfInfoIn.flags.depth = 0;
 
-               r = gfx9_compute_miptree(addrlib, surf, compressed, &AddrSurfInfoIn);
+               r = gfx9_compute_miptree(addrlib, config, surf, compressed,
+                                        &AddrSurfInfoIn);
                if (r)
                        return r;
        }
index f18548f73e46e245dea38315eb95952379a146dc..71f320af8eeb0e01f8383ac8cde9abb534239f15 100644 (file)
@@ -147,6 +147,8 @@ struct gfx9_surf_layout {
 
     uint32_t                    fmask_alignment;
     uint32_t                    cmask_alignment;
+
+    uint8_t                     fmask_tile_swizzle;
 };
 
 struct radeon_surf {
@@ -175,7 +177,8 @@ struct radeon_surf {
     /* Tile swizzle can be OR'd with low bits of the BASE_256B address.
      * The value is the same for all mipmap levels. Supported tile modes:
      * - GFX6: Only macro tiling.
-     * - GFX9: Only *_X swizzle modes. Level 0 must not be in the mip tail.
+     * - GFX9: Only *_X and *_T swizzle modes. Level 0 must not be in the mip
+     *   tail.
      *
      * Only these surfaces are allowed to set it:
      * - color (if it doesn't have to be displayable)
@@ -218,6 +221,7 @@ struct ac_surf_info {
        uint8_t levels;
        uint16_t array_size;
        uint32_t *surf_index; /* Set a monotonic counter for tile swizzling. */
+       uint32_t *fmask_surf_index; /* GFX9+ */
 };
 
 struct ac_surf_config {
index 125e7ef4089105233293f6542a58607e8d5fdd19..3a0a79187b8a667268d93e36a0d025259fdbca4f 100644 (file)
@@ -848,6 +848,7 @@ void si_texture_get_fmask_info(struct si_screen *sscreen,
        if (sscreen->info.chip_class >= GFX9) {
                out->alignment = rtex->surface.u.gfx9.fmask_alignment;
                out->size = rtex->surface.u.gfx9.fmask_size;
+               out->tile_swizzle = rtex->surface.u.gfx9.fmask_tile_swizzle;
                return;
        }
 
index fabc6ccd93bf0d8dd8a20996f977fd999b98df95..fc5c9d5a127eb416d0b6a90c588a1af4c46eb001 100644 (file)
@@ -100,6 +100,8 @@ static int amdgpu_surface_init(struct radeon_winsys *rws,
    else
       config.info.surf_index = NULL;
 
+   config.info.fmask_surf_index = &ws->surf_index_fmask;
+
    return ac_compute_surface(ws->addrlib, &ws->info, &config, mode, surf);
 }