util: Make helper functions for pack/unpacking pixel rows.
[mesa.git] / src / gallium / drivers / r600 / r600_texture.c
index 15a1ec92675b9ded217444cd437951f86ca25efb..ad94c9fb0f04edda83eaf25270a5dbc28d681a15 100644 (file)
 #include "r600_pipe_common.h"
 #include "r600_cs.h"
 #include "r600_query.h"
-#include "util/u_format.h"
+#include "util/format/u_format.h"
 #include "util/u_log.h"
 #include "util/u_memory.h"
 #include "util/u_pack_color.h"
 #include "util/u_surface.h"
-#include "os/os_time.h"
+#include "util/os_time.h"
+#include "state_tracker/winsys_handle.h"
 #include <errno.h>
 #include <inttypes.h>
 
@@ -176,36 +177,21 @@ static unsigned r600_texture_get_offset(struct r600_common_screen *rscreen,
                                        unsigned *stride,
                                        unsigned *layer_stride)
 {
-       if (rscreen->chip_class >= GFX9) {
-               *stride = rtex->surface.u.gfx9.surf_pitch * rtex->surface.bpe;
-               *layer_stride = rtex->surface.u.gfx9.surf_slice_size;
-
-               if (!box)
-                       return 0;
-
-               /* Each texture is an array of slices. Each slice is an array
-                * of mipmap levels. */
-               return box->z * rtex->surface.u.gfx9.surf_slice_size +
-                      rtex->surface.u.gfx9.offset[level] +
-                      (box->y / rtex->surface.blk_h *
-                       rtex->surface.u.gfx9.surf_pitch +
-                       box->x / rtex->surface.blk_w) * rtex->surface.bpe;
-       } else {
-               *stride = rtex->surface.u.legacy.level[level].nblk_x *
-                         rtex->surface.bpe;
-               *layer_stride = rtex->surface.u.legacy.level[level].slice_size;
-
-               if (!box)
-                       return rtex->surface.u.legacy.level[level].offset;
-
-               /* Each texture is an array of mipmap levels. Each level is
-                * an array of slices. */
-               return rtex->surface.u.legacy.level[level].offset +
-                      box->z * rtex->surface.u.legacy.level[level].slice_size +
-                      (box->y / rtex->surface.blk_h *
-                       rtex->surface.u.legacy.level[level].nblk_x +
-                       box->x / rtex->surface.blk_w) * rtex->surface.bpe;
-       }
+       *stride = rtex->surface.u.legacy.level[level].nblk_x *
+               rtex->surface.bpe;
+       assert((uint64_t)rtex->surface.u.legacy.level[level].slice_size_dw * 4 <= UINT_MAX);
+       *layer_stride = (uint64_t)rtex->surface.u.legacy.level[level].slice_size_dw * 4;
+
+       if (!box)
+               return rtex->surface.u.legacy.level[level].offset;
+
+       /* Each texture is an array of mipmap levels. Each level is
+        * an array of slices. */
+       return rtex->surface.u.legacy.level[level].offset +
+               box->z * (uint64_t)rtex->surface.u.legacy.level[level].slice_size_dw * 4 +
+               (box->y / rtex->surface.blk_h *
+                rtex->surface.u.legacy.level[level].nblk_x +
+                box->x / rtex->surface.blk_w) * rtex->surface.bpe;
 }
 
 static int r600_init_surface(struct r600_common_screen *rscreen,
@@ -216,8 +202,7 @@ static int r600_init_surface(struct r600_common_screen *rscreen,
                             unsigned offset,
                             bool is_imported,
                             bool is_scanout,
-                            bool is_flushed_depth,
-                            bool tc_compatible_htile)
+                            bool is_flushed_depth)
 {
        const struct util_format_description *desc =
                util_format_description(ptex->format);
@@ -233,35 +218,16 @@ static int r600_init_surface(struct r600_common_screen *rscreen,
                bpe = 4; /* stencil is allocated separately on evergreen */
        } else {
                bpe = util_format_get_blocksize(ptex->format);
-               assert(util_is_power_of_two(bpe));
+               assert(util_is_power_of_two_or_zero(bpe));
        }
 
        if (!is_flushed_depth && is_depth) {
                flags |= RADEON_SURF_ZBUFFER;
 
-               if (tc_compatible_htile &&
-                   (rscreen->chip_class >= GFX9 ||
-                    array_mode == RADEON_SURF_MODE_2D)) {
-                       /* TC-compatible HTILE only supports Z32_FLOAT.
-                        * GFX9 also supports Z16_UNORM.
-                        * On VI, promote Z16 to Z32. DB->CB copies will convert
-                        * the format for transfers.
-                        */
-                       if (rscreen->chip_class == VI)
-                               bpe = 4;
-
-                       flags |= RADEON_SURF_TC_COMPATIBLE_HTILE;
-               }
-
                if (is_stencil)
                        flags |= RADEON_SURF_SBUFFER;
        }
 
-       if (rscreen->chip_class >= VI &&
-           (ptex->flags & R600_RESOURCE_FLAG_DISABLE_DCC ||
-            ptex->format == PIPE_FORMAT_R9G9B9E5_FLOAT))
-               flags |= RADEON_SURF_DISABLE_DCC;
-
        if (ptex->bind & PIPE_BIND_SCANOUT || is_scanout) {
                /* This should catch bugs in gallium users setting incorrect flags. */
                assert(ptex->nr_samples <= 1 &&
@@ -280,32 +246,27 @@ static int r600_init_surface(struct r600_common_screen *rscreen,
        if (!(ptex->flags & R600_RESOURCE_FLAG_FORCE_TILING))
                flags |= RADEON_SURF_OPTIMIZE_FOR_SPACE;
 
-       r = rscreen->ws->surface_init(rscreen->ws, ptex, flags, bpe,
-                                     array_mode, surface);
+       r = rscreen->ws->surface_init(rscreen->ws, ptex,
+                                     flags, bpe, array_mode, surface);
        if (r) {
                return r;
        }
 
-       if (rscreen->chip_class >= GFX9) {
-               assert(!pitch_in_bytes_override ||
-                      pitch_in_bytes_override == surface->u.gfx9.surf_pitch * bpe);
-               surface->u.gfx9.surf_offset = offset;
-       } else {
-               if (pitch_in_bytes_override &&
-                   pitch_in_bytes_override != surface->u.legacy.level[0].nblk_x * bpe) {
-                       /* old ddx on evergreen over estimate alignment for 1d, only 1 level
-                        * for those
-                        */
-                       surface->u.legacy.level[0].nblk_x = pitch_in_bytes_override / bpe;
-                       surface->u.legacy.level[0].slice_size = pitch_in_bytes_override *
-                                                               surface->u.legacy.level[0].nblk_y;
-               }
+       if (pitch_in_bytes_override &&
+           pitch_in_bytes_override != surface->u.legacy.level[0].nblk_x * bpe) {
+               /* old ddx on evergreen over estimate alignment for 1d, only 1 level
+                * for those
+                */
+               surface->u.legacy.level[0].nblk_x = pitch_in_bytes_override / bpe;
+               surface->u.legacy.level[0].slice_size_dw =
+                       ((uint64_t)pitch_in_bytes_override * surface->u.legacy.level[0].nblk_y) / 4;
+       }
 
-               if (offset) {
-                       for (i = 0; i < ARRAY_SIZE(surface->u.legacy.level); ++i)
-                               surface->u.legacy.level[i].offset += offset;
-               }
+       if (offset) {
+               for (i = 0; i < ARRAY_SIZE(surface->u.legacy.level); ++i)
+                       surface->u.legacy.level[i].offset += offset;
        }
+
        return 0;
 }
 
@@ -317,22 +278,18 @@ static void r600_texture_init_metadata(struct r600_common_screen *rscreen,
 
        memset(metadata, 0, sizeof(*metadata));
 
-       if (rscreen->chip_class >= GFX9) {
-               metadata->u.gfx9.swizzle_mode = surface->u.gfx9.surf.swizzle_mode;
-       } else {
-               metadata->u.legacy.microtile = surface->u.legacy.level[0].mode >= RADEON_SURF_MODE_1D ?
-                                          RADEON_LAYOUT_TILED : RADEON_LAYOUT_LINEAR;
-               metadata->u.legacy.macrotile = surface->u.legacy.level[0].mode >= RADEON_SURF_MODE_2D ?
-                                          RADEON_LAYOUT_TILED : RADEON_LAYOUT_LINEAR;
-               metadata->u.legacy.pipe_config = surface->u.legacy.pipe_config;
-               metadata->u.legacy.bankw = surface->u.legacy.bankw;
-               metadata->u.legacy.bankh = surface->u.legacy.bankh;
-               metadata->u.legacy.tile_split = surface->u.legacy.tile_split;
-               metadata->u.legacy.mtilea = surface->u.legacy.mtilea;
-               metadata->u.legacy.num_banks = surface->u.legacy.num_banks;
-               metadata->u.legacy.stride = surface->u.legacy.level[0].nblk_x * surface->bpe;
-               metadata->u.legacy.scanout = (surface->flags & RADEON_SURF_SCANOUT) != 0;
-       }
+       metadata->u.legacy.microtile = surface->u.legacy.level[0].mode >= RADEON_SURF_MODE_1D ?
+               RADEON_LAYOUT_TILED : RADEON_LAYOUT_LINEAR;
+       metadata->u.legacy.macrotile = surface->u.legacy.level[0].mode >= RADEON_SURF_MODE_2D ?
+               RADEON_LAYOUT_TILED : RADEON_LAYOUT_LINEAR;
+       metadata->u.legacy.pipe_config = surface->u.legacy.pipe_config;
+       metadata->u.legacy.bankw = surface->u.legacy.bankw;
+       metadata->u.legacy.bankh = surface->u.legacy.bankh;
+       metadata->u.legacy.tile_split = surface->u.legacy.tile_split;
+       metadata->u.legacy.mtilea = surface->u.legacy.mtilea;
+       metadata->u.legacy.num_banks = surface->u.legacy.num_banks;
+       metadata->u.legacy.stride = surface->u.legacy.level[0].nblk_x * surface->bpe;
+       metadata->u.legacy.scanout = (surface->flags & RADEON_SURF_SCANOUT) != 0;
 }
 
 static void r600_surface_import_metadata(struct r600_common_screen *rscreen,
@@ -341,33 +298,21 @@ static void r600_surface_import_metadata(struct r600_common_screen *rscreen,
                                         enum radeon_surf_mode *array_mode,
                                         bool *is_scanout)
 {
-       if (rscreen->chip_class >= GFX9) {
-               if (metadata->u.gfx9.swizzle_mode > 0)
-                       *array_mode = RADEON_SURF_MODE_2D;
-               else
-                       *array_mode = RADEON_SURF_MODE_LINEAR_ALIGNED;
-
-               *is_scanout = metadata->u.gfx9.swizzle_mode == 0 ||
-                             metadata->u.gfx9.swizzle_mode % 4 == 2;
-
-               surf->u.gfx9.surf.swizzle_mode = metadata->u.gfx9.swizzle_mode;
-       } 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;
+       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;
-       }
+       *is_scanout = metadata->u.legacy.scanout;
 }
 
 static void r600_eliminate_fast_color_clear(struct r600_common_context *rctx,
@@ -399,10 +344,7 @@ static void r600_texture_discard_cmask(struct r600_common_screen *rscreen,
        rtex->cmask.base_address_reg = rtex->resource.gpu_address >> 8;
        rtex->dirty_level_mask = 0;
 
-       if (rscreen->chip_class >= SI)
-               rtex->cb_color_info &= ~SI_S_028C70_FAST_CLEAR(1);
-       else
-               rtex->cb_color_info &= ~EG_S_028C70_FAST_CLEAR(1);
+       rtex->cb_color_info &= ~EG_S_028C70_FAST_CLEAR(1);
 
        if (rtex->cmask_buffer != &rtex->resource)
            r600_resource_reference(&rtex->cmask_buffer, NULL);
@@ -412,72 +354,6 @@ static void r600_texture_discard_cmask(struct r600_common_screen *rscreen,
        p_atomic_inc(&rscreen->compressed_colortex_counter);
 }
 
-static bool r600_can_disable_dcc(struct r600_texture *rtex)
-{
-       /* We can't disable DCC if it can be written by another process. */
-       return rtex->dcc_offset &&
-              (!rtex->resource.b.is_shared ||
-               !(rtex->resource.external_usage & PIPE_HANDLE_USAGE_WRITE));
-}
-
-static bool r600_texture_discard_dcc(struct r600_common_screen *rscreen,
-                                    struct r600_texture *rtex)
-{
-       if (!r600_can_disable_dcc(rtex))
-               return false;
-
-       assert(rtex->dcc_separate_buffer == NULL);
-
-       /* Disable DCC. */
-       rtex->dcc_offset = 0;
-
-       /* Notify all contexts about the change. */
-       p_atomic_inc(&rscreen->dirty_tex_counter);
-       return true;
-}
-
-/**
- * Disable DCC for the texture. (first decompress, then discard metadata).
- *
- * There is unresolved multi-context synchronization issue between
- * screen::aux_context and the current context. If applications do this with
- * multiple contexts, it's already undefined behavior for them and we don't
- * have to worry about that. The scenario is:
- *
- * If context 1 disables DCC and context 2 has queued commands that write
- * to the texture via CB with DCC enabled, and the order of operations is
- * as follows:
- *   context 2 queues draw calls rendering to the texture, but doesn't flush
- *   context 1 disables DCC and flushes
- *   context 1 & 2 reset descriptors and FB state
- *   context 2 flushes (new compressed tiles written by the draw calls)
- *   context 1 & 2 read garbage, because DCC is disabled, yet there are
- *   compressed tiled
- *
- * \param rctx  the current context if you have one, or rscreen->aux_context
- *              if you don't.
- */
-bool r600_texture_disable_dcc(struct r600_common_context *rctx,
-                             struct r600_texture *rtex)
-{
-       struct r600_common_screen *rscreen = rctx->screen;
-
-       if (!r600_can_disable_dcc(rtex))
-               return false;
-
-       if (&rctx->b == rscreen->aux_context)
-               mtx_lock(&rscreen->aux_context_lock);
-
-       /* Decompress DCC. */
-       rctx->decompress_dcc(&rctx->b, rtex);
-       rctx->b.flush(&rctx->b, NULL, 0);
-
-       if (&rctx->b == rscreen->aux_context)
-               mtx_unlock(&rscreen->aux_context_lock);
-
-       return r600_texture_discard_dcc(rscreen, rtex);
-}
-
 static void r600_reallocate_texture_inplace(struct r600_common_context *rctx,
                                            struct r600_texture *rtex,
                                            unsigned new_bind_flag,
@@ -491,7 +367,7 @@ static void r600_reallocate_texture_inplace(struct r600_common_context *rctx,
        templ.bind |= new_bind_flag;
 
        /* r600g doesn't react to dirty_tex_descriptor_counter */
-       if (rctx->chip_class < SI)
+       if (rctx->chip_class < GFX6)
                return;
 
        if (rtex->resource.b.is_shared)
@@ -518,7 +394,7 @@ static void r600_reallocate_texture_inplace(struct r600_common_context *rctx,
 
                        u_box_3d(0, 0, 0,
                                 u_minify(templ.width0, i), u_minify(templ.height0, i),
-                                util_max_layer(&templ, i) + 1, &box);
+                                util_num_layers(&templ, i), &box);
 
                        rctx->dma_copy(&rctx->b, &new_tex->resource.b.b, i, 0, 0, 0,
                                       &rtex->resource.b.b, i, &box);
@@ -527,7 +403,6 @@ static void r600_reallocate_texture_inplace(struct r600_common_context *rctx,
 
        if (new_bind_flag == PIPE_BIND_LINEAR) {
                r600_texture_discard_cmask(rctx->screen, rtex);
-               r600_texture_discard_dcc(rctx->screen, rtex);
        }
 
        /* Replace the structure fields of rtex. */
@@ -551,18 +426,15 @@ static void r600_reallocate_texture_inplace(struct r600_common_context *rctx,
        rtex->cb_color_info = new_tex->cb_color_info;
        rtex->last_msaa_resolve_target_micro_mode = new_tex->last_msaa_resolve_target_micro_mode;
        rtex->htile_offset = new_tex->htile_offset;
-       rtex->tc_compatible_htile = new_tex->tc_compatible_htile;
        rtex->depth_cleared = new_tex->depth_cleared;
        rtex->stencil_cleared = new_tex->stencil_cleared;
        rtex->non_disp_tiling = new_tex->non_disp_tiling;
-       rtex->dcc_gather_statistics = new_tex->dcc_gather_statistics;
        rtex->framebuffers_bound = new_tex->framebuffers_bound;
 
        if (new_bind_flag == PIPE_BIND_LINEAR) {
                assert(!rtex->htile_offset);
                assert(!rtex->cmask.size);
                assert(!rtex->fmask.size);
-               assert(!rtex->dcc_offset);
                assert(!rtex->is_depth);
        }
 
@@ -571,11 +443,37 @@ static void r600_reallocate_texture_inplace(struct r600_common_context *rctx,
        p_atomic_inc(&rctx->screen->dirty_tex_counter);
 }
 
-static boolean r600_texture_get_handle(struct pipe_screen* screen,
-                                      struct pipe_context *ctx,
-                                      struct pipe_resource *resource,
-                                      struct winsys_handle *whandle,
-                                       unsigned usage)
+static void r600_texture_get_info(struct pipe_screen* screen,
+                                 struct pipe_resource *resource,
+                                 unsigned *pstride,
+                                 unsigned *poffset)
+{
+       struct r600_common_screen *rscreen = (struct r600_common_screen*)screen;
+       struct r600_texture *rtex = (struct r600_texture*)resource;
+       unsigned stride = 0;
+       unsigned offset = 0;
+
+       if (!rscreen || !rtex)
+               return;
+
+       if (resource->target != PIPE_BUFFER) {
+               offset = rtex->surface.u.legacy.level[0].offset;
+               stride = rtex->surface.u.legacy.level[0].nblk_x *
+                        rtex->surface.bpe;
+       }
+
+       if (pstride)
+               *pstride = stride;
+
+       if (poffset)
+               *poffset = offset;
+}
+
+static bool r600_texture_get_handle(struct pipe_screen* screen,
+                                   struct pipe_context *ctx,
+                                   struct pipe_resource *resource,
+                                   struct winsys_handle *whandle,
+                                   unsigned usage)
 {
        struct r600_common_screen *rscreen = (struct r600_common_screen*)screen;
        struct r600_common_context *rctx;
@@ -607,18 +505,9 @@ static boolean r600_texture_get_handle(struct pipe_screen* screen,
                        assert(rtex->surface.tile_swizzle == 0);
                }
 
-               /* Since shader image stores don't support DCC on VI,
-                * disable it for external clients that want write
-                * access.
-                */
-               if (usage & PIPE_HANDLE_USAGE_WRITE && rtex->dcc_offset) {
-                       if (r600_texture_disable_dcc(rctx, rtex))
-                               update_metadata = true;
-               }
-
                if (!(usage & PIPE_HANDLE_USAGE_EXPLICIT_FLUSH) &&
-                   (rtex->cmask.size || rtex->dcc_offset)) {
-                       /* Eliminate fast clear (both CMASK and DCC) */
+                   rtex->cmask.size) {
+                       /* Eliminate fast clear (CMASK) */
                        r600_eliminate_fast_color_clear(rctx, rtex);
 
                        /* Disable CMASK if flush_resource isn't going
@@ -631,24 +520,11 @@ static boolean r600_texture_get_handle(struct pipe_screen* screen,
                /* Set metadata. */
                if (!res->b.is_shared || update_metadata) {
                        r600_texture_init_metadata(rscreen, rtex, &metadata);
-                       if (rscreen->query_opaque_metadata)
-                               rscreen->query_opaque_metadata(rscreen, rtex,
-                                                              &metadata);
 
                        rscreen->ws->buffer_set_metadata(res->buf, &metadata);
                }
 
-               if (rscreen->chip_class >= GFX9) {
-                       offset = rtex->surface.u.gfx9.surf_offset;
-                       stride = rtex->surface.u.gfx9.surf_pitch *
-                                rtex->surface.bpe;
-                       slice_size = rtex->surface.u.gfx9.surf_slice_size;
-               } else {
-                       offset = rtex->surface.u.legacy.level[0].offset;
-                       stride = rtex->surface.u.legacy.level[0].nblk_x *
-                                rtex->surface.bpe;
-                       slice_size = rtex->surface.u.legacy.level[0].slice_size;
-               }
+               slice_size = (uint64_t)rtex->surface.u.legacy.level[0].slice_size_dw * 4;
        } else {
                /* Move a suballocated buffer into a non-suballocated allocation. */
                if (rscreen->ws->buffer_is_suballocated(res->buf)) {
@@ -677,11 +553,11 @@ static boolean r600_texture_get_handle(struct pipe_screen* screen,
                }
 
                /* Buffers */
-               offset = 0;
-               stride = 0;
                slice_size = 0;
        }
 
+       r600_texture_get_info(screen, resource, &stride, &offset);
+
        if (res->b.is_shared) {
                /* USAGE_EXPLICIT_FLUSH must be cleared if at least one user
                 * doesn't set it.
@@ -694,8 +570,10 @@ static boolean r600_texture_get_handle(struct pipe_screen* screen,
                res->external_usage = usage;
        }
 
-       return rscreen->ws->buffer_get_handle(res->buf, stride, offset,
-                                             slice_size, whandle);
+       whandle->stride = stride;
+       whandle->offset = offset + slice_size * whandle->layer;
+
+       return rscreen->ws->buffer_get_handle(rscreen->ws, res->buf, whandle);
 }
 
 static void r600_texture_destroy(struct pipe_screen *screen,
@@ -705,13 +583,12 @@ static void r600_texture_destroy(struct pipe_screen *screen,
        struct r600_resource *resource = &rtex->resource;
 
        r600_texture_reference(&rtex->flushed_depth_texture, NULL);
+       pipe_resource_reference((struct pipe_resource**)&resource->immed_buffer, NULL);
 
        if (rtex->cmask_buffer != &rtex->resource) {
            r600_resource_reference(&rtex->cmask_buffer, NULL);
        }
        pb_reference(&resource->buf, NULL);
-       r600_resource_reference(&rtex->dcc_separate_buffer, NULL);
-       r600_resource_reference(&rtex->last_dcc_separate_buffer, NULL);
        FREE(rtex);
 }
 
@@ -730,25 +607,17 @@ void r600_texture_get_fmask_info(struct r600_common_screen *rscreen,
 
        memset(out, 0, sizeof(*out));
 
-       if (rscreen->chip_class >= GFX9) {
-               out->alignment = rtex->surface.u.gfx9.fmask_alignment;
-               out->size = rtex->surface.u.gfx9.fmask_size;
-               return;
-       }
-
        templ.nr_samples = 1;
        flags = rtex->surface.flags | RADEON_SURF_FMASK;
 
-       if (rscreen->chip_class <= CAYMAN) {
-               /* Use the same parameters and tile mode. */
-               fmask.u.legacy.bankw = rtex->surface.u.legacy.bankw;
-               fmask.u.legacy.bankh = rtex->surface.u.legacy.bankh;
-               fmask.u.legacy.mtilea = rtex->surface.u.legacy.mtilea;
-               fmask.u.legacy.tile_split = rtex->surface.u.legacy.tile_split;
+       /* Use the same parameters and tile mode. */
+       fmask.u.legacy.bankw = rtex->surface.u.legacy.bankw;
+       fmask.u.legacy.bankh = rtex->surface.u.legacy.bankh;
+       fmask.u.legacy.mtilea = rtex->surface.u.legacy.mtilea;
+       fmask.u.legacy.tile_split = rtex->surface.u.legacy.tile_split;
 
-               if (nr_samples <= 4)
-                       fmask.u.legacy.bankh = 4;
-       }
+       if (nr_samples <= 4)
+               fmask.u.legacy.bankh = 4;
 
        switch (nr_samples) {
        case 2:
@@ -770,8 +639,8 @@ void r600_texture_get_fmask_info(struct r600_common_screen *rscreen,
                bpe *= 2;
        }
 
-       if (rscreen->ws->surface_init(rscreen->ws, &templ, flags, bpe,
-                                     RADEON_SURF_MODE_2D, &fmask)) {
+       if (rscreen->ws->surface_init(rscreen->ws, &templ,
+                                     flags, bpe, RADEON_SURF_MODE_2D, &fmask)) {
                R600_ERR("Got error in surface_init while allocating FMASK.\n");
                return;
        }
@@ -830,80 +699,19 @@ void r600_texture_get_cmask_info(struct r600_common_screen *rscreen,
 
        out->slice_tile_max = ((pitch_elements * height) / (128*128)) - 1;
        out->alignment = MAX2(256, base_align);
-       out->size = (util_max_layer(&rtex->resource.b.b, 0) + 1) *
-                   align(slice_bytes, base_align);
-}
-
-static void si_texture_get_cmask_info(struct r600_common_screen *rscreen,
-                                     struct r600_texture *rtex,
-                                     struct r600_cmask_info *out)
-{
-       unsigned pipe_interleave_bytes = rscreen->info.pipe_interleave_bytes;
-       unsigned num_pipes = rscreen->info.num_tile_pipes;
-       unsigned cl_width, cl_height;
-
-       if (rscreen->chip_class >= GFX9) {
-               out->alignment = rtex->surface.u.gfx9.cmask_alignment;
-               out->size = rtex->surface.u.gfx9.cmask_size;
-               return;
-       }
-
-       switch (num_pipes) {
-       case 2:
-               cl_width = 32;
-               cl_height = 16;
-               break;
-       case 4:
-               cl_width = 32;
-               cl_height = 32;
-               break;
-       case 8:
-               cl_width = 64;
-               cl_height = 32;
-               break;
-       case 16: /* Hawaii */
-               cl_width = 64;
-               cl_height = 64;
-               break;
-       default:
-               assert(0);
-               return;
-       }
-
-       unsigned base_align = num_pipes * pipe_interleave_bytes;
-
-       unsigned width = align(rtex->resource.b.b.width0, cl_width*8);
-       unsigned height = align(rtex->resource.b.b.height0, cl_height*8);
-       unsigned slice_elements = (width * height) / (8*8);
-
-       /* Each element of CMASK is a nibble. */
-       unsigned slice_bytes = slice_elements / 2;
-
-       out->slice_tile_max = (width * height) / (128*128);
-       if (out->slice_tile_max)
-               out->slice_tile_max -= 1;
-
-       out->alignment = MAX2(256, base_align);
-       out->size = (util_max_layer(&rtex->resource.b.b, 0) + 1) *
+       out->size = util_num_layers(&rtex->resource.b.b, 0) *
                    align(slice_bytes, base_align);
 }
 
 static void r600_texture_allocate_cmask(struct r600_common_screen *rscreen,
                                        struct r600_texture *rtex)
 {
-       if (rscreen->chip_class >= SI) {
-               si_texture_get_cmask_info(rscreen, rtex, &rtex->cmask);
-       } else {
-               r600_texture_get_cmask_info(rscreen, rtex, &rtex->cmask);
-       }
+       r600_texture_get_cmask_info(rscreen, rtex, &rtex->cmask);
 
        rtex->cmask.offset = align64(rtex->size, rtex->cmask.alignment);
        rtex->size = rtex->cmask.offset + rtex->cmask.size;
 
-       if (rscreen->chip_class >= SI)
-               rtex->cb_color_info |= SI_S_028C70_FAST_CLEAR(1);
-       else
-               rtex->cb_color_info |= EG_S_028C70_FAST_CLEAR(1);
+       rtex->cb_color_info |= EG_S_028C70_FAST_CLEAR(1);
 }
 
 static void r600_texture_alloc_cmask_separate(struct r600_common_screen *rscreen,
@@ -914,11 +722,7 @@ static void r600_texture_alloc_cmask_separate(struct r600_common_screen *rscreen
 
        assert(rtex->cmask.size == 0);
 
-       if (rscreen->chip_class >= SI) {
-               si_texture_get_cmask_info(rscreen, rtex, &rtex->cmask);
-       } else {
-               r600_texture_get_cmask_info(rscreen, rtex, &rtex->cmask);
-       }
+       r600_texture_get_cmask_info(rscreen, rtex, &rtex->cmask);
 
        rtex->cmask_buffer = (struct r600_resource *)
                r600_aligned_buffer_create(&rscreen->b,
@@ -934,14 +738,20 @@ static void r600_texture_alloc_cmask_separate(struct r600_common_screen *rscreen
        /* update colorbuffer state bits */
        rtex->cmask.base_address_reg = rtex->cmask_buffer->gpu_address >> 8;
 
-       if (rscreen->chip_class >= SI)
-               rtex->cb_color_info |= SI_S_028C70_FAST_CLEAR(1);
-       else
-               rtex->cb_color_info |= EG_S_028C70_FAST_CLEAR(1);
+       rtex->cb_color_info |= EG_S_028C70_FAST_CLEAR(1);
 
        p_atomic_inc(&rscreen->compressed_colortex_counter);
 }
 
+void eg_resource_alloc_immed(struct r600_common_screen *rscreen,
+                            struct r600_resource *res,
+                            unsigned immed_size)
+{
+       res->immed_buffer = (struct r600_resource *)
+               pipe_buffer_create(&rscreen->b, PIPE_BIND_CUSTOM,
+                                  PIPE_USAGE_DEFAULT, immed_size);
+}
+
 static void r600_texture_get_htile_size(struct r600_common_screen *rscreen,
                                        struct r600_texture *rtex)
 {
@@ -949,12 +759,10 @@ static void r600_texture_get_htile_size(struct r600_common_screen *rscreen,
        unsigned slice_elements, slice_bytes, pipe_interleave_bytes, base_align;
        unsigned num_pipes = rscreen->info.num_tile_pipes;
 
-       assert(rscreen->chip_class <= VI);
-
        rtex->surface.htile_size = 0;
 
        if (rscreen->chip_class <= EVERGREEN &&
-           rscreen->info.drm_major == 2 && rscreen->info.drm_minor < 26)
+           rscreen->info.drm_minor < 26)
                return;
 
        /* HW bug on R6xx. */
@@ -963,22 +771,6 @@ static void r600_texture_get_htile_size(struct r600_common_screen *rscreen,
             rtex->resource.b.b.height0 > 7680))
                return;
 
-       /* HTILE is broken with 1D tiling on old kernels and CIK. */
-       if (rscreen->chip_class >= CIK &&
-           rtex->surface.u.legacy.level[0].mode == RADEON_SURF_MODE_1D &&
-           rscreen->info.drm_major == 2 && rscreen->info.drm_minor < 38)
-               return;
-
-       /* Overalign HTILE on P2 configs to work around GPU hangs in
-        * piglit/depthstencil-render-miplevels 585.
-        *
-        * This has been confirmed to help Kabini & Stoney, where the hangs
-        * are always reproducible. I think I have seen the test hang
-        * on Carrizo too, though it was very rare there.
-        */
-       if (rscreen->chip_class >= CIK && num_pipes < 4)
-               num_pipes = 4;
-
        switch (num_pipes) {
        case 1:
                cl_width = 32;
@@ -1005,8 +797,8 @@ static void r600_texture_get_htile_size(struct r600_common_screen *rscreen,
                return;
        }
 
-       width = align(rtex->resource.b.b.width0, cl_width * 8);
-       height = align(rtex->resource.b.b.height0, cl_height * 8);
+       width = align(rtex->surface.u.legacy.level[0].nblk_x, cl_width * 8);
+       height = align(rtex->surface.u.legacy.level[0].nblk_y, cl_height * 8);
 
        slice_elements = (width * height) / (8 * 8);
        slice_bytes = slice_elements * 4;
@@ -1016,15 +808,14 @@ static void r600_texture_get_htile_size(struct r600_common_screen *rscreen,
 
        rtex->surface.htile_alignment = base_align;
        rtex->surface.htile_size =
-               (util_max_layer(&rtex->resource.b.b, 0) + 1) *
+               util_num_layers(&rtex->resource.b.b, 0) *
                align(slice_bytes, base_align);
 }
 
 static void r600_texture_allocate_htile(struct r600_common_screen *rscreen,
                                        struct r600_texture *rtex)
 {
-       if (rscreen->chip_class <= VI && !rtex->tc_compatible_htile)
-               r600_texture_get_htile_size(rscreen, rtex);
+       r600_texture_get_htile_size(rscreen, rtex);
 
        if (!rtex->surface.htile_size)
                return;
@@ -1049,64 +840,6 @@ void r600_print_texture_info(struct r600_common_screen *rscreen,
                rtex->surface.bpe, rtex->resource.b.b.nr_samples,
                rtex->surface.flags, util_format_short_name(rtex->resource.b.b.format));
 
-       if (rscreen->chip_class >= GFX9) {
-               u_log_printf(log, "  Surf: size=%"PRIu64", slice_size=%"PRIu64", "
-                       "alignment=%u, swmode=%u, epitch=%u, pitch=%u\n",
-                       rtex->surface.surf_size,
-                       rtex->surface.u.gfx9.surf_slice_size,
-                       rtex->surface.surf_alignment,
-                       rtex->surface.u.gfx9.surf.swizzle_mode,
-                       rtex->surface.u.gfx9.surf.epitch,
-                       rtex->surface.u.gfx9.surf_pitch);
-
-               if (rtex->fmask.size) {
-                       u_log_printf(log, "  FMASK: offset=%"PRIu64", size=%"PRIu64", "
-                               "alignment=%u, swmode=%u, epitch=%u\n",
-                               rtex->fmask.offset,
-                               rtex->surface.u.gfx9.fmask_size,
-                               rtex->surface.u.gfx9.fmask_alignment,
-                               rtex->surface.u.gfx9.fmask.swizzle_mode,
-                               rtex->surface.u.gfx9.fmask.epitch);
-               }
-
-               if (rtex->cmask.size) {
-                       u_log_printf(log, "  CMask: offset=%"PRIu64", size=%"PRIu64", "
-                               "alignment=%u, rb_aligned=%u, pipe_aligned=%u\n",
-                               rtex->cmask.offset,
-                               rtex->surface.u.gfx9.cmask_size,
-                               rtex->surface.u.gfx9.cmask_alignment,
-                               rtex->surface.u.gfx9.cmask.rb_aligned,
-                               rtex->surface.u.gfx9.cmask.pipe_aligned);
-               }
-
-               if (rtex->htile_offset) {
-                       u_log_printf(log, "  HTile: offset=%"PRIu64", size=%"PRIu64", alignment=%u, "
-                               "rb_aligned=%u, pipe_aligned=%u\n",
-                               rtex->htile_offset,
-                               rtex->surface.htile_size,
-                               rtex->surface.htile_alignment,
-                               rtex->surface.u.gfx9.htile.rb_aligned,
-                               rtex->surface.u.gfx9.htile.pipe_aligned);
-               }
-
-               if (rtex->dcc_offset) {
-                       u_log_printf(log, "  DCC: offset=%"PRIu64", size=%"PRIu64", "
-                               "alignment=%u, pitch_max=%u, num_dcc_levels=%u\n",
-                               rtex->dcc_offset, rtex->surface.dcc_size,
-                               rtex->surface.dcc_alignment,
-                               rtex->surface.u.gfx9.dcc_pitch_max,
-                               rtex->surface.num_dcc_levels);
-               }
-
-               if (rtex->surface.u.gfx9.stencil_offset) {
-                       u_log_printf(log, "  Stencil: offset=%"PRIu64", swmode=%u, epitch=%u\n",
-                               rtex->surface.u.gfx9.stencil_offset,
-                               rtex->surface.u.gfx9.stencil.swizzle_mode,
-                               rtex->surface.u.gfx9.stencil.epitch);
-               }
-               return;
-       }
-
        u_log_printf(log, "  Layout: size=%"PRIu64", alignment=%u, bankw=%u, "
                "bankh=%u, nbanks=%u, mtilea=%u, tilesplit=%u, pipeconfig=%u, scanout=%u\n",
                rtex->surface.surf_size, rtex->surface.surf_alignment, rtex->surface.u.legacy.bankw,
@@ -1128,30 +861,17 @@ void r600_print_texture_info(struct r600_common_screen *rscreen,
                        rtex->cmask.slice_tile_max);
 
        if (rtex->htile_offset)
-               u_log_printf(log, "  HTile: offset=%"PRIu64", size=%"PRIu64", "
-                       "alignment=%u, TC_compatible = %u\n",
-                       rtex->htile_offset, rtex->surface.htile_size,
-                       rtex->surface.htile_alignment,
-                       rtex->tc_compatible_htile);
-
-       if (rtex->dcc_offset) {
-               u_log_printf(log, "  DCC: offset=%"PRIu64", size=%"PRIu64", alignment=%u\n",
-                       rtex->dcc_offset, rtex->surface.dcc_size,
-                       rtex->surface.dcc_alignment);
-               for (i = 0; i <= rtex->resource.b.b.last_level; i++)
-                       u_log_printf(log, "  DCCLevel[%i]: enabled=%u, offset=%"PRIu64", "
-                               "fast_clear_size=%"PRIu64"\n",
-                               i, i < rtex->surface.num_dcc_levels,
-                               rtex->surface.u.legacy.level[i].dcc_offset,
-                               rtex->surface.u.legacy.level[i].dcc_fast_clear_size);
-       }
+               u_log_printf(log, "  HTile: offset=%"PRIu64", size=%u "
+                       "alignment=%u\n",
+                            rtex->htile_offset, rtex->surface.htile_size,
+                            rtex->surface.htile_alignment);
 
        for (i = 0; i <= rtex->resource.b.b.last_level; i++)
                u_log_printf(log, "  Level[%i]: offset=%"PRIu64", slice_size=%"PRIu64", "
                        "npix_x=%u, npix_y=%u, npix_z=%u, nblk_x=%u, nblk_y=%u, "
                        "mode=%u, tiling_index = %u\n",
                        i, rtex->surface.u.legacy.level[i].offset,
-                       rtex->surface.u.legacy.level[i].slice_size,
+                       (uint64_t)rtex->surface.u.legacy.level[i].slice_size_dw * 4,
                        u_minify(rtex->resource.b.b.width0, i),
                        u_minify(rtex->resource.b.b.height0, i),
                        u_minify(rtex->resource.b.b.depth0, i),
@@ -1169,7 +889,7 @@ void r600_print_texture_info(struct r600_common_screen *rscreen,
                                "npix_y=%u, npix_z=%u, nblk_x=%u, nblk_y=%u, "
                                "mode=%u, tiling_index = %u\n",
                                i, rtex->surface.u.legacy.stencil_level[i].offset,
-                               rtex->surface.u.legacy.stencil_level[i].slice_size,
+                               (uint64_t)rtex->surface.u.legacy.stencil_level[i].slice_size_dw * 4,
                                u_minify(rtex->resource.b.b.width0, i),
                                u_minify(rtex->resource.b.b.height0, i),
                                u_minify(rtex->resource.b.b.depth0, i),
@@ -1208,23 +928,7 @@ r600_texture_create_object(struct pipe_screen *screen,
 
        rtex->surface = *surface;
        rtex->size = rtex->surface.surf_size;
-
-       rtex->tc_compatible_htile = rtex->surface.htile_size != 0 &&
-                                   (rtex->surface.flags &
-                                    RADEON_SURF_TC_COMPATIBLE_HTILE);
-
-       /* TC-compatible HTILE:
-        * - VI only supports Z32_FLOAT.
-        * - GFX9 only supports Z32_FLOAT and Z16_UNORM. */
-       if (rtex->tc_compatible_htile) {
-               if (rscreen->chip_class >= GFX9 &&
-                   base->format == PIPE_FORMAT_Z16_UNORM)
-                       rtex->db_render_format = base->format;
-               else
-                       rtex->db_render_format = PIPE_FORMAT_Z32_FLOAT;
-       } else {
-               rtex->db_render_format = base->format;
-       }
+       rtex->db_render_format = base->format;
 
        /* Tiled depth textures utilize the non-displayable tile order.
         * This must be done after r600_setup_surface.
@@ -1233,23 +937,12 @@ r600_texture_create_object(struct pipe_screen *screen,
        /* Applies to GCN. */
        rtex->last_msaa_resolve_target_micro_mode = rtex->surface.micro_tile_mode;
 
-       /* Disable separate DCC at the beginning. DRI2 doesn't reuse buffers
-        * between frames, so the only thing that can enable separate DCC
-        * with DRI2 is multiple slow clears within a frame.
-        */
-       rtex->ps_draw_ratio = 0;
-
        if (rtex->is_depth) {
                if (base->flags & (R600_RESOURCE_FLAG_TRANSFER |
                                   R600_RESOURCE_FLAG_FLUSHED_DEPTH) ||
                    rscreen->chip_class >= EVERGREEN) {
-                       if (rscreen->chip_class >= GFX9) {
-                               rtex->can_sample_z = true;
-                               rtex->can_sample_s = true;
-                       } else {
-                               rtex->can_sample_z = !rtex->surface.u.legacy.depth_adjusted;
-                               rtex->can_sample_s = !rtex->surface.u.legacy.stencil_adjusted;
-                       }
+                       rtex->can_sample_z = !rtex->surface.u.legacy.depth_adjusted;
+                       rtex->can_sample_s = !rtex->surface.u.legacy.stencil_adjusted;
                } else {
                        if (rtex->resource.b.b.nr_samples <= 1 &&
                            (rtex->resource.b.b.format == PIPE_FORMAT_Z16_UNORM ||
@@ -1276,18 +969,6 @@ r600_texture_create_object(struct pipe_screen *screen,
                                return NULL;
                        }
                }
-
-               /* Shared textures must always set up DCC here.
-                * If it's not present, it will be disabled by
-                * apply_opaque_metadata later.
-                */
-               if (rtex->surface.dcc_size &&
-                   (buf || !(rscreen->debug_flags & DBG_NO_DCC)) &&
-                   !(rtex->surface.flags & RADEON_SURF_SCANOUT)) {
-                       /* Reserve space for the DCC buffer. */
-                       rtex->dcc_offset = align64(rtex->size, rtex->surface.dcc_alignment);
-                       rtex->size = rtex->dcc_offset + rtex->surface.dcc_size;
-               }
        }
 
        /* Now create the backing buffer. */
@@ -1295,10 +976,6 @@ r600_texture_create_object(struct pipe_screen *screen,
                r600_init_resource_fields(rscreen, resource, rtex->size,
                                          rtex->surface.surf_alignment);
 
-               /* Displayable surfaces are not suballocated. */
-               if (resource->b.b.bind & PIPE_BIND_SCANOUT)
-                       resource->flags |= RADEON_FLAG_NO_SUBALLOC;
-
                if (!r600_alloc_resource(rscreen, resource)) {
                        FREE(rtex);
                        return NULL;
@@ -1324,23 +1001,12 @@ r600_texture_create_object(struct pipe_screen *screen,
        if (rtex->htile_offset) {
                uint32_t clear_value = 0;
 
-               if (rscreen->chip_class >= GFX9 || rtex->tc_compatible_htile)
-                       clear_value = 0x0000030F;
-
                r600_screen_clear_buffer(rscreen, &rtex->resource.b.b,
                                         rtex->htile_offset,
                                         rtex->surface.htile_size,
                                         clear_value);
        }
 
-       /* Initialize DCC only if the texture is not being imported. */
-       if (!buf && rtex->dcc_offset) {
-               r600_screen_clear_buffer(rscreen, &rtex->resource.b.b,
-                                        rtex->dcc_offset,
-                                        rtex->surface.dcc_size,
-                                        0xFFFFFFFF);
-       }
-
        /* Initialize the CMASK base register value. */
        rtex->cmask.base_address_reg =
                (rtex->resource.gpu_address + rtex->cmask.offset) >> 8;
@@ -1349,7 +1015,7 @@ r600_texture_create_object(struct pipe_screen *screen,
                fprintf(stderr, "VM start=0x%"PRIX64"  end=0x%"PRIX64" | Texture %ix%ix%i, %i levels, %i samples, %s\n",
                        rtex->resource.gpu_address,
                        rtex->resource.gpu_address + rtex->resource.buf->size,
-                       base->width0, base->height0, util_max_layer(base, 0)+1, base->last_level+1,
+                       base->width0, base->height0, util_num_layers(base, 0), base->last_level+1,
                        base->nr_samples ? base->nr_samples : 1, util_format_short_name(base->format));
        }
 
@@ -1383,14 +1049,6 @@ r600_choose_tiling(struct r600_common_screen *rscreen,
        if (templ->flags & R600_RESOURCE_FLAG_TRANSFER)
                return RADEON_SURF_MODE_LINEAR_ALIGNED;
 
-       /* Avoid Z/S decompress blits by forcing TC-compatible HTILE on VI,
-        * which requires 2D tiling.
-        */
-       if (rscreen->chip_class == VI &&
-           is_depth_stencil &&
-           (templ->flags & PIPE_RESOURCE_FLAG_TEXTURING_MORE_LIKELY))
-               return RADEON_SURF_MODE_2D;
-
        /* r600g: force tiling on TEXTURE_2D and TEXTURE_3D compute resources. */
        if (rscreen->chip_class >= R600 && rscreen->chip_class <= CAYMAN &&
            (templ->bind & PIPE_BIND_COMPUTE_RESOURCE) &&
@@ -1411,21 +1069,12 @@ r600_choose_tiling(struct r600_common_screen *rscreen,
                if (desc->layout == UTIL_FORMAT_LAYOUT_SUBSAMPLED)
                        return RADEON_SURF_MODE_LINEAR_ALIGNED;
 
-               /* Cursors are linear on SI.
-                * (XXX double-check, maybe also use RADEON_SURF_SCANOUT) */
-               if (rscreen->chip_class >= SI &&
-                   (templ->bind & PIPE_BIND_CURSOR))
-                       return RADEON_SURF_MODE_LINEAR_ALIGNED;
-
                if (templ->bind & PIPE_BIND_LINEAR)
                        return RADEON_SURF_MODE_LINEAR_ALIGNED;
 
-               /* Textures with a very small height are recommended to be linear. */
+               /* 1D textures should be linear - fixes image operations on 1d */
                if (templ->target == PIPE_TEXTURE_1D ||
-                   templ->target == PIPE_TEXTURE_1D_ARRAY ||
-                   /* Only very thin and long 2D textures should benefit from
-                    * linear_aligned. */
-                   (templ->width0 > 8 && templ->height0 <= 2))
+                   templ->target == PIPE_TEXTURE_1D_ARRAY)
                        return RADEON_SURF_MODE_LINEAR_ALIGNED;
 
                /* Textures likely to be mapped often. */
@@ -1449,20 +1098,11 @@ struct pipe_resource *r600_texture_create(struct pipe_screen *screen,
        struct r600_common_screen *rscreen = (struct r600_common_screen*)screen;
        struct radeon_surf surface = {0};
        bool is_flushed_depth = templ->flags & R600_RESOURCE_FLAG_FLUSHED_DEPTH;
-       bool tc_compatible_htile =
-               rscreen->chip_class >= VI &&
-               (templ->flags & PIPE_RESOURCE_FLAG_TEXTURING_MORE_LIKELY) &&
-               !(rscreen->debug_flags & DBG_NO_HYPERZ) &&
-               !is_flushed_depth &&
-               templ->nr_samples <= 1 && /* TC-compat HTILE is less efficient with MSAA */
-               util_format_is_depth_or_stencil(templ->format);
-
        int r;
 
        r = r600_init_surface(rscreen, &surface, templ,
                              r600_choose_tiling(rscreen, templ), 0, 0,
-                             false, false, is_flushed_depth,
-                             tc_compatible_htile);
+                             false, false, is_flushed_depth);
        if (r) {
                return NULL;
        }
@@ -1478,7 +1118,6 @@ static struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen
 {
        struct r600_common_screen *rscreen = (struct r600_common_screen*)screen;
        struct pb_buffer *buf = NULL;
-       unsigned stride = 0, offset = 0;
        enum radeon_surf_mode array_mode;
        struct radeon_surf surface = {};
        int r;
@@ -1491,7 +1130,8 @@ static struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen
              templ->depth0 != 1 || templ->last_level != 0)
                return NULL;
 
-       buf = rscreen->ws->buffer_from_handle(rscreen->ws, whandle, &stride, &offset);
+       buf = rscreen->ws->buffer_from_handle(rscreen->ws, whandle,
+                                             rscreen->info.max_alignment);
        if (!buf)
                return NULL;
 
@@ -1499,8 +1139,9 @@ static struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen
        r600_surface_import_metadata(rscreen, &surface, &metadata,
                                     &array_mode, &is_scanout);
 
-       r = r600_init_surface(rscreen, &surface, templ, array_mode, stride,
-                             offset, true, is_scanout, false, false);
+       r = r600_init_surface(rscreen, &surface, templ, array_mode,
+                             whandle->stride, whandle->offset,
+                             true, is_scanout, false);
        if (r) {
                return NULL;
        }
@@ -1512,9 +1153,6 @@ static struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen
        rtex->resource.b.is_shared = true;
        rtex->resource.external_usage = usage;
 
-       if (rscreen->apply_opaque_metadata)
-               rscreen->apply_opaque_metadata(rscreen, rtex, &metadata);
-
        assert(rtex->surface.tile_swizzle == 0);
        return &rtex->resource.b.b;
 }
@@ -1622,7 +1260,7 @@ static bool r600_can_invalidate_texture(struct r600_common_screen *rscreen,
                                        const struct pipe_box *box)
 {
        /* r600g doesn't react to dirty_tex_descriptor_counter */
-       return rscreen->chip_class >= SI &&
+       return rscreen->chip_class >= GFX6 &&
                !rtex->resource.b.is_shared &&
                !(transfer_usage & PIPE_TRANSFER_READ) &&
                rtex->resource.b.b.last_level == 0 &&
@@ -1876,7 +1514,7 @@ static void r600_texture_transfer_unmap(struct pipe_context *ctx,
         * The result is that the kernel memory manager is never a bottleneck.
         */
        if (rctx->num_alloc_tex_transfer_bytes > rctx->screen->info.gart_size / 4) {
-               rctx->gfx.flush(rctx, RADEON_FLUSH_ASYNC, NULL);
+               rctx->gfx.flush(rctx, PIPE_FLUSH_ASYNC, NULL);
                rctx->num_alloc_tex_transfer_bytes = 0;
        }
 
@@ -1997,11 +1635,11 @@ static void r600_clear_texture(struct pipe_context *pipe,
 
                /* Depth is always present. */
                clear = PIPE_CLEAR_DEPTH;
-               desc->unpack_z_float(&depth, 0, data, 0, 1, 1);
+               util_format_unpack_z_float(tex->format, &depth, data, 1);
 
                if (rtex->surface.has_stencil) {
                        clear |= PIPE_CLEAR_STENCIL;
-                       desc->unpack_s_8uint(&stencil, 0, data, 0, 1, 1);
+                       util_format_unpack_s_8uint(tex->format, &stencil, data, 1);
                }
 
                pipe->clear_depth_stencil(pipe, sf, clear, depth, stencil,
@@ -2010,16 +1648,10 @@ static void r600_clear_texture(struct pipe_context *pipe,
        } else {
                union pipe_color_union color;
 
-               /* pipe_color_union requires the full vec4 representation. */
-               if (util_format_is_pure_uint(tex->format))
-                       desc->unpack_rgba_uint(color.ui, 0, data, 0, 1, 1);
-               else if (util_format_is_pure_sint(tex->format))
-                       desc->unpack_rgba_sint(color.i, 0, data, 0, 1, 1);
-               else
-                       desc->unpack_rgba_float(color.f, 0, data, 0, 1, 1);
+               util_format_unpack_rgba(tex->format, color.ui, data, 1);
 
                if (screen->is_format_supported(screen, tex->format,
-                                               tex->target, 0,
+                                               tex->target, 0, 0,
                                                PIPE_BIND_RENDER_TARGET)) {
                        pipe->clear_render_target(pipe, sf, &color,
                                                  box->x, box->y,
@@ -2124,114 +1756,6 @@ static void evergreen_set_clear_color(struct r600_texture *rtex,
        memcpy(rtex->color_clear_value, &uc, 2 * sizeof(uint32_t));
 }
 
-/* Set the same micro tile mode as the destination of the last MSAA resolve.
- * This allows hitting the MSAA resolve fast path, which requires that both
- * src and dst micro tile modes match.
- */
-static void si_set_optimal_micro_tile_mode(struct r600_common_screen *rscreen,
-                                          struct r600_texture *rtex)
-{
-       if (rtex->resource.b.is_shared ||
-           rtex->resource.b.b.nr_samples <= 1 ||
-           rtex->surface.micro_tile_mode == rtex->last_msaa_resolve_target_micro_mode)
-               return;
-
-       assert(rscreen->chip_class >= GFX9 ||
-              rtex->surface.u.legacy.level[0].mode == RADEON_SURF_MODE_2D);
-       assert(rtex->resource.b.b.last_level == 0);
-
-       if (rscreen->chip_class >= GFX9) {
-               /* 4K or larger tiles only. 0 is linear. 1-3 are 256B tiles. */
-               assert(rtex->surface.u.gfx9.surf.swizzle_mode >= 4);
-
-               /* If you do swizzle_mode % 4, you'll get:
-                *   0 = Depth
-                *   1 = Standard,
-                *   2 = Displayable
-                *   3 = Rotated
-                *
-                * Depth-sample order isn't allowed:
-                */
-               assert(rtex->surface.u.gfx9.surf.swizzle_mode % 4 != 0);
-
-               switch (rtex->last_msaa_resolve_target_micro_mode) {
-               case RADEON_MICRO_MODE_DISPLAY:
-                       rtex->surface.u.gfx9.surf.swizzle_mode &= ~0x3;
-                       rtex->surface.u.gfx9.surf.swizzle_mode += 2; /* D */
-                       break;
-               case RADEON_MICRO_MODE_THIN:
-                       rtex->surface.u.gfx9.surf.swizzle_mode &= ~0x3;
-                       rtex->surface.u.gfx9.surf.swizzle_mode += 1; /* S */
-                       break;
-               case RADEON_MICRO_MODE_ROTATED:
-                       rtex->surface.u.gfx9.surf.swizzle_mode &= ~0x3;
-                       rtex->surface.u.gfx9.surf.swizzle_mode += 3; /* R */
-                       break;
-               default: /* depth */
-                       assert(!"unexpected micro mode");
-                       return;
-               }
-       } else if (rscreen->chip_class >= CIK) {
-               /* These magic numbers were copied from addrlib. It doesn't use
-                * any definitions for them either. They are all 2D_TILED_THIN1
-                * modes with different bpp and micro tile mode.
-                */
-               switch (rtex->last_msaa_resolve_target_micro_mode) {
-               case RADEON_MICRO_MODE_DISPLAY:
-                       rtex->surface.u.legacy.tiling_index[0] = 10;
-                       break;
-               case RADEON_MICRO_MODE_THIN:
-                       rtex->surface.u.legacy.tiling_index[0] = 14;
-                       break;
-               case RADEON_MICRO_MODE_ROTATED:
-                       rtex->surface.u.legacy.tiling_index[0] = 28;
-                       break;
-               default: /* depth, thick */
-                       assert(!"unexpected micro mode");
-                       return;
-               }
-       } else { /* SI */
-               switch (rtex->last_msaa_resolve_target_micro_mode) {
-               case RADEON_MICRO_MODE_DISPLAY:
-                       switch (rtex->surface.bpe) {
-                       case 1:
-                            rtex->surface.u.legacy.tiling_index[0] = 10;
-                            break;
-                       case 2:
-                            rtex->surface.u.legacy.tiling_index[0] = 11;
-                            break;
-                       default: /* 4, 8 */
-                            rtex->surface.u.legacy.tiling_index[0] = 12;
-                            break;
-                       }
-                       break;
-               case RADEON_MICRO_MODE_THIN:
-                       switch (rtex->surface.bpe) {
-                       case 1:
-                                rtex->surface.u.legacy.tiling_index[0] = 14;
-                                break;
-                       case 2:
-                                rtex->surface.u.legacy.tiling_index[0] = 15;
-                                break;
-                       case 4:
-                                rtex->surface.u.legacy.tiling_index[0] = 16;
-                                break;
-                       default: /* 8, 16 */
-                                rtex->surface.u.legacy.tiling_index[0] = 17;
-                                break;
-                       }
-                       break;
-               default: /* depth, thick */
-                       assert(!"unexpected micro mode");
-                       return;
-               }
-       }
-
-       rtex->surface.micro_tile_mode = rtex->last_msaa_resolve_target_micro_mode;
-
-       p_atomic_inc(&rscreen->dirty_tex_counter);
-}
-
 void evergreen_do_fast_color_clear(struct r600_common_context *rctx,
                                   struct pipe_framebuffer_state *fb,
                                   struct r600_atom *fb_state,
@@ -2241,7 +1765,7 @@ void evergreen_do_fast_color_clear(struct r600_common_context *rctx,
        int i;
 
        /* This function is broken in BE, so just disable this path for now */
-#ifdef PIPE_ARCH_BIG_ENDIAN
+#if UTIL_ARCH_BIG_ENDIAN
        return;
 #endif
 
@@ -2285,13 +1809,15 @@ void evergreen_do_fast_color_clear(struct r600_common_context *rctx,
                    !(tex->resource.external_usage & PIPE_HANDLE_USAGE_EXPLICIT_FLUSH))
                        continue;
 
-               /* fast color clear with 1D tiling doesn't work on old kernels and CIK */
-               if (rctx->chip_class == CIK &&
-                   tex->surface.u.legacy.level[0].mode == RADEON_SURF_MODE_1D &&
-                   rctx->screen->info.drm_major == 2 &&
-                   rctx->screen->info.drm_minor < 38) {
+               /* Use a slow clear for small surfaces where the cost of
+                * the eliminate pass can be higher than the benefit of fast
+                * clear. AMDGPU-pro does this, but the numbers may differ.
+                *
+                * This helps on both dGPUs and APUs, even small ones.
+                */
+               if (tex->resource.b.b.nr_samples <= 1 &&
+                   tex->resource.b.b.width0 * tex->resource.b.b.height0 <= 300 * 300)
                        continue;
-               }
 
                {
                        /* 128-bit formats are unusupported */
@@ -2299,10 +1825,6 @@ void evergreen_do_fast_color_clear(struct r600_common_context *rctx,
                                continue;
                        }
 
-                       /* RB+ doesn't work with CMASK fast clear on Stoney. */
-                       if (rctx->family == CHIP_STONEY)
-                               continue;
-
                        /* ensure CMASK is enabled */
                        r600_texture_alloc_cmask_separate(rctx->screen, tex);
                        if (tex->cmask.size == 0) {
@@ -2322,10 +1844,6 @@ void evergreen_do_fast_color_clear(struct r600_common_context *rctx,
                                p_atomic_inc(&rctx->screen->compressed_colortex_counter);
                }
 
-               /* We can change the micro tile mode before a full clear. */
-               if (rctx->screen->chip_class >= SI)
-                       si_set_optimal_micro_tile_mode(rctx->screen, tex);
-
                evergreen_set_clear_color(tex, fb->cbufs[i]->format, color);
 
                if (dirty_cbufs)
@@ -2343,13 +1861,12 @@ r600_memobj_from_handle(struct pipe_screen *screen,
        struct r600_common_screen *rscreen = (struct r600_common_screen*)screen;
        struct r600_memory_object *memobj = CALLOC_STRUCT(r600_memory_object);
        struct pb_buffer *buf = NULL;
-       uint32_t stride, offset;
 
        if (!memobj)
                return NULL;
 
        buf = rscreen->ws->buffer_from_handle(rscreen->ws, whandle,
-                                             &stride, &offset);
+                                             rscreen->info.max_alignment);
        if (!buf) {
                free(memobj);
                return NULL;
@@ -2357,8 +1874,8 @@ r600_memobj_from_handle(struct pipe_screen *screen,
 
        memobj->b.dedicated = dedicated;
        memobj->buf = buf;
-       memobj->stride = stride;
-       memobj->offset = offset;
+       memobj->stride = whandle->stride;
+       memobj->offset = whandle->offset;
 
        return (struct pipe_memory_object *)memobj;
 
@@ -2425,7 +1942,7 @@ r600_texture_from_memobj(struct pipe_screen *screen,
        r = r600_init_surface(rscreen, &surface, templ,
                              array_mode, memobj->stride,
                              offset, true, is_scanout,
-                             false, false);
+                             false);
        if (r)
                return NULL;
 
@@ -2439,10 +1956,7 @@ r600_texture_from_memobj(struct pipe_screen *screen,
        pb_reference(&buf, memobj->buf);
 
        rtex->resource.b.is_shared = true;
-       rtex->resource.external_usage = PIPE_HANDLE_USAGE_READ_WRITE;
-
-       if (rscreen->apply_opaque_metadata)
-               rscreen->apply_opaque_metadata(rscreen, rtex, &metadata);
+       rtex->resource.external_usage = PIPE_HANDLE_USAGE_FRAMEBUFFER_WRITE;
 
        return &rtex->resource.b.b;
 }
@@ -2451,6 +1965,7 @@ void r600_init_screen_texture_functions(struct r600_common_screen *rscreen)
 {
        rscreen->b.resource_from_handle = r600_texture_from_handle;
        rscreen->b.resource_get_handle = r600_texture_get_handle;
+       rscreen->b.resource_get_info = r600_texture_get_info;
        rscreen->b.resource_from_memobj = r600_texture_from_memobj;
        rscreen->b.memobj_create_from_handle = r600_memobj_from_handle;
        rscreen->b.memobj_destroy = r600_memobj_destroy;