return 0;
 }
+
+static unsigned eg_tile_split(unsigned tile_split)
+{
+   switch (tile_split) {
+   case 0:     tile_split = 64;    break;
+   case 1:     tile_split = 128;   break;
+   case 2:     tile_split = 256;   break;
+   case 3:     tile_split = 512;   break;
+   default:
+   case 4:     tile_split = 1024;  break;
+   case 5:     tile_split = 2048;  break;
+   case 6:     tile_split = 4096;  break;
+   }
+   return tile_split;
+}
+
+static unsigned eg_tile_split_rev(unsigned eg_tile_split)
+{
+   switch (eg_tile_split) {
+   case 64:    return 0;
+   case 128:   return 1;
+   case 256:   return 2;
+   case 512:   return 3;
+   default:
+   case 1024:  return 4;
+   case 2048:  return 5;
+   case 4096:  return 6;
+   }
+}
+
+#define AMDGPU_TILING_DCC_MAX_COMPRESSED_BLOCK_SIZE_SHIFT  45
+#define AMDGPU_TILING_DCC_MAX_COMPRESSED_BLOCK_SIZE_MASK   0x3
+
+/* This should be called before ac_compute_surface. */
+void ac_surface_set_bo_metadata(const struct radeon_info *info,
+                                struct radeon_surf *surf, uint64_t tiling_flags,
+                                enum radeon_surf_mode *mode)
+{
+   bool scanout;
+
+   if (info->chip_class >= GFX9) {
+      surf->u.gfx9.surf.swizzle_mode = AMDGPU_TILING_GET(tiling_flags, SWIZZLE_MODE);
+      surf->u.gfx9.dcc.independent_64B_blocks = AMDGPU_TILING_GET(tiling_flags, DCC_INDEPENDENT_64B);
+      surf->u.gfx9.dcc.independent_128B_blocks = AMDGPU_TILING_GET(tiling_flags, DCC_INDEPENDENT_128B);
+      surf->u.gfx9.dcc.max_compressed_block_size = AMDGPU_TILING_GET(tiling_flags, DCC_MAX_COMPRESSED_BLOCK_SIZE);
+      surf->u.gfx9.display_dcc_pitch_max = AMDGPU_TILING_GET(tiling_flags, DCC_PITCH_MAX);
+      scanout = AMDGPU_TILING_GET(tiling_flags, SCANOUT);
+      *mode = surf->u.gfx9.surf.swizzle_mode > 0 ? RADEON_SURF_MODE_2D : RADEON_SURF_MODE_LINEAR_ALIGNED;
+   } else {
+      surf->u.legacy.pipe_config = AMDGPU_TILING_GET(tiling_flags, PIPE_CONFIG);
+      surf->u.legacy.bankw = 1 << AMDGPU_TILING_GET(tiling_flags, BANK_WIDTH);
+      surf->u.legacy.bankh = 1 << AMDGPU_TILING_GET(tiling_flags, BANK_HEIGHT);
+      surf->u.legacy.tile_split = eg_tile_split(AMDGPU_TILING_GET(tiling_flags, TILE_SPLIT));
+      surf->u.legacy.mtilea = 1 << AMDGPU_TILING_GET(tiling_flags, MACRO_TILE_ASPECT);
+      surf->u.legacy.num_banks = 2 << AMDGPU_TILING_GET(tiling_flags, NUM_BANKS);
+      scanout = AMDGPU_TILING_GET(tiling_flags, MICRO_TILE_MODE) == 0; /* DISPLAY */
+
+      if (AMDGPU_TILING_GET(tiling_flags, ARRAY_MODE) == 4)  /* 2D_TILED_THIN1 */
+         *mode = RADEON_SURF_MODE_2D;
+      else if (AMDGPU_TILING_GET(tiling_flags, ARRAY_MODE) == 2) /* 1D_TILED_THIN1 */
+         *mode = RADEON_SURF_MODE_1D;
+      else
+         *mode = RADEON_SURF_MODE_LINEAR_ALIGNED;
+   }
+
+   if (scanout)
+      surf->flags |= RADEON_SURF_SCANOUT;
+   else
+      surf->flags &= ~RADEON_SURF_SCANOUT;
+}
+
+void ac_surface_get_bo_metadata(const struct radeon_info *info,
+                                struct radeon_surf *surf, uint64_t *tiling_flags)
+{
+   *tiling_flags = 0;
+
+   if (info->chip_class >= GFX9) {
+      uint64_t dcc_offset = 0;
+
+      if (surf->dcc_offset) {
+         uint64_t dcc_offset = surf->display_dcc_offset ? surf->display_dcc_offset
+                                                        : surf->dcc_offset;
+         assert((dcc_offset >> 8) != 0 && (dcc_offset >> 8) < (1 << 24));
+      }
+
+      *tiling_flags |= AMDGPU_TILING_SET(SWIZZLE_MODE, surf->u.gfx9.surf.swizzle_mode);
+      *tiling_flags |= AMDGPU_TILING_SET(DCC_OFFSET_256B, dcc_offset >> 8);
+      *tiling_flags |= AMDGPU_TILING_SET(DCC_PITCH_MAX, surf->u.gfx9.display_dcc_pitch_max);
+      *tiling_flags |= AMDGPU_TILING_SET(DCC_INDEPENDENT_64B, surf->u.gfx9.dcc.independent_64B_blocks);
+      *tiling_flags |= AMDGPU_TILING_SET(DCC_INDEPENDENT_128B, surf->u.gfx9.dcc.independent_128B_blocks);
+      *tiling_flags |= AMDGPU_TILING_SET(DCC_MAX_COMPRESSED_BLOCK_SIZE, surf->u.gfx9.dcc.max_compressed_block_size);
+      *tiling_flags |= AMDGPU_TILING_SET(SCANOUT, (surf->flags & RADEON_SURF_SCANOUT) != 0);
+   } else {
+      if (surf->u.legacy.level[0].mode >= RADEON_SURF_MODE_2D)
+         *tiling_flags |= AMDGPU_TILING_SET(ARRAY_MODE, 4); /* 2D_TILED_THIN1 */
+      else if (surf->u.legacy.level[0].mode >= RADEON_SURF_MODE_1D)
+         *tiling_flags |= AMDGPU_TILING_SET(ARRAY_MODE, 2); /* 1D_TILED_THIN1 */
+      else
+         *tiling_flags |= AMDGPU_TILING_SET(ARRAY_MODE, 1); /* LINEAR_ALIGNED */
+
+      *tiling_flags |= AMDGPU_TILING_SET(PIPE_CONFIG, surf->u.legacy.pipe_config);
+      *tiling_flags |= AMDGPU_TILING_SET(BANK_WIDTH, util_logbase2(surf->u.legacy.bankw));
+      *tiling_flags |= AMDGPU_TILING_SET(BANK_HEIGHT, util_logbase2(surf->u.legacy.bankh));
+      if (surf->u.legacy.tile_split)
+         *tiling_flags |= AMDGPU_TILING_SET(TILE_SPLIT, eg_tile_split_rev(surf->u.legacy.tile_split));
+      *tiling_flags |= AMDGPU_TILING_SET(MACRO_TILE_ASPECT, util_logbase2(surf->u.legacy.mtilea));
+      *tiling_flags |= AMDGPU_TILING_SET(NUM_BANKS, util_logbase2(surf->u.legacy.num_banks)-1);
+
+      if (surf->flags & RADEON_SURF_SCANOUT)
+         *tiling_flags |= AMDGPU_TILING_SET(MICRO_TILE_MODE, 0); /* DISPLAY_MICRO_TILING */
+      else
+         *tiling_flags |= AMDGPU_TILING_SET(MICRO_TILE_MODE, 1); /* THIN_MICRO_TILING */
+   }
+}
 
                       enum radeon_surf_mode mode,
                       struct radeon_surf *surf);
 
