From: Marek Olšák <marek.ol...@amd.com>

This enables the tile swizzle for some cases of the displayable micro mode,
and it also fixes an addrlib assertion failure on Vega.
---
 src/amd/common/ac_surface.c                    | 34 +++++++++++++++++++++++---
 src/amd/common/ac_surface.h                    |  1 +
 src/amd/vulkan/radv_image.c                    |  1 +
 src/gallium/winsys/amdgpu/drm/amdgpu_surface.c |  1 +
 4 files changed, 33 insertions(+), 4 deletions(-)

diff --git a/src/amd/common/ac_surface.c b/src/amd/common/ac_surface.c
index b294cd85259..1b4d72e31bd 100644
--- a/src/amd/common/ac_surface.c
+++ b/src/amd/common/ac_surface.c
@@ -408,20 +408,45 @@ static unsigned cik_get_macro_tile_index(struct 
radeon_surf *surf)
        tileb = 8 * 8 * surf->bpe;
        tileb = MIN2(surf->u.legacy.tile_split, tileb);
 
        for (index = 0; tileb > 64; index++)
                tileb >>= 1;
 
        assert(index < 16);
        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.
  *
  * Copy surface-global settings like pipe/bank config from level 0 surface
  * computation, and compute tile swizzle.
  */
 static int gfx6_surface_settings(ADDR_HANDLE addrlib,
                                 const struct radeon_info *info,
                                 const struct ac_surf_config *config,
                                 ADDR_COMPUTE_SURFACE_INFO_OUTPUT* csio,
@@ -442,21 +467,21 @@ static int gfx6_surface_settings(ADDR_HANDLE addrlib,
        } else {
                surf->u.legacy.macro_tile_index = 0;
        }
 
        /* Compute tile swizzle. */
        /* TODO: fix tile swizzle with mipmapping for SI */
        if ((info->chip_class >= CIK || config->info.levels == 1) &&
            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};
 
                AddrBaseSwizzleIn.size = 
sizeof(ADDR_COMPUTE_BASE_SWIZZLE_INPUT);
                AddrBaseSwizzleOut.size = 
sizeof(ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT);
 
                AddrBaseSwizzleIn.surfIndex = 
p_atomic_inc_return(config->info.surf_index) - 1;
                AddrBaseSwizzleIn.tileIndex = csio->tileIndex;
                AddrBaseSwizzleIn.macroModeIndex = csio->macroModeIndex;
                AddrBaseSwizzleIn.pTileInfo = csio->pTileInfo;
@@ -561,21 +586,21 @@ static int gfx6_compute_surface(ADDR_HANDLE addrlib,
                AddrSurfInfoIn.tileType = ADDR_DISPLAYABLE;
        else if (surf->flags & (RADEON_SURF_Z_OR_SBUFFER | RADEON_SURF_FMASK))
                AddrSurfInfoIn.tileType = ADDR_DEPTH_SAMPLE_ORDER;
        else
                AddrSurfInfoIn.tileType = ADDR_NON_DISPLAYABLE;
 
        AddrSurfInfoIn.flags.color = !(surf->flags & RADEON_SURF_Z_OR_SBUFFER);
        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;
 
        /* Only degrade the tile mode for space if TC-compatible HTILE hasn't 
been
         * requested, because TC-compatible HTILE requires 2D tiling.
         */
        AddrSurfInfoIn.flags.opt4Space = !AddrSurfInfoIn.flags.tcCompatible &&
                                         !AddrSurfInfoIn.flags.fmask &&
                                         config->info.samples <= 1 &&
                                         (surf->flags & 
RADEON_SURF_OPTIMIZE_FOR_SPACE);
@@ -841,20 +866,21 @@ gfx9_get_preferred_swizzle_mode(ADDR_HANDLE addrlib,
        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;
        }
 
        ret = Addr2GetPreferredSurfaceSetting(addrlib, &sin, &sout);
        if (ret != ADDR_OK)
                return ret;
 
        *swizzle_mode = sout.swizzleMode;
        return 0;
@@ -936,21 +962,21 @@ 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))) {
+                   !in->flags.display) {
                        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;
@@ -1189,21 +1215,21 @@ static int gfx9_compute_surface(ADDR_HANDLE addrlib,
                        AddrSurfInfoIn.format = ADDR_FMT_32_32_32_32;
                        break;
                default:
                        assert(0);
                }
                AddrSurfInfoIn.bpp = surf->bpe * 8;
        }
 
        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;
        AddrSurfInfoIn.flags.opt4space = 1;
 
        AddrSurfInfoIn.numMipLevels = config->info.levels;
        AddrSurfInfoIn.numSamples = config->info.samples ? config->info.samples 
