ac/surface: don't set the display flag for obviously unsupported cases (v2)
[mesa.git] / src / amd / common / ac_surface.c
index 81882576bafeb55c23c3081fd84a23f1489e74a4..1b4d72e31bd25f34926fdd026c3a15758fc9d518 100644 (file)
@@ -275,7 +275,7 @@ static int gfx6_compute_level(ADDR_HANDLE addrlib,
            AddrSurfInfoIn->bpp) {
                unsigned alignment = 256 / (AddrSurfInfoIn->bpp / 8);
 
-               assert(util_is_power_of_two(AddrSurfInfoIn->bpp));
+               assert(util_is_power_of_two_or_zero(AddrSurfInfoIn->bpp));
                AddrSurfInfoIn->width = align(AddrSurfInfoIn->width, alignment);
        }
 
@@ -415,6 +415,31 @@ static unsigned cik_get_macro_tile_index(struct radeon_surf *surf)
        return index;
 }
 
+static bool get_display_flag(const struct ac_surf_config *config,
+                            const struct radeon_surf *surf)
+{
+       unsigned num_channels = config->info.num_channels;
+       unsigned bpe = surf->bpe;
+
+       if (surf->flags & RADEON_SURF_SCANOUT &&
+           !(surf->flags & RADEON_SURF_FMASK) &&
+           config->info.samples <= 1 &&
+           surf->blk_w <= 2 && surf->blk_h == 1) {
+               /* subsampled */
+               if (surf->blk_w == 2 && surf->blk_h == 1)
+                       return true;
+
+               if  (/* RGBA8 or RGBA16F */
+                    (bpe >= 4 && bpe <= 8 && num_channels == 4) ||
+                    /* R5G6B5 or R5G5B5A1 */
+                    (bpe == 2 && num_channels >= 3) ||
+                    /* C8 palette */
+                    (bpe == 1 && num_channels == 1))
+                       return true;
+       }
+       return false;
+}
+
 /**
  * This must be called after the first level is computed.
  *
@@ -449,7 +474,7 @@ static int gfx6_surface_settings(ADDR_HANDLE addrlib,
            config->info.surf_index &&
            surf->u.legacy.level[0].mode == RADEON_SURF_MODE_2D &&
            !(surf->flags & (RADEON_SURF_Z_OR_SBUFFER | RADEON_SURF_SHAREABLE)) &&
-           (config->info.samples > 1 || !(surf->flags & RADEON_SURF_SCANOUT))) {
+           !get_display_flag(config, surf)) {
                ADDR_COMPUTE_BASE_SWIZZLE_INPUT AddrBaseSwizzleIn = {0};
                ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT AddrBaseSwizzleOut = {0};
 
@@ -568,7 +593,7 @@ static int gfx6_compute_surface(ADDR_HANDLE addrlib,
        AddrSurfInfoIn.flags.depth = (surf->flags & RADEON_SURF_ZBUFFER) != 0;
        AddrSurfInfoIn.flags.cube = config->is_cube;
        AddrSurfInfoIn.flags.fmask = (surf->flags & RADEON_SURF_FMASK) != 0;
-       AddrSurfInfoIn.flags.display = (surf->flags & RADEON_SURF_SCANOUT) != 0;
+       AddrSurfInfoIn.flags.display = get_display_flag(config, surf);
        AddrSurfInfoIn.flags.pow2Pad = config->info.levels > 1;
        AddrSurfInfoIn.flags.tcCompatible = (surf->flags & RADEON_SURF_TC_COMPATIBLE_HTILE) != 0;
 
@@ -814,7 +839,8 @@ static int gfx6_compute_surface(ADDR_HANDLE addrlib,
 static int
 gfx9_get_preferred_swizzle_mode(ADDR_HANDLE addrlib,
                                ADDR2_COMPUTE_SURFACE_INFO_INPUT *in,
-                               bool is_fmask, AddrSwizzleMode *swizzle_mode)
+                               bool is_fmask, unsigned flags,
+                               AddrSwizzleMode *swizzle_mode)
 {
        ADDR_E_RETURNCODE ret;
        ADDR2_GET_PREFERRED_SURF_SETTING_INPUT sin = {0};
@@ -839,7 +865,15 @@ gfx9_get_preferred_swizzle_mode(ADDR_HANDLE addrlib,
        sin.numSamples = in->numSamples;
        sin.numFrags = in->numFrags;
 
+       if (flags & RADEON_SURF_SCANOUT)
+               sin.preferredSwSet.sw_D = 1;
+       else if (in->flags.depth || in->flags.stencil || is_fmask)
+               sin.preferredSwSet.sw_Z = 1;
+       else
+               sin.preferredSwSet.sw_S = 1;
+
        if (is_fmask) {
+               sin.flags.display = 0;
                sin.flags.color = 0;
                sin.flags.fmask = 1;
        }
@@ -935,7 +969,7 @@ static int gfx9_compute_miptree(ADDR_HANDLE addrlib,
                    in->swizzleMode >= ADDR_SW_64KB_Z_T &&
                    !out.mipChainInTail &&
                    !(surf->flags & RADEON_SURF_SHAREABLE) &&
-                   (in->numSamples > 1 || !(surf->flags & RADEON_SURF_SCANOUT))) {
+                   !in->flags.display) {
                        ADDR2_COMPUTE_PIPEBANKXOR_INPUT xin = {0};
                        ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT xout = {0};
 
@@ -1036,7 +1070,9 @@ static int gfx9_compute_miptree(ADDR_HANDLE addrlib,
                        fin.size = sizeof(ADDR2_COMPUTE_FMASK_INFO_INPUT);
                        fout.size = sizeof(ADDR2_COMPUTE_FMASK_INFO_OUTPUT);
 
-                       ret = gfx9_get_preferred_swizzle_mode(addrlib, in, true, &fin.swizzleMode);
+                       ret = gfx9_get_preferred_swizzle_mode(addrlib, in,
+                                                             true, surf->flags,
+                                                             &fin.swizzleMode);
                        if (ret != ADDR_OK)
                                return ret;
 
@@ -1186,7 +1222,7 @@ static int gfx9_compute_surface(ADDR_HANDLE addrlib,
 
        AddrSurfInfoIn.flags.color = !(surf->flags & RADEON_SURF_Z_OR_SBUFFER);
        AddrSurfInfoIn.flags.depth = (surf->flags & RADEON_SURF_ZBUFFER) != 0;
-       AddrSurfInfoIn.flags.display = (surf->flags & RADEON_SURF_SCANOUT) != 0;
+       AddrSurfInfoIn.flags.display = get_display_flag(config, surf);
        /* flags.texture currently refers to TC-compatible HTILE */
        AddrSurfInfoIn.flags.texture = AddrSurfInfoIn.flags.color ||
                                       surf->flags & RADEON_SURF_TC_COMPATIBLE_HTILE;
@@ -1232,7 +1268,8 @@ static int gfx9_compute_surface(ADDR_HANDLE addrlib,
                        break;
                }
 
-               r = gfx9_get_preferred_swizzle_mode(addrlib, &AddrSurfInfoIn, false,
+               r = gfx9_get_preferred_swizzle_mode(addrlib, &AddrSurfInfoIn,
+                                                   false, surf->flags,
                                                    &AddrSurfInfoIn.swizzleMode);
                if (r)
                        return r;
@@ -1268,7 +1305,8 @@ static int gfx9_compute_surface(ADDR_HANDLE addrlib,
                AddrSurfInfoIn.format = ADDR_FMT_8;
 
                if (!AddrSurfInfoIn.flags.depth) {
-                       r = gfx9_get_preferred_swizzle_mode(addrlib, &AddrSurfInfoIn, false,
+                       r = gfx9_get_preferred_swizzle_mode(addrlib, &AddrSurfInfoIn,
+                                                           false, surf->flags,
                                                            &AddrSurfInfoIn.swizzleMode);
                        if (r)
                                return r;