+void ac_surface_set_bo_metadata(const struct radeon_info *info,
+                                struct radeon_surf *surf, uint64_t tiling_flags,
+                                enum radeon_surf_mode *mode);
+void ac_surface_get_bo_metadata(const struct radeon_info *info,
+                                struct radeon_surf *surf, uint64_t *tiling_flags);
+
 #ifdef __cplusplus
 }
 #endif
 
     tiling.u.legacy.microtile = tex->tex.microtile;
     tiling.u.legacy.macrotile = tex->tex.macrotile[0];
     tiling.u.legacy.stride = tex->tex.stride_in_bytes[0];
-    rws->buffer_set_metadata(tex->buf, &tiling);
+    rws->buffer_set_metadata(tex->buf, &tiling, NULL);
 
     return tex;
 
     if (!buffer)
         return NULL;
 
-    rws->buffer_get_metadata(buffer, &tiling);
+    rws->buffer_get_metadata(buffer, &tiling, NULL);
 
     /* Enforce a microtiled zbuffer. */
     if (util_format_is_depth_or_stencil(base->format) &&
 
                if (!res->b.is_shared || update_metadata) {
                        r600_texture_init_metadata(rscreen, rtex, &metadata);
 
-                       rscreen->ws->buffer_set_metadata(res->buf, &metadata);
+                       rscreen->ws->buffer_set_metadata(res->buf, &metadata, NULL);
                }
 
                slice_size = (uint64_t)rtex->surface.u.legacy.level[0].slice_size_dw * 4;
        if (!buf)
                return NULL;
 
-       rscreen->ws->buffer_get_metadata(buf, &metadata);
+       rscreen->ws->buffer_get_metadata(buf, &metadata, NULL);
        r600_surface_import_metadata(rscreen, &surface, &metadata,
                                     &array_mode, &is_scanout);
 
        struct pb_buffer *buf = NULL;
 
        if (memobj->b.dedicated) {
-               rscreen->ws->buffer_get_metadata(memobj->buf, &metadata);
+               rscreen->ws->buffer_get_metadata(memobj->buf, &metadata, NULL);
                r600_surface_import_metadata(rscreen, &surface, &metadata,
                                     &array_mode, &is_scanout);
        } else {
 
          unsigned stride;
          bool scanout;
       } legacy;
-
-      struct {
-         /* surface flags */
-         unsigned swizzle_mode : 5;
-
-         /* DCC flags */
-         /* [31:8]: max offset = 4GB - 256; 0 = DCC disabled */
-         unsigned dcc_offset_256B : 24;
-         unsigned dcc_pitch_max : 14; /* (mip chain pitch - 1) for DCN */
-         unsigned dcc_independent_64B : 1;
-         unsigned dcc_independent_128B : 1;
-         unsigned dcc_max_compressed_block_size : 2;
-
-         bool scanout;
-      } gfx9;
    } u;
 