: 1;
        AddrSurfInfoIn.numFrags = AddrSurfInfoIn.numSamples;
 
        /* GFX9 doesn't support 1D depth textures, so allocate all 1D textures
diff --git a/src/amd/common/ac_surface.h b/src/amd/common/ac_surface.h
index 71f320af8ee..37df859e6de 100644
--- a/src/amd/common/ac_surface.h
+++ b/src/amd/common/ac_surface.h
@@ -212,20 +212,21 @@ struct radeon_surf {
         struct gfx9_surf_layout gfx9;
     } u;
 };
 
 struct ac_surf_info {
        uint32_t width;
        uint32_t height;
        uint32_t depth;
        uint8_t samples;
        uint8_t levels;
+       uint8_t num_channels; /* heuristic for displayability */
        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 {
        struct ac_surf_info info;
        unsigned is_3d : 1;
        unsigned is_cube : 1;
 };
diff --git a/src/amd/vulkan/radv_image.c b/src/amd/vulkan/radv_image.c
index dd3189c67d0..ef6f1072abd 100644
--- a/src/amd/vulkan/radv_image.c
+++ b/src/amd/vulkan/radv_image.c
@@ -919,20 +919,21 @@ radv_image_create(VkDevice _device,
        if (!image)
                return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
 
        image->type = pCreateInfo->imageType;
        image->info.width = pCreateInfo->extent.width;
        image->info.height = pCreateInfo->extent.height;
        image->info.depth = pCreateInfo->extent.depth;
        image->info.samples = pCreateInfo->samples;
        image->info.array_size = pCreateInfo->arrayLayers;
        image->info.levels = pCreateInfo->mipLevels;
+       image->info.num_channels = 4; /* TODO: set this correctly */
 
        image->vk_format = pCreateInfo->format;
        image->tiling = pCreateInfo->tiling;
        image->usage = pCreateInfo->usage;
        image->flags = pCreateInfo->flags;
 
        image->exclusive = pCreateInfo->sharingMode == 
VK_SHARING_MODE_EXCLUSIVE;
        if (pCreateInfo->sharingMode == VK_SHARING_MODE_CONCURRENT) {
                for (uint32_t i = 0; i < pCreateInfo->queueFamilyIndexCount; 
++i)
                        if (pCreateInfo->pQueueFamilyIndices[i] == 
VK_QUEUE_FAMILY_EXTERNAL_KHR)
diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c 
b/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c
index fc5c9d5a127..b5a1ebb1628 100644
--- a/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c
+++ b/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c
@@ -79,20 +79,21 @@ static int amdgpu_surface_init(struct radeon_winsys *rws,
    surf->flags = flags;
 
    struct ac_surf_config config;
 
    config.info.width = tex->width0;
    config.info.height = tex->height0;
    config.info.depth = tex->depth0;
    config.info.array_size = tex->array_size;
    config.info.samples = tex->nr_samples;
    config.info.levels = tex->last_level + 1;
+   config.info.num_channels = util_format_get_nr_components(tex->format);
    config.is_3d = !!(tex->target == PIPE_TEXTURE_3D);
    config.is_cube = !!(tex->target == PIPE_TEXTURE_CUBE);
 
    /* Use different surface counters for color and FMASK, so that MSAA MRTs
     * always use consecutive surface indices when FMASK is allocated between
     * them.
     */
    if (flags & RADEON_SURF_FMASK)
       config.info.surf_index = &ws->surf_index_fmask;
    else if (!(flags & RADEON_SURF_Z_OR_SBUFFER))
-- 
2.15.1

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to