+   enum radeon_surf_mode mode;   /* Output from buffer_get_metadata */
+
    /* Additional metadata associated with the buffer, in bytes.
     * The maximum size is 64 * 4. This is opaque for the winsys & kernel.
     * Supported by amdgpu only.
     * \param buf       A winsys buffer object to get the flags from.
     * \param md        Metadata
     */
-   void (*buffer_get_metadata)(struct pb_buffer *buf, struct radeon_bo_metadata *md);
+   void (*buffer_get_metadata)(struct pb_buffer *buf, struct radeon_bo_metadata *md,
+                               struct radeon_surf *surf);
 
    /**
     * Set buffer metadata.
     * \param buf       A winsys buffer object to set the flags for.
     * \param md        Metadata
     */
-   void (*buffer_set_metadata)(struct pb_buffer *buf, struct radeon_bo_metadata *md);
+   void (*buffer_set_metadata)(struct pb_buffer *buf, struct radeon_bo_metadata *md,
+                               struct radeon_surf *surf);
 
    /**
     * Get a winsys buffer from a winsys handle. The internal structure
 
    return 0;
 }
 
-static void si_get_display_metadata(struct si_screen *sscreen, struct radeon_surf *surf,
-                                    struct radeon_bo_metadata *metadata,
-                                    enum radeon_surf_mode *array_mode, bool *is_scanout)
-{
-   if (sscreen->info.chip_class >= GFX9) {
-      if (metadata->u.gfx9.swizzle_mode > 0)
-         *array_mode = RADEON_SURF_MODE_2D;
-      else
-         *array_mode = RADEON_SURF_MODE_LINEAR_ALIGNED;
-
-      surf->u.gfx9.surf.swizzle_mode = metadata->u.gfx9.swizzle_mode;
-      surf->u.gfx9.dcc.independent_64B_blocks = metadata->u.gfx9.dcc_independent_64B;
-      surf->u.gfx9.dcc.independent_128B_blocks = metadata->u.gfx9.dcc_independent_128B;
-      surf->u.gfx9.dcc.max_compressed_block_size = metadata->u.gfx9.dcc_max_compressed_block_size;
-      surf->u.gfx9.display_dcc_pitch_max = metadata->u.gfx9.dcc_pitch_max;
-      *is_scanout = metadata->u.gfx9.scanout;
-   } else {
-      surf->u.legacy.pipe_config = metadata->u.legacy.pipe_config;
-      surf->u.legacy.bankw = metadata->u.legacy.bankw;
-      surf->u.legacy.bankh = metadata->u.legacy.bankh;
-      surf->u.legacy.tile_split = metadata->u.legacy.tile_split;
-      surf->u.legacy.mtilea = metadata->u.legacy.mtilea;
-      surf->u.legacy.num_banks = metadata->u.legacy.num_banks;
-
-      if (metadata->u.legacy.macrotile == RADEON_LAYOUT_TILED)
-         *array_mode = RADEON_SURF_MODE_2D;
-      else if (metadata->u.legacy.microtile == RADEON_LAYOUT_TILED)
-         *array_mode = RADEON_SURF_MODE_1D;
-      else
-         *array_mode = RADEON_SURF_MODE_LINEAR_ALIGNED;
-
-      *is_scanout = metadata->u.legacy.scanout;
-   }
-}
-
 void si_eliminate_fast_color_clear(struct si_context *sctx, struct si_texture *tex)
 {
    struct si_screen *sscreen = sctx->screen;
 
 static void si_set_tex_bo_metadata(struct si_screen *sscreen, struct si_texture *tex)
 {
-   struct radeon_surf *surface = &tex->surface;
    struct pipe_resource *res = &tex->buffer.b.b;
    struct radeon_bo_metadata md;
 
    memset(&md, 0, sizeof(md));
 
-   if (sscreen->info.chip_class >= GFX9) {
-      md.u.gfx9.swizzle_mode = surface->u.gfx9.surf.swizzle_mode;
-      md.u.gfx9.scanout = (surface->flags & RADEON_SURF_SCANOUT) != 0;
-
-      if (tex->surface.dcc_offset && !tex->dcc_separate_buffer) {
-         uint64_t dcc_offset = tex->surface.display_dcc_offset ? tex->surface.display_dcc_offset
-                                                               : tex->surface.dcc_offset;
-
-         assert((dcc_offset >> 8) != 0 && (dcc_offset >> 8) < (1 << 24));
-         md.u.gfx9.dcc_offset_256B = dcc_offset >> 8;
-         md.u.gfx9.dcc_pitch_max = tex->surface.u.gfx9.display_dcc_pitch_max;
-         md.u.gfx9.dcc_independent_64B = tex->surface.u.gfx9.dcc.independent_64B_blocks;
-         md.u.gfx9.dcc_independent_128B = tex->surface.u.gfx9.dcc.independent_128B_blocks;
-         md.u.gfx9.dcc_max_compressed_block_size = tex->surface.u.gfx9.dcc.max_compressed_block_size;
-      }
-   } else {
-      md.u.legacy.microtile = surface->u.legacy.level[0].mode >= RADEON_SURF_MODE_1D
-                                 ? RADEON_LAYOUT_TILED
-                                 : RADEON_LAYOUT_LINEAR;
-      md.u.legacy.macrotile = surface->u.legacy.level[0].mode >= RADEON_SURF_MODE_2D
-                                 ? RADEON_LAYOUT_TILED
-                                 : RADEON_LAYOUT_LINEAR;
-      md.u.legacy.pipe_config = surface->u.legacy.pipe_config;
-      md.u.legacy.bankw = surface->u.legacy.bankw;
-      md.u.legacy.bankh = surface->u.legacy.bankh;
-      md.u.legacy.tile_split = surface->u.legacy.tile_split;
-      md.u.legacy.mtilea = surface->u.legacy.mtilea;
-      md.u.legacy.num_banks = surface->u.legacy.num_banks;
-      md.u.legacy.stride = surface->u.legacy.level[0].nblk_x * surface->bpe;
-      md.u.legacy.scanout = (surface->flags & RADEON_SURF_SCANOUT) != 0;
-   }
-
    assert(tex->dcc_separate_buffer == NULL);
    assert(tex->surface.fmask_size == 0);
 
       md.size_metadata += (1 + res->last_level) * 4;
    }
 
-   sscreen->ws->buffer_set_metadata(tex->buffer.buf, &md);
+   sscreen->ws->buffer_set_metadata(tex->buffer.buf, &md, &tex->surface);
 }
 
 static bool si_read_tex_bo_metadata(struct si_screen *sscreen, struct si_texture *tex,
                                                            unsigned offset, unsigned usage,
                                                            bool dedicated)
 {
-   enum radeon_surf_mode array_mode;
    struct radeon_surf surface = {};
    struct radeon_bo_metadata metadata = {};
    struct si_texture *tex;
-   bool is_scanout;
    int r;
 
    /* Ignore metadata for non-zero planes. */
       dedicated = false;
 
    if (dedicated) {
-      sscreen->ws->buffer_get_metadata(buf, &metadata);
-      si_get_display_metadata(sscreen, &surface, &metadata, &array_mode, &is_scanout);
+      sscreen->ws->buffer_get_metadata(buf, &metadata, &surface);
    } else {
       /**
        * The bo metadata is unset for un-dedicated images. So we fall
        * tiling information when the TexParameter TEXTURE_TILING_EXT
        * is set.
        */
-      array_mode = RADEON_SURF_MODE_LINEAR_ALIGNED;
-      is_scanout = false;
+      metadata.mode = RADEON_SURF_MODE_LINEAR_ALIGNED;
    }
 
-   r =
-      si_init_surface(sscreen, &surface, templ, array_mode, stride, true, is_scanout, false, false);
+   r = si_init_surface(sscreen, &surface, templ, metadata.mode, stride, true,
+                       surface.flags & RADEON_SURF_SCANOUT, false, false);
    if (r)
       return NULL;
 
 
    return ok;
 }
 
-static unsigned eg_tile_split(unsigned tile_split)
-{
-   switch (tile_split) {
-   case 0:     tile_split = 64;    break;
-   case 1:     tile_split = 128;   break;
-   case 2:     tile_split = 256;   break;
-   case 3:     tile_split = 512;   break;
-   default:
-   case 4:     tile_split = 1024;  break;
-   case 5:     tile_split = 2048;  break;
-   case 6:     tile_split = 4096;  break;
-   }
-   return tile_split;
-}
-
-static unsigned eg_tile_split_rev(unsigned eg_tile_split)
-{
-   switch (eg_tile_split) {
-   case 64:    return 0;
-   case 128:   return 1;
-   case 256:   return 2;
-   case 512:   return 3;
-   default:
-   case 1024:  return 4;
-   case 2048:  return 5;
-   case 4096:  return 6;
-   }
-}
-
-#define AMDGPU_TILING_DCC_MAX_COMPRESSED_BLOCK_SIZE_SHIFT  45
-#define AMDGPU_TILING_DCC_MAX_COMPRESSED_BLOCK_SIZE_MASK   0x3
-
 static void amdgpu_buffer_get_metadata(struct pb_buffer *_buf,
-                                       struct radeon_bo_metadata *md)
+                                       struct radeon_bo_metadata *md,
+                                       struct radeon_surf *surf)
 {
    struct amdgpu_winsys_bo *bo = amdgpu_winsys_bo(_buf);
    struct amdgpu_bo_info info = {0};
-   uint64_t tiling_flags;
    int r;
 
    assert(bo->bo && "must not be called for slab entries");
    if (r)
       return;
 
-   tiling_flags = info.metadata.tiling_info;
-
-   if (bo->ws->info.chip_class >= GFX9) {
-      md->u.gfx9.swizzle_mode = AMDGPU_TILING_GET(tiling_flags, SWIZZLE_MODE);
-
-      md->u.gfx9.dcc_offset_256B = AMDGPU_TILING_GET(tiling_flags, DCC_OFFSET_256B);
-      md->u.gfx9.dcc_pitch_max = AMDGPU_TILING_GET(tiling_flags, DCC_PITCH_MAX);
-      md->u.gfx9.dcc_independent_64B = AMDGPU_TILING_GET(tiling_flags, DCC_INDEPENDENT_64B);
-      md->u.gfx9.dcc_independent_128B = AMDGPU_TILING_GET(tiling_flags, DCC_INDEPENDENT_128B);
-      md->u.gfx9.dcc_max_compressed_block_size = AMDGPU_TILING_GET(tiling_flags, DCC_MAX_COMPRESSED_BLOCK_SIZE);
-      md->u.gfx9.scanout = AMDGPU_TILING_GET(tiling_flags, SCANOUT);
-   } else {
-      md->u.legacy.microtile = RADEON_LAYOUT_LINEAR;
-      md->u.legacy.macrotile = RADEON_LAYOUT_LINEAR;
-
-      if (AMDGPU_TILING_GET(tiling_flags, ARRAY_MODE) == 4)  /* 2D_TILED_THIN1 */
-         md->u.legacy.macrotile = RADEON_LAYOUT_TILED;
-      else if (AMDGPU_TILING_GET(tiling_flags, ARRAY_MODE) == 2) /* 1D_TILED_THIN1 */
-         md->u.legacy.microtile = RADEON_LAYOUT_TILED;
-
-      md->u.legacy.pipe_config = AMDGPU_TILING_GET(tiling_flags, PIPE_CONFIG);
-      md->u.legacy.bankw = 1 << AMDGPU_TILING_GET(tiling_flags, BANK_WIDTH);
-      md->u.legacy.bankh = 1 << AMDGPU_TILING_GET(tiling_flags, BANK_HEIGHT);
-      md->u.legacy.tile_split = eg_tile_split(AMDGPU_TILING_GET(tiling_flags, TILE_SPLIT));
-      md->u.legacy.mtilea = 1 << AMDGPU_TILING_GET(tiling_flags, MACRO_TILE_ASPECT);
-      md->u.legacy.num_banks = 2 << AMDGPU_TILING_GET(tiling_flags, NUM_BANKS);
-      md->u.legacy.scanout = AMDGPU_TILING_GET(tiling_flags, MICRO_TILE_MODE) == 0; /* DISPLAY */
-   }
+   ac_surface_set_bo_metadata(&bo->ws->info, surf, info.metadata.tiling_info,
+                              &md->mode);
 
    md->size_metadata = info.metadata.size_metadata;
    memcpy(md->metadata, info.metadata.umd_metadata, sizeof(md->metadata));
 }
 
 static void amdgpu_buffer_set_metadata(struct pb_buffer *_buf,
-                                       struct radeon_bo_metadata *md)
+                                       struct radeon_bo_metadata *md,
+                                       struct radeon_surf *surf)
 {
    struct amdgpu_winsys_bo *bo = amdgpu_winsys_bo(_buf);
    struct amdgpu_bo_metadata metadata = {0};
-   uint64_t tiling_flags = 0;
 
    assert(bo->bo && "must not be called for slab entries");
 
-   if (bo->ws->info.chip_class >= GFX9) {
-      tiling_flags |= AMDGPU_TILING_SET(SWIZZLE_MODE, md->u.gfx9.swizzle_mode);
-
-      tiling_flags |= AMDGPU_TILING_SET(DCC_OFFSET_256B, md->u.gfx9.dcc_offset_256B);
-      tiling_flags |= AMDGPU_TILING_SET(DCC_PITCH_MAX, md->u.gfx9.dcc_pitch_max);
-      tiling_flags |= AMDGPU_TILING_SET(DCC_INDEPENDENT_64B, md->u.gfx9.dcc_independent_64B);
-      tiling_flags |= AMDGPU_TILING_SET(DCC_INDEPENDENT_128B, md->u.gfx9.dcc_independent_128B);
-      tiling_flags |= AMDGPU_TILING_SET(DCC_MAX_COMPRESSED_BLOCK_SIZE, md->u.gfx9.dcc_max_compressed_block_size);
-      tiling_flags |= AMDGPU_TILING_SET(SCANOUT, md->u.gfx9.scanout);
-   } else {
-      if (md->u.legacy.macrotile == RADEON_LAYOUT_TILED)
-         tiling_flags |= AMDGPU_TILING_SET(ARRAY_MODE, 4); /* 2D_TILED_THIN1 */
-      else if (md->u.legacy.microtile == RADEON_LAYOUT_TILED)
-         tiling_flags |= AMDGPU_TILING_SET(ARRAY_MODE, 2); /* 1D_TILED_THIN1 */
-      else
-         tiling_flags |= AMDGPU_TILING_SET(ARRAY_MODE, 1); /* LINEAR_ALIGNED */
-
-      tiling_flags |= AMDGPU_TILING_SET(PIPE_CONFIG, md->u.legacy.pipe_config);
-      tiling_flags |= AMDGPU_TILING_SET(BANK_WIDTH, util_logbase2(md->u.legacy.bankw));
-      tiling_flags |= AMDGPU_TILING_SET(BANK_HEIGHT, util_logbase2(md->u.legacy.bankh));
-      if (md->u.legacy.tile_split)
-         tiling_flags |= AMDGPU_TILING_SET(TILE_SPLIT, eg_tile_split_rev(md->u.legacy.tile_split));
-      tiling_flags |= AMDGPU_TILING_SET(MACRO_TILE_ASPECT, util_logbase2(md->u.legacy.mtilea));
-      tiling_flags |= AMDGPU_TILING_SET(NUM_BANKS, util_logbase2(md->u.legacy.num_banks)-1);
-
-      if (md->u.legacy.scanout)
-         tiling_flags |= AMDGPU_TILING_SET(MICRO_TILE_MODE, 0); /* DISPLAY_MICRO_TILING */
-      else
-         tiling_flags |= AMDGPU_TILING_SET(MICRO_TILE_MODE, 1); /* THIN_MICRO_TILING */
-   }
+   ac_surface_get_bo_metadata(&bo->ws->info, surf, &metadata.tiling_info);
 
-   metadata.tiling_info = tiling_flags;
    metadata.size_metadata = md->size_metadata;
    memcpy(metadata.umd_metadata, md->metadata, sizeof(md->metadata));
 
 
 }
 
 static void radeon_bo_get_metadata(struct pb_buffer *_buf,
-                                   struct radeon_bo_metadata *md)
+                                   struct radeon_bo_metadata *md,
+                                   struct radeon_surf *surf)
 {
    struct radeon_bo *bo = radeon_bo(_buf);
    struct drm_radeon_gem_set_tiling args;
                        &args,
                        sizeof(args));
 
+   if (surf) {
+      if (args.tiling_flags & RADEON_TILING_MACRO)
+         md->mode = RADEON_SURF_MODE_2D;
+      else if (args.tiling_flags & RADEON_TILING_MICRO)
+         md->mode = RADEON_SURF_MODE_1D;
+      else
+         md->mode = RADEON_SURF_MODE_LINEAR_ALIGNED;
+
+      surf->u.legacy.bankw = (args.tiling_flags >> RADEON_TILING_EG_BANKW_SHIFT) & RADEON_TILING_EG_BANKW_MASK;
+      surf->u.legacy.bankh = (args.tiling_flags >> RADEON_TILING_EG_BANKH_SHIFT) & RADEON_TILING_EG_BANKH_MASK;
+      surf->u.legacy.tile_split = (args.tiling_flags >> RADEON_TILING_EG_TILE_SPLIT_SHIFT) & RADEON_TILING_EG_TILE_SPLIT_MASK;
+      surf->u.legacy.tile_split = eg_tile_split(surf->u.legacy.tile_split);
+      surf->u.legacy.mtilea = (args.tiling_flags >> RADEON_TILING_EG_MACRO_TILE_ASPECT_SHIFT) & RADEON_TILING_EG_MACRO_TILE_ASPECT_MASK;
+
+      if (bo->rws->gen >= DRV_SI && !(args.tiling_flags & RADEON_TILING_R600_NO_SCANOUT))
+         surf->flags |= RADEON_SURF_SCANOUT;
+      else
+         surf->flags &= ~RADEON_SURF_SCANOUT;
+      return;
+   }
+
    md->u.legacy.microtile = RADEON_LAYOUT_LINEAR;
    md->u.legacy.macrotile = RADEON_LAYOUT_LINEAR;
    if (args.tiling_flags & RADEON_TILING_MICRO)
 }
 
 static void radeon_bo_set_metadata(struct pb_buffer *_buf,
-                                   struct radeon_bo_metadata *md)
+                                   struct radeon_bo_metadata *md,
+                                   struct radeon_surf *surf)
 {
    struct radeon_bo *bo = radeon_bo(_buf);
    struct drm_radeon_gem_set_tiling args;
 
    os_wait_until_zero(&bo->num_active_ioctls, PIPE_TIMEOUT_INFINITE);
 
-   if (md->u.legacy.microtile == RADEON_LAYOUT_TILED)
-      args.tiling_flags |= RADEON_TILING_MICRO;
-   else if (md->u.legacy.microtile == RADEON_LAYOUT_SQUARETILED)
-      args.tiling_flags |= RADEON_TILING_MICRO_SQUARE;
-
-   if (md->u.legacy.macrotile == RADEON_LAYOUT_TILED)
-      args.tiling_flags |= RADEON_TILING_MACRO;
-
-   args.tiling_flags |= (md->u.legacy.bankw & RADEON_TILING_EG_BANKW_MASK) <<
-                                                                              RADEON_TILING_EG_BANKW_SHIFT;
-   args.tiling_flags |= (md->u.legacy.bankh & RADEON_TILING_EG_BANKH_MASK) <<
-                                                                              RADEON_TILING_EG_BANKH_SHIFT;
-   if (md->u.legacy.tile_split) {
-      args.tiling_flags |= (eg_tile_split_rev(md->u.legacy.tile_split) &
-                            RADEON_TILING_EG_TILE_SPLIT_MASK) <<
-                                                                 RADEON_TILING_EG_TILE_SPLIT_SHIFT;
-   }
-   args.tiling_flags |= (md->u.legacy.mtilea & RADEON_TILING_EG_MACRO_TILE_ASPECT_MASK) <<
-                                                                                           RADEON_TILING_EG_MACRO_TILE_ASPECT_SHIFT;
+   if (surf) {
+      if (surf->u.legacy.level[0].mode >= RADEON_SURF_MODE_1D)
+         args.tiling_flags |= RADEON_TILING_MICRO;
+      if (surf->u.legacy.level[0].mode >= RADEON_SURF_MODE_2D)
+         args.tiling_flags |= RADEON_TILING_MACRO;
+
+      args.tiling_flags |= (surf->u.legacy.bankw & RADEON_TILING_EG_BANKW_MASK) <<
+                           RADEON_TILING_EG_BANKW_SHIFT;
+      args.tiling_flags |= (surf->u.legacy.bankh & RADEON_TILING_EG_BANKH_MASK) <<
+                           RADEON_TILING_EG_BANKH_SHIFT;
+      if (surf->u.legacy.tile_split) {
+         args.tiling_flags |= (eg_tile_split_rev(surf->u.legacy.tile_split) &
+                               RADEON_TILING_EG_TILE_SPLIT_MASK) <<
+                              RADEON_TILING_EG_TILE_SPLIT_SHIFT;
+      }
+      args.tiling_flags |= (surf->u.legacy.mtilea & RADEON_TILING_EG_MACRO_TILE_ASPECT_MASK) <<
+                           RADEON_TILING_EG_MACRO_TILE_ASPECT_SHIFT;
+
+      if (bo->rws->gen >= DRV_SI && !(surf->flags & RADEON_SURF_SCANOUT))
+         args.tiling_flags |= RADEON_TILING_R600_NO_SCANOUT;
 
-   if (bo->rws->gen >= DRV_SI && !md->u.legacy.scanout)
-      args.tiling_flags |= RADEON_TILING_R600_NO_SCANOUT;
+      args.pitch = surf->u.legacy.level[0].nblk_x * surf->bpe;
+   } else {
+      if (md->u.legacy.microtile == RADEON_LAYOUT_TILED)
+         args.tiling_flags |= RADEON_TILING_MICRO;
+      else if (md->u.legacy.microtile == RADEON_LAYOUT_SQUARETILED)
+         args.tiling_flags |= RADEON_TILING_MICRO_SQUARE;
+
+      if (md->u.legacy.macrotile == RADEON_LAYOUT_TILED)
+         args.tiling_flags |= RADEON_TILING_MACRO;
+
+      args.tiling_flags |= (md->u.legacy.bankw & RADEON_TILING_EG_BANKW_MASK) <<
+                           RADEON_TILING_EG_BANKW_SHIFT;
+      args.tiling_flags |= (md->u.legacy.bankh & RADEON_TILING_EG_BANKH_MASK) <<
+                           RADEON_TILING_EG_BANKH_SHIFT;
+      if (md->u.legacy.tile_split) {
+         args.tiling_flags |= (eg_tile_split_rev(md->u.legacy.tile_split) &
+                               RADEON_TILING_EG_TILE_SPLIT_MASK) <<
+                              RADEON_TILING_EG_TILE_SPLIT_SHIFT;
+      }
+      args.tiling_flags |= (md->u.legacy.mtilea & RADEON_TILING_EG_MACRO_TILE_ASPECT_MASK) <<
+                           RADEON_TILING_EG_MACRO_TILE_ASPECT_SHIFT;
+
+      if (bo->rws->gen >= DRV_SI && !md->u.legacy.scanout)
+         args.tiling_flags |= RADEON_TILING_R600_NO_SCANOUT;
+
+      args.pitch = md->u.legacy.stride;
+   }
 
    args.handle = bo->handle;
-   args.pitch = md->u.legacy.stride;
 
    drmCommandWriteRead(bo->rws->fd,
                        DRM_RADEON_GEM_SET_TILING,