[Mesa-dev] [PATCH 10/24] gallium/radeon: pass pipe_resource and other params to surface_init directly

Marek Olšák maraeo at gmail.com
Mon Oct 24 22:33:10 UTC 2016


From: Marek Olšák <marek.olsak at amd.com>

This removes input-only parameters from the radeon_surf structure.

Some of the translation logic from pipe_resource to radeon_surf is moved to
winsys/radeon.
---
 src/gallium/drivers/radeon/r600_texture.c          | 120 ++++++-----------
 src/gallium/drivers/radeon/radeon_winsys.h         |  33 ++---
 src/gallium/winsys/amdgpu/drm/amdgpu_surface.c     | 146 +++++++++++----------
 src/gallium/winsys/radeon/drm/radeon_drm_surface.c |  73 ++++++++---
 4 files changed, 179 insertions(+), 193 deletions(-)

diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c
index daa743e..a89b285 100644
--- a/src/gallium/drivers/radeon/r600_texture.c
+++ b/src/gallium/drivers/radeon/r600_texture.c
@@ -196,129 +196,90 @@ static int r600_init_surface(struct r600_common_screen *rscreen,
 			     unsigned pitch_in_bytes_override,
 			     unsigned offset,
 			     bool is_imported,
 			     bool is_scanout,
 			     bool is_flushed_depth,
 			     bool tc_compatible_htile)
 {
 	const struct util_format_description *desc =
 		util_format_description(ptex->format);
 	bool is_depth, is_stencil;
-	int r, i;
+	int r;
+	unsigned i, bpe, flags = 0;
 
 	is_depth = util_format_has_depth(desc);
 	is_stencil = util_format_has_stencil(desc);
 
-	surface->npix_x = ptex->width0;
-	surface->npix_y = ptex->height0;
-	surface->npix_z = ptex->depth0;
-	surface->blk_w = util_format_get_blockwidth(ptex->format);
-	surface->blk_h = util_format_get_blockheight(ptex->format);
-	surface->blk_d = 1;
-	surface->array_size = 1;
-	surface->last_level = ptex->last_level;
-
 	if (rscreen->chip_class >= EVERGREEN && !is_flushed_depth &&
 	    ptex->format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) {
-		surface->bpe = 4; /* stencil is allocated separately on evergreen */
+		bpe = 4; /* stencil is allocated separately on evergreen */
 	} else {
-		surface->bpe = util_format_get_blocksize(ptex->format);
+		bpe = util_format_get_blocksize(ptex->format);
 		/* align byte per element on dword */
-		if (surface->bpe == 3) {
-			surface->bpe = 4;
+		if (bpe == 3) {
+			bpe = 4;
 		}
 	}
 
-	surface->nsamples = ptex->nr_samples ? ptex->nr_samples : 1;
-	surface->flags = RADEON_SURF_SET(array_mode, MODE);
-
-	switch (ptex->target) {
-	case PIPE_TEXTURE_1D:
-		surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_1D, TYPE);
-		break;
-	case PIPE_TEXTURE_RECT:
-	case PIPE_TEXTURE_2D:
-		surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE);
-		break;
-	case PIPE_TEXTURE_3D:
-		surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_3D, TYPE);
-		break;
-	case PIPE_TEXTURE_1D_ARRAY:
-		surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_1D_ARRAY, TYPE);
-		surface->array_size = ptex->array_size;
-		break;
-	case PIPE_TEXTURE_CUBE_ARRAY: /* cube array layout like 2d array */
-		assert(ptex->array_size % 6 == 0);
-	case PIPE_TEXTURE_2D_ARRAY:
-		surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D_ARRAY, TYPE);
-		surface->array_size = ptex->array_size;
-		break;
-	case PIPE_TEXTURE_CUBE:
-		surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_CUBEMAP, TYPE);
-		break;
-	case PIPE_BUFFER:
-	default:
-		return -EINVAL;
-	}
-
 	if (!is_flushed_depth && is_depth) {
-		surface->flags |= RADEON_SURF_ZBUFFER;
+		flags |= RADEON_SURF_ZBUFFER;
 
 		if (tc_compatible_htile &&
 		    array_mode == RADEON_SURF_MODE_2D) {
 			/* TC-compatible HTILE only supports Z32_FLOAT.
 			 * Promote Z16 to Z32. DB->CB copies will convert
 			 * the format for transfers.
 			 */
-			surface->bpe = 4;
-			surface->flags |= RADEON_SURF_TC_COMPATIBLE_HTILE;
+			bpe = 4;
+			flags |= RADEON_SURF_TC_COMPATIBLE_HTILE;
 		}
 
 		if (is_stencil) {
-			surface->flags |= RADEON_SURF_SBUFFER |
-					  RADEON_SURF_HAS_SBUFFER_MIPTREE;
+			flags |= RADEON_SURF_SBUFFER |
+				 RADEON_SURF_HAS_SBUFFER_MIPTREE;
 		}
 	}
 
 	if (rscreen->chip_class >= SI) {
-		surface->flags |= RADEON_SURF_HAS_TILE_MODE_INDEX;
+		flags |= RADEON_SURF_HAS_TILE_MODE_INDEX;
 	}
 
 	if (rscreen->chip_class >= VI &&
 	    (ptex->flags & R600_RESOURCE_FLAG_DISABLE_DCC ||
 	     ptex->format == PIPE_FORMAT_R9G9B9E5_FLOAT))
-		surface->flags |= RADEON_SURF_DISABLE_DCC;
+		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 &&
 		       ptex->array_size == 1 &&
 		       ptex->depth0 == 1 &&
 		       ptex->last_level == 0 &&
-		       !(surface->flags & RADEON_SURF_Z_OR_SBUFFER));
+		       !(flags & RADEON_SURF_Z_OR_SBUFFER));
 
-		surface->flags |= RADEON_SURF_SCANOUT;
+		flags |= RADEON_SURF_SCANOUT;
 	}
 
 	if (is_imported)
-		surface->flags |= RADEON_SURF_IMPORTED;
+		flags |= RADEON_SURF_IMPORTED;
 
-	r = rscreen->ws->surface_init(rscreen->ws, surface);
+	r = rscreen->ws->surface_init(rscreen->ws, ptex, flags, bpe,
+				      array_mode, surface);
 	if (r) {
 		return r;
 	}
 
 	if (pitch_in_bytes_override && pitch_in_bytes_override != surface->level[0].pitch_bytes) {
 		/* old ddx on evergreen over estimate alignment for 1d, only 1 level
 		 * for those
 		 */
-		surface->level[0].nblk_x = pitch_in_bytes_override / surface->bpe;
+		surface->level[0].nblk_x = pitch_in_bytes_override / bpe;
 		surface->level[0].pitch_bytes = pitch_in_bytes_override;
 		surface->level[0].slice_size = pitch_in_bytes_override * surface->level[0].nblk_y;
 	}
 
 	if (offset) {
 		for (i = 0; i < ARRAY_SIZE(surface->level); ++i)
 			surface->level[i].offset += offset;
 	}
 	return 0;
 }
@@ -622,63 +583,64 @@ static void r600_texture_destroy(struct pipe_screen *screen,
 
 static const struct u_resource_vtbl r600_texture_vtbl;
 
 /* The number of samples can be specified independently of the texture. */
 void r600_texture_get_fmask_info(struct r600_common_screen *rscreen,
 				 struct r600_texture *rtex,
 				 unsigned nr_samples,
 				 struct r600_fmask_info *out)
 {
 	/* FMASK is allocated like an ordinary texture. */
-	struct radeon_surf fmask = rtex->surface;
+	struct pipe_resource templ = rtex->resource.b.b;
+	struct radeon_surf fmask = {};
+	unsigned flags, bpe;
 
 	memset(out, 0, sizeof(*out));
 
-	fmask.bo_alignment = 0;
-	fmask.bo_size = 0;
-	fmask.nsamples = 1;
-	fmask.flags |= RADEON_SURF_FMASK;
+	templ.nr_samples = 1;
+	flags = rtex->surface.flags | RADEON_SURF_FMASK;
 
-	/* Force 2D tiling if it wasn't set. This may occur when creating
-	 * FMASK for MSAA resolve on R6xx. On R6xx, the single-sample
-	 * destination buffer must have an FMASK too. */
-	fmask.flags = RADEON_SURF_CLR(fmask.flags, MODE);
-	fmask.flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
+	/* Use the same parameters and tile mode. */
+	fmask.bankw = rtex->surface.bankw;
+	fmask.bankh = rtex->surface.bankh;
+	fmask.mtilea = rtex->surface.mtilea;
+	fmask.tile_split = rtex->surface.tile_split;
 
 	if (rscreen->chip_class >= SI) {
-		fmask.flags |= RADEON_SURF_HAS_TILE_MODE_INDEX;
+		flags |= RADEON_SURF_HAS_TILE_MODE_INDEX;
 	}
 
 	switch (nr_samples) {
 	case 2:
 	case 4:
-		fmask.bpe = 1;
+		bpe = 1;
 		if (rscreen->chip_class <= CAYMAN) {
 			fmask.bankh = 4;
 		}
 		break;
 	case 8:
-		fmask.bpe = 4;
+		bpe = 4;
 		break;
 	default:
 		R600_ERR("Invalid sample count for FMASK allocation.\n");
 		return;
 	}
 
 	/* Overallocate FMASK on R600-R700 to fix colorbuffer corruption.
 	 * This can be fixed by writing a separate FMASK allocator specifically
 	 * for R600-R700 asics. */
 	if (rscreen->chip_class <= R700) {
-		fmask.bpe *= 2;
+		bpe *= 2;
 	}
 
-	if (rscreen->ws->surface_init(rscreen->ws, &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;
 	}
 
 	assert(fmask.level[0].mode == RADEON_SURF_MODE_2D);
 
 	out->slice_tile_max = (fmask.level[0].nblk_x * fmask.level[0].nblk_y) / 64;
 	if (out->slice_tile_max)
 		out->slice_tile_max -= 1;
 
@@ -951,27 +913,27 @@ static void r600_texture_allocate_htile(struct r600_common_screen *rscreen,
 					 0, htile_size, clear_value,
 					 R600_COHERENCY_NONE);
 	}
 }
 
 void r600_print_texture_info(struct r600_texture *rtex, FILE *f)
 {
 	int i;
 
 	fprintf(f, "  Info: npix_x=%u, npix_y=%u, npix_z=%u, blk_w=%u, "
-		"blk_h=%u, blk_d=%u, array_size=%u, last_level=%u, "
+		"blk_h=%u, array_size=%u, last_level=%u, "
 		"bpe=%u, nsamples=%u, flags=0x%x, %s\n",
-		rtex->surface.npix_x, rtex->surface.npix_y,
-		rtex->surface.npix_z, rtex->surface.blk_w,
-		rtex->surface.blk_h, rtex->surface.blk_d,
-		rtex->surface.array_size, rtex->surface.last_level,
-		rtex->surface.bpe, rtex->surface.nsamples,
+		rtex->resource.b.b.width0, rtex->resource.b.b.height0,
+		rtex->resource.b.b.depth0, rtex->surface.blk_w,
+		rtex->surface.blk_h,
+		rtex->resource.b.b.array_size, rtex->resource.b.b.last_level,
+		rtex->surface.bpe, rtex->resource.b.b.nr_samples,
 		rtex->surface.flags, util_format_short_name(rtex->resource.b.b.format));
 
 	fprintf(f, "  Layout: size=%"PRIu64", alignment=%"PRIu64", bankw=%u, "
 		"bankh=%u, nbanks=%u, mtilea=%u, tilesplit=%u, pipeconfig=%u, scanout=%u\n",
 		rtex->surface.bo_size, rtex->surface.bo_alignment, rtex->surface.bankw,
 		rtex->surface.bankh, rtex->surface.num_banks, rtex->surface.mtilea,
 		rtex->surface.tile_split, rtex->surface.pipe_config,
 		(rtex->surface.flags & RADEON_SURF_SCANOUT) != 0);
 
 	if (rtex->fmask.size)
diff --git a/src/gallium/drivers/radeon/radeon_winsys.h b/src/gallium/drivers/radeon/radeon_winsys.h
index 3bd141e..4b79752 100644
--- a/src/gallium/drivers/radeon/radeon_winsys.h
+++ b/src/gallium/drivers/radeon/radeon_winsys.h
@@ -256,73 +256,53 @@ enum radeon_feature_id {
 };
 
 #define RADEON_SURF_MAX_LEVEL                   32
 
 enum radeon_surf_mode {
     RADEON_SURF_MODE_LINEAR_ALIGNED = 1,
     RADEON_SURF_MODE_1D = 2,
     RADEON_SURF_MODE_2D = 3,
 };
 
-#define RADEON_SURF_TYPE_MASK                   0xFF
-#define RADEON_SURF_TYPE_SHIFT                  0
-#define     RADEON_SURF_TYPE_1D                     0
-#define     RADEON_SURF_TYPE_2D                     1
-#define     RADEON_SURF_TYPE_3D                     2
-#define     RADEON_SURF_TYPE_CUBEMAP                3
-#define     RADEON_SURF_TYPE_1D_ARRAY               4
-#define     RADEON_SURF_TYPE_2D_ARRAY               5
-#define RADEON_SURF_MODE_MASK                   0xFF
-#define RADEON_SURF_MODE_SHIFT                  8
+/* the first 16 bits are reserved for libdrm_radeon, don't use them */
 #define RADEON_SURF_SCANOUT                     (1 << 16)
 #define RADEON_SURF_ZBUFFER                     (1 << 17)
 #define RADEON_SURF_SBUFFER                     (1 << 18)
 #define RADEON_SURF_Z_OR_SBUFFER                (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)
 #define RADEON_SURF_HAS_SBUFFER_MIPTREE         (1 << 19)
 #define RADEON_SURF_HAS_TILE_MODE_INDEX         (1 << 20)
 #define RADEON_SURF_FMASK                       (1 << 21)
 #define RADEON_SURF_DISABLE_DCC                 (1 << 22)
 #define RADEON_SURF_TC_COMPATIBLE_HTILE         (1 << 23)
 #define RADEON_SURF_IMPORTED                    (1 << 24)
 
-#define RADEON_SURF_GET(v, field)   (((v) >> RADEON_SURF_ ## field ## _SHIFT) & RADEON_SURF_ ## field ## _MASK)
-#define RADEON_SURF_SET(v, field)   (((v) & RADEON_SURF_ ## field ## _MASK) << RADEON_SURF_ ## field ## _SHIFT)
-#define RADEON_SURF_CLR(v, field)   ((v) & ~(RADEON_SURF_ ## field ## _MASK << RADEON_SURF_ ## field ## _SHIFT))
-
 struct radeon_surf_level {
     uint64_t                    offset;
     uint64_t                    slice_size;
     uint32_t                    npix_x;
     uint32_t                    npix_y;
     uint32_t                    npix_z;
     uint32_t                    nblk_x;
     uint32_t                    nblk_y;
     uint32_t                    nblk_z;
     uint32_t                    pitch_bytes;
     enum radeon_surf_mode       mode;
     uint64_t                    dcc_offset;
     uint64_t                    dcc_fast_clear_size;
     bool                        dcc_enabled;
 };
 
 struct radeon_surf {
-    /* These are inputs to the calculator. */
-    uint32_t                    npix_x;
-    uint32_t                    npix_y;
-    uint32_t                    npix_z;
+    /* Format properties. */
     uint32_t                    blk_w;
     uint32_t                    blk_h;
-    uint32_t                    blk_d;
-    uint32_t                    array_size;
-    uint32_t                    last_level;
     uint32_t                    bpe;
-    uint32_t                    nsamples;
     uint32_t                    flags;
 
     /* These are return values. Some of them can be set by the caller, but
      * they will be treated as hints (e.g. bankw, bankh) and might be
      * changed by the calculator.
      */
     uint64_t                    bo_size;
     uint64_t                    bo_alignment;
     /* This applies to EG and later. */
     uint32_t                    bankw;
@@ -736,23 +716,30 @@ struct radeon_winsys {
     /**
      * Reference counting for fences.
      */
     void (*fence_reference)(struct pipe_fence_handle **dst,
                             struct pipe_fence_handle *src);
 
     /**
      * Initialize surface
      *
      * \param ws        The winsys this function is called from.
-     * \param surf      Surface structure ptr
+     * \param tex       Input texture description
+     * \param flags     Bitmask of RADEON_SURF_* flags
+     * \param bpe       Bytes per pixel, it can be different for Z buffers.
+     * \param mode      Preferred tile mode. (linear, 1D, or 2D)
+     * \param surf      Output structure
      */
     int (*surface_init)(struct radeon_winsys *ws,
+                        const struct pipe_resource *tex,
+                        unsigned flags, unsigned bpe,
+                        enum radeon_surf_mode mode,
                         struct radeon_surf *surf);
 
     uint64_t (*query_value)(struct radeon_winsys *ws,
                             enum radeon_value_id value);
 
     bool (*read_registers)(struct radeon_winsys *ws, unsigned reg_offset,
                            unsigned num_registers, uint32_t *out);
 };
 
 static inline bool radeon_emitted(struct radeon_winsys_cs *cs, unsigned num_dw)
diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c b/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c
index 94fe7d6..3b4c13b 100644
--- a/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c
+++ b/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c
@@ -23,71 +23,67 @@
  * The above copyright notice and this permission notice (including the
  * next paragraph) shall be included in all copies or substantial portions
  * of the Software.
  */
 
 /* Contact:
  *     Marek Olšák <maraeo at gmail.com>
  */
 
 #include "amdgpu_winsys.h"
+#include "util/u_format.h"
 
 #ifndef CIASICIDGFXENGINE_SOUTHERNISLAND
 #define CIASICIDGFXENGINE_SOUTHERNISLAND 0x0000000A
 #endif
 
 
-static int amdgpu_surface_sanity(const struct radeon_surf *surf)
+static int amdgpu_surface_sanity(const struct pipe_resource *tex)
 {
-   unsigned type = RADEON_SURF_GET(surf->flags, TYPE);
-
-   if (!(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX))
-      return -EINVAL;
-
    /* all dimension must be at least 1 ! */
-   if (!surf->npix_x || !surf->npix_y || !surf->npix_z ||
-       !surf->array_size)
+   if (!tex->width0 || !tex->height0 || !tex->depth0 ||
+       !tex->array_size)
       return -EINVAL;
 
-   if (!surf->blk_w || !surf->blk_h || !surf->blk_d)
-      return -EINVAL;
-
-   switch (surf->nsamples) {
+   switch (tex->nr_samples) {
+   case 0:
    case 1:
    case 2:
    case 4:
    case 8:
       break;
    default:
       return -EINVAL;
    }
 
-   switch (type) {
-   case RADEON_SURF_TYPE_1D:
-      if (surf->npix_y > 1)
+   switch (tex->target) {
+   case PIPE_TEXTURE_1D:
+      if (tex->height0 > 1)
          return -EINVAL;
       /* fall through */
-   case RADEON_SURF_TYPE_2D:
-   case RADEON_SURF_TYPE_CUBEMAP:
-      if (surf->npix_z > 1 || surf->array_size > 1)
+   case PIPE_TEXTURE_2D:
+   case PIPE_TEXTURE_RECT:
+      if (tex->depth0 > 1 || tex->array_size > 1)
          return -EINVAL;
       break;
-   case RADEON_SURF_TYPE_3D:
-      if (surf->array_size > 1)
+   case PIPE_TEXTURE_3D:
+      if (tex->array_size > 1)
          return -EINVAL;
       break;
-   case RADEON_SURF_TYPE_1D_ARRAY:
-      if (surf->npix_y > 1)
+   case PIPE_TEXTURE_1D_ARRAY:
+      if (tex->height0 > 1)
          return -EINVAL;
       /* fall through */
-   case RADEON_SURF_TYPE_2D_ARRAY:
-      if (surf->npix_z > 1)
+   case PIPE_TEXTURE_CUBE:
+   case PIPE_TEXTURE_2D_ARRAY:
+   case PIPE_TEXTURE_CUBE_ARRAY:
+      if (tex->depth0 > 1)
          return -EINVAL;
       break;
    default:
       return -EINVAL;
    }
    return 0;
 }
 
 static void *ADDR_API allocSysMem(const ADDR_ALLOCSYSMEM_INPUT * pInput)
 {
@@ -141,42 +137,43 @@ ADDR_HANDLE amdgpu_addr_create(struct amdgpu_winsys *ws)
    addrCreateInput.regValue = regValue;
 
    addrRet = AddrCreate(&addrCreateInput, &addrCreateOutput);
    if (addrRet != ADDR_OK)
       return NULL;
 
    return addrCreateOutput.hLib;
 }
 
 static int compute_level(struct amdgpu_winsys *ws,
+                         const struct pipe_resource *tex,
                          struct radeon_surf *surf, bool is_stencil,
-                         unsigned level, unsigned type, bool compressed,
+                         unsigned level, bool compressed,
                          ADDR_COMPUTE_SURFACE_INFO_INPUT *AddrSurfInfoIn,
                          ADDR_COMPUTE_SURFACE_INFO_OUTPUT *AddrSurfInfoOut,
                          ADDR_COMPUTE_DCCINFO_INPUT *AddrDccIn,
                          ADDR_COMPUTE_DCCINFO_OUTPUT *AddrDccOut,
                          ADDR_COMPUTE_HTILE_INFO_INPUT *AddrHtileIn,
                          ADDR_COMPUTE_HTILE_INFO_OUTPUT *AddrHtileOut)
 {
    struct radeon_surf_level *surf_level;
    ADDR_E_RETURNCODE ret;
 
    AddrSurfInfoIn->mipLevel = level;
-   AddrSurfInfoIn->width = u_minify(surf->npix_x, level);
-   AddrSurfInfoIn->height = u_minify(surf->npix_y, level);
+   AddrSurfInfoIn->width = u_minify(tex->width0, level);
+   AddrSurfInfoIn->height = u_minify(tex->height0, level);
 
-   if (type == RADEON_SURF_TYPE_3D)
-      AddrSurfInfoIn->numSlices = u_minify(surf->npix_z, level);
-   else if (type == RADEON_SURF_TYPE_CUBEMAP)
+   if (tex->target == PIPE_TEXTURE_3D)
+      AddrSurfInfoIn->numSlices = u_minify(tex->depth0, level);
+   else if (tex->target == PIPE_TEXTURE_CUBE)
       AddrSurfInfoIn->numSlices = 6;
    else
-      AddrSurfInfoIn->numSlices = surf->array_size;
+      AddrSurfInfoIn->numSlices = tex->array_size;
 
    if (level > 0) {
       /* Set the base level pitch. This is needed for calculation
        * of non-zero levels. */
       if (is_stencil)
          AddrSurfInfoIn->basePitch = surf->stencil_level[0].nblk_x;
       else
          AddrSurfInfoIn->basePitch = surf->level[0].nblk_x;
 
       /* Convert blocks to pixels for compressed formats. */
@@ -188,26 +185,26 @@ static int compute_level(struct amdgpu_winsys *ws,
                                 AddrSurfInfoIn,
                                 AddrSurfInfoOut);
    if (ret != ADDR_OK) {
       return ret;
    }
 
    surf_level = is_stencil ? &surf->stencil_level[level] : &surf->level[level];
    surf_level->offset = align64(surf->bo_size, AddrSurfInfoOut->baseAlign);
    surf_level->slice_size = AddrSurfInfoOut->sliceSize;
    surf_level->pitch_bytes = AddrSurfInfoOut->pitch * (is_stencil ? 1 : surf->bpe);
-   surf_level->npix_x = u_minify(surf->npix_x, level);
-   surf_level->npix_y = u_minify(surf->npix_y, level);
-   surf_level->npix_z = u_minify(surf->npix_z, level);
+   surf_level->npix_x = u_minify(tex->width0, level);
+   surf_level->npix_y = u_minify(tex->height0, level);
+   surf_level->npix_z = u_minify(tex->depth0, level);
    surf_level->nblk_x = AddrSurfInfoOut->pitch;
    surf_level->nblk_y = AddrSurfInfoOut->height;
-   if (type == RADEON_SURF_TYPE_3D)
+   if (tex->target == PIPE_TEXTURE_3D)
       surf_level->nblk_z = AddrSurfInfoOut->depth;
    else
       surf_level->nblk_z = 1;
 
    switch (AddrSurfInfoOut->tileMode) {
    case ADDR_TM_LINEAR_ALIGNED:
       surf_level->mode = RADEON_SURF_MODE_LINEAR_ALIGNED;
       break;
    case ADDR_TM_1D_TILED_THIN1:
       surf_level->mode = RADEON_SURF_MODE_1D;
@@ -303,58 +300,64 @@ static unsigned cik_get_macro_tile_index(struct radeon_surf *surf)
 	tileb = MIN2(surf->tile_split, tileb);
 
 	for (index = 0; tileb > 64; index++)
 		tileb >>= 1;
 
 	assert(index < 16);
 	return index;
 }
 
 static int amdgpu_surface_init(struct radeon_winsys *rws,
+                               const struct pipe_resource *tex,
+                               unsigned flags, unsigned bpe,
+                               enum radeon_surf_mode mode,
                                struct radeon_surf *surf)
 {
    struct amdgpu_winsys *ws = (struct amdgpu_winsys*)rws;
-   unsigned level, mode, type;
+   unsigned level;
    bool compressed;
    ADDR_COMPUTE_SURFACE_INFO_INPUT AddrSurfInfoIn = {0};
    ADDR_COMPUTE_SURFACE_INFO_OUTPUT AddrSurfInfoOut = {0};
    ADDR_COMPUTE_DCCINFO_INPUT AddrDccIn = {0};
    ADDR_COMPUTE_DCCINFO_OUTPUT AddrDccOut = {0};
    ADDR_COMPUTE_HTILE_INFO_INPUT AddrHtileIn = {0};
    ADDR_COMPUTE_HTILE_INFO_OUTPUT AddrHtileOut = {0};
    ADDR_TILEINFO AddrTileInfoIn = {0};
    ADDR_TILEINFO AddrTileInfoOut = {0};
    int r;
 
-   r = amdgpu_surface_sanity(surf);
+   r = amdgpu_surface_sanity(tex);
    if (r)
       return r;
 
    AddrSurfInfoIn.size = sizeof(ADDR_COMPUTE_SURFACE_INFO_INPUT);
    AddrSurfInfoOut.size = sizeof(ADDR_COMPUTE_SURFACE_INFO_OUTPUT);
    AddrDccIn.size = sizeof(ADDR_COMPUTE_DCCINFO_INPUT);
    AddrDccOut.size = sizeof(ADDR_COMPUTE_DCCINFO_OUTPUT);
    AddrHtileIn.size = sizeof(ADDR_COMPUTE_HTILE_INFO_INPUT);
    AddrHtileOut.size = sizeof(ADDR_COMPUTE_HTILE_INFO_OUTPUT);
    AddrSurfInfoOut.pTileInfo = &AddrTileInfoOut;
 
-   type = RADEON_SURF_GET(surf->flags, TYPE);
-   mode = RADEON_SURF_GET(surf->flags, MODE);
+   surf->blk_w = util_format_get_blockwidth(tex->format);
+   surf->blk_h = util_format_get_blockheight(tex->format);
+   surf->bpe = bpe;
+   surf->flags = flags;
+
    compressed = surf->blk_w == 4 && surf->blk_h == 4;
 
    /* MSAA and FMASK require 2D tiling. */
-   if (surf->nsamples > 1 ||
-       (surf->flags & RADEON_SURF_FMASK))
+   if (tex->nr_samples > 1 ||
+       (flags & RADEON_SURF_FMASK))
       mode = RADEON_SURF_MODE_2D;
 
    /* DB doesn't support linear layouts. */
-   if (surf->flags & (RADEON_SURF_Z_OR_SBUFFER) &&
+   if (flags & (RADEON_SURF_Z_OR_SBUFFER) &&
        mode < RADEON_SURF_MODE_1D)
       mode = RADEON_SURF_MODE_1D;
 
    /* Set the requested tiling mode. */
    switch (mode) {
    case RADEON_SURF_MODE_LINEAR_ALIGNED:
       AddrSurfInfoIn.tileMode = ADDR_TM_LINEAR_ALIGNED;
       break;
    case RADEON_SURF_MODE_1D:
       AddrSurfInfoIn.tileMode = ADDR_TM_1D_TILED_THIN1;
@@ -362,82 +365,83 @@ static int amdgpu_surface_init(struct radeon_winsys *rws,
    case RADEON_SURF_MODE_2D:
       AddrSurfInfoIn.tileMode = ADDR_TM_2D_TILED_THIN1;
       break;
    default:
       assert(0);
    }
 
    /* The format must be set correctly for the allocation of compressed
     * textures to work. In other cases, setting the bpp is sufficient. */
    if (compressed) {
-      switch (surf->bpe) {
+      switch (bpe) {
       case 8:
          AddrSurfInfoIn.format = ADDR_FMT_BC1;
          break;
       case 16:
          AddrSurfInfoIn.format = ADDR_FMT_BC3;
          break;
       default:
          assert(0);
       }
    }
    else {
-      AddrDccIn.bpp = AddrSurfInfoIn.bpp = surf->bpe * 8;
+      AddrDccIn.bpp = AddrSurfInfoIn.bpp = bpe * 8;
    }
 
-   AddrDccIn.numSamples = AddrSurfInfoIn.numSamples = surf->nsamples;
+   AddrDccIn.numSamples = AddrSurfInfoIn.numSamples =
+      tex->nr_samples ? tex->nr_samples : 1;
    AddrSurfInfoIn.tileIndex = -1;
 
    /* Set the micro tile type. */
-   if (surf->flags & RADEON_SURF_SCANOUT)
+   if (flags & RADEON_SURF_SCANOUT)
       AddrSurfInfoIn.tileType = ADDR_DISPLAYABLE;
-   else if (surf->flags & RADEON_SURF_Z_OR_SBUFFER)
+   else if (flags & RADEON_SURF_Z_OR_SBUFFER)
       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 = type == RADEON_SURF_TYPE_CUBEMAP;
-   AddrSurfInfoIn.flags.display = (surf->flags & RADEON_SURF_SCANOUT) != 0;
-   AddrSurfInfoIn.flags.pow2Pad = surf->last_level > 0;
-   AddrSurfInfoIn.flags.tcCompatible = (surf->flags & RADEON_SURF_TC_COMPATIBLE_HTILE) != 0;
+   AddrSurfInfoIn.flags.color = !(flags & RADEON_SURF_Z_OR_SBUFFER);
+   AddrSurfInfoIn.flags.depth = (flags & RADEON_SURF_ZBUFFER) != 0;
+   AddrSurfInfoIn.flags.cube = tex->target == PIPE_TEXTURE_CUBE;
+   AddrSurfInfoIn.flags.display = (flags & RADEON_SURF_SCANOUT) != 0;
+   AddrSurfInfoIn.flags.pow2Pad = tex->last_level > 0;
+   AddrSurfInfoIn.flags.tcCompatible = (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.degrade4Space = !AddrSurfInfoIn.flags.tcCompatible;
 
    /* DCC notes:
     * - If we add MSAA support, keep in mind that CB can't decompress 8bpp
     *   with samples >= 4.
     * - Mipmapped array textures have low performance (discovered by a closed
     *   driver team).
     */
    AddrSurfInfoIn.flags.dccCompatible = ws->info.chip_class >= VI &&
-                                        !(surf->flags & RADEON_SURF_Z_OR_SBUFFER) &&
-                                        !(surf->flags & RADEON_SURF_DISABLE_DCC) &&
+                                        !(flags & RADEON_SURF_Z_OR_SBUFFER) &&
+                                        !(flags & RADEON_SURF_DISABLE_DCC) &&
                                         !compressed && AddrDccIn.numSamples <= 1 &&
-                                        ((surf->array_size == 1 && surf->npix_z == 1) ||
-                                         surf->last_level == 0);
+                                        ((tex->array_size == 1 && tex->depth0 == 1) ||
+                                         tex->last_level == 0);
 
-   AddrSurfInfoIn.flags.noStencil = (surf->flags & RADEON_SURF_SBUFFER) == 0;
+   AddrSurfInfoIn.flags.noStencil = (flags & RADEON_SURF_SBUFFER) == 0;
    AddrSurfInfoIn.flags.compressZ = AddrSurfInfoIn.flags.depth;
 
    /* noStencil = 0 can result in a depth part that is incompatible with
     * mipmapped texturing. So set noStencil = 1 when mipmaps are requested (in
     * this case, we may end up setting stencil_adjusted).
     *
     * TODO: update addrlib to a newer version, remove this, and
     * use flags.matchStencilTileCfg = 1 as an alternative fix.
     */
-  if (surf->last_level > 0)
+  if (tex->last_level > 0)
       AddrSurfInfoIn.flags.noStencil = 1;
 
    /* Set preferred macrotile parameters. This is usually required
     * for shared resources. This is for 2D tiling only. */
    if (AddrSurfInfoIn.tileMode >= ADDR_TM_2D_TILED_THIN1 &&
        surf->bankw && surf->bankh && surf->mtilea && surf->tile_split) {
       /* If any of these parameters are incorrect, the calculation
        * will fail. */
       AddrTileInfoIn.banks = surf->num_banks;
       AddrTileInfoIn.bankWidth = surf->bankw;
@@ -449,35 +453,35 @@ static int amdgpu_surface_init(struct radeon_winsys *rws,
       AddrSurfInfoIn.pTileInfo = &AddrTileInfoIn;
 
       /* If AddrSurfInfoIn.pTileInfo is set, Addrlib doesn't set
        * the tile index, because we are expected to know it if
        * we know the other parameters.
        *
        * This is something that can easily be fixed in Addrlib.
        * For now, just figure it out here.
        * Note that only 2D_TILE_THIN1 is handled here.
        */
-      assert(!(surf->flags & RADEON_SURF_Z_OR_SBUFFER));
+      assert(!(flags & RADEON_SURF_Z_OR_SBUFFER));
       assert(AddrSurfInfoIn.tileMode == ADDR_TM_2D_TILED_THIN1);
 
       if (ws->info.chip_class == SI) {
          if (AddrSurfInfoIn.tileType == ADDR_DISPLAYABLE) {
-            if (surf->bpe == 2)
+            if (bpe == 2)
                AddrSurfInfoIn.tileIndex = 11; /* 16bpp */
             else
                AddrSurfInfoIn.tileIndex = 12; /* 32bpp */
          } else {
-            if (surf->bpe == 1)
+            if (bpe == 1)
                AddrSurfInfoIn.tileIndex = 14; /* 8bpp */
-            else if (surf->bpe == 2)
+            else if (bpe == 2)
                AddrSurfInfoIn.tileIndex = 15; /* 16bpp */
-            else if (surf->bpe == 4)
+            else if (bpe == 4)
                AddrSurfInfoIn.tileIndex = 16; /* 32bpp */
             else
                AddrSurfInfoIn.tileIndex = 17; /* 64bpp (and 128bpp) */
          }
       } else {
          /* CIK - VI */
          if (AddrSurfInfoIn.tileType == ADDR_DISPLAYABLE)
             AddrSurfInfoIn.tileIndex = 10; /* 2D displayable */
          else
             AddrSurfInfoIn.tileIndex = 14; /* 2D non-displayable */
@@ -487,22 +491,22 @@ static int amdgpu_surface_init(struct radeon_winsys *rws,
       }
    }
 
    surf->bo_size = 0;
    surf->dcc_size = 0;
    surf->dcc_alignment = 1;
    surf->htile_size = 0;
    surf->htile_alignment = 1;
 
    /* Calculate texture layout information. */
-   for (level = 0; level <= surf->last_level; level++) {
-      r = compute_level(ws, surf, false, level, type, compressed,
+   for (level = 0; level <= tex->last_level; level++) {
+      r = compute_level(ws, tex, surf, false, level, compressed,
                         &AddrSurfInfoIn, &AddrSurfInfoOut,
                         &AddrDccIn, &AddrDccOut, &AddrHtileIn, &AddrHtileOut);
       if (r)
          return r;
 
       if (level == 0) {
          surf->bo_alignment = AddrSurfInfoOut.baseAlign;
          surf->pipe_config = AddrSurfInfoOut.pTileInfo->pipeConfig - 1;
          set_micro_tile_mode(surf, &ws->info);
 
@@ -514,30 +518,30 @@ static int amdgpu_surface_init(struct radeon_winsys *rws,
             surf->tile_split = AddrSurfInfoOut.pTileInfo->tileSplitBytes;
             surf->num_banks = AddrSurfInfoOut.pTileInfo->banks;
             surf->macro_tile_index = AddrSurfInfoOut.macroModeIndex;
          } else {
             surf->macro_tile_index = 0;
          }
       }
    }
 
    /* Calculate texture layout information for stencil. */
-   if (surf->flags & RADEON_SURF_SBUFFER) {
+   if (flags & RADEON_SURF_SBUFFER) {
       AddrSurfInfoIn.bpp = 8;
       AddrSurfInfoIn.flags.depth = 0;
       AddrSurfInfoIn.flags.stencil = 1;
       AddrSurfInfoIn.flags.tcCompatible = 0;
       /* This will be ignored if AddrSurfInfoIn.pTileInfo is NULL. */
       AddrTileInfoIn.tileSplitBytes = surf->stencil_tile_split;
 
-      for (level = 0; level <= surf->last_level; level++) {
-         r = compute_level(ws, surf, true, level, type, compressed,
+      for (level = 0; level <= tex->last_level; level++) {
+         r = compute_level(ws, tex, surf, true, level, compressed,
                            &AddrSurfInfoIn, &AddrSurfInfoOut, &AddrDccIn, &AddrDccOut,
                            NULL, NULL);
          if (r)
             return r;
 
          /* DB uses the depth pitch for both stencil and depth. */
          if (surf->stencil_level[level].nblk_x != surf->level[level].nblk_x)
             surf->stencil_adjusted = true;
 
          if (level == 0) {
@@ -547,29 +551,29 @@ static int amdgpu_surface_init(struct radeon_winsys *rws,
                      AddrSurfInfoOut.pTileInfo->tileSplitBytes;
             }
          }
       }
    }
 
    /* Recalculate the whole DCC miptree size including disabled levels.
     * This is what addrlib does, but calling addrlib would be a lot more
     * complicated.
     */
-   if (surf->dcc_size && surf->last_level > 0) {
+   if (surf->dcc_size && tex->last_level > 0) {
       surf->dcc_size = align64(surf->bo_size >> 8,
                                ws->info.pipe_interleave_bytes *
                                ws->info.num_tile_pipes);
    }
 
    /* Make sure HTILE covers the whole miptree, because the shader reads
     * TC-compatible HTILE even for levels where it's disabled by DB.
     */
-   if (surf->htile_size && surf->last_level)
+   if (surf->htile_size && tex->last_level)
 	   surf->htile_size *= 2;
 
    return 0;
 }
 
 void amdgpu_surface_init_functions(struct amdgpu_winsys *ws)
 {
    ws->base.surface_init = amdgpu_surface_init;
 }
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_surface.c b/src/gallium/winsys/radeon/drm/radeon_drm_surface.c
index 8a88ee5..fafcee1 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_surface.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_surface.c
@@ -21,21 +21,21 @@
  *
  * The above copyright notice and this permission notice (including the
  * next paragraph) shall be included in all copies or substantial portions
  * of the Software.
  *
  * Authors:
  *   Marek Olšák <maraeo at gmail.com>
  */
 
 #include "radeon_drm_winsys.h"
-
+#include "util/u_format.h"
 #include <radeon_surface.h>
 
 static unsigned cik_get_macro_tile_index(struct radeon_surf *surf)
 {
 	unsigned index, tileb;
 
 	tileb = 8 * 8 * surf->bpe;
 	tileb = MIN2(surf->tile_split, tileb);
 
 	for (index = 0; tileb > 64; index++)
@@ -90,37 +90,74 @@ static void surf_level_drm_to_winsys(struct radeon_surf_level *level_ws,
     level_ws->npix_y = level_drm->npix_y;
     level_ws->npix_z = level_drm->npix_z;
     level_ws->nblk_x = level_drm->nblk_x;
     level_ws->nblk_y = level_drm->nblk_y;
     level_ws->nblk_z = level_drm->nblk_z;
     level_ws->pitch_bytes = level_drm->pitch_bytes;
     level_ws->mode = level_drm->mode;
 }
 
 static void surf_winsys_to_drm(struct radeon_surface *surf_drm,
+                               const struct pipe_resource *tex,
+                               unsigned flags, unsigned bpe,
+                               enum radeon_surf_mode mode,
                                const struct radeon_surf *surf_ws)
 {
     int i;
 
     memset(surf_drm, 0, sizeof(*surf_drm));
 
-    surf_drm->npix_x = surf_ws->npix_x;
-    surf_drm->npix_y = surf_ws->npix_y;
-    surf_drm->npix_z = surf_ws->npix_z;
-    surf_drm->blk_w = surf_ws->blk_w;
-    surf_drm->blk_h = surf_ws->blk_h;
-    surf_drm->blk_d = surf_ws->blk_d;
-    surf_drm->array_size = surf_ws->array_size;
-    surf_drm->last_level = surf_ws->last_level;
-    surf_drm->bpe = surf_ws->bpe;
-    surf_drm->nsamples = surf_ws->nsamples;
-    surf_drm->flags = surf_ws->flags;
+    surf_drm->npix_x = tex->width0;
+    surf_drm->npix_y = tex->height0;
+    surf_drm->npix_z = tex->depth0;
+    surf_drm->blk_w = util_format_get_blockwidth(tex->format);
+    surf_drm->blk_h = util_format_get_blockheight(tex->format);
+    surf_drm->blk_d = 1;
+    surf_drm->array_size = 1;
+    surf_drm->last_level = tex->last_level;
+    surf_drm->bpe = bpe;
+    surf_drm->nsamples = tex->nr_samples ? tex->nr_samples : 1;
+
+    surf_drm->flags = flags;
+    surf_drm->flags = RADEON_SURF_CLR(surf_drm->flags, TYPE);
+    surf_drm->flags = RADEON_SURF_CLR(surf_drm->flags, MODE);
+    surf_drm->flags |= RADEON_SURF_SET(mode, MODE);
+
+    switch (tex->target) {
+    case PIPE_TEXTURE_1D:
+            surf_drm->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_1D, TYPE);
+            break;
+    case PIPE_TEXTURE_RECT:
+    case PIPE_TEXTURE_2D:
+            surf_drm->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE);
+            break;
+    case PIPE_TEXTURE_3D:
+            surf_drm->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_3D, TYPE);
+            break;
+    case PIPE_TEXTURE_1D_ARRAY:
+            surf_drm->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_1D_ARRAY, TYPE);
+            surf_drm->array_size = tex->array_size;
+            break;
+    case PIPE_TEXTURE_CUBE_ARRAY: /* cube array layout like 2d array */
+            assert(tex->array_size % 6 == 0);
+            /* fall through */
+    case PIPE_TEXTURE_2D_ARRAY:
+            surf_drm->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D_ARRAY, TYPE);
+            surf_drm->array_size = tex->array_size;
+            break;
+    case PIPE_TEXTURE_CUBE:
+            surf_drm->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_CUBEMAP, TYPE);
+            break;
+    case PIPE_BUFFER:
+    default:
+            assert(0);
+    }
 
     surf_drm->bo_size = surf_ws->bo_size;
     surf_drm->bo_alignment = surf_ws->bo_alignment;
 
     surf_drm->bankw = surf_ws->bankw;
     surf_drm->bankh = surf_ws->bankh;
     surf_drm->mtilea = surf_ws->mtilea;
     surf_drm->tile_split = surf_ws->tile_split;
     surf_drm->stencil_tile_split = surf_ws->stencil_tile_split;
 
@@ -135,30 +172,23 @@ static void surf_winsys_to_drm(struct radeon_surface *surf_drm,
 }
 
 static void surf_drm_to_winsys(struct radeon_drm_winsys *ws,
                                struct radeon_surf *surf_ws,
                                const struct radeon_surface *surf_drm)
 {
     int i;
 
     memset(surf_ws, 0, sizeof(*surf_ws));
 
-    surf_ws->npix_x = surf_drm->npix_x;
-    surf_ws->npix_y = surf_drm->npix_y;
-    surf_ws->npix_z = surf_drm->npix_z;
     surf_ws->blk_w = surf_drm->blk_w;
     surf_ws->blk_h = surf_drm->blk_h;
-    surf_ws->blk_d = surf_drm->blk_d;
-    surf_ws->array_size = surf_drm->array_size;
-    surf_ws->last_level = surf_drm->last_level;
     surf_ws->bpe = surf_drm->bpe;
-    surf_ws->nsamples = surf_drm->nsamples;
     surf_ws->flags = surf_drm->flags;
 
     surf_ws->bo_size = surf_drm->bo_size;
     surf_ws->bo_alignment = surf_drm->bo_alignment;
 
     surf_ws->bankw = surf_drm->bankw;
     surf_ws->bankh = surf_drm->bankh;
     surf_ws->mtilea = surf_drm->mtilea;
     surf_ws->tile_split = surf_drm->tile_split;
     surf_ws->stencil_tile_split = surf_drm->stencil_tile_split;
@@ -171,27 +201,30 @@ static void surf_drm_to_winsys(struct radeon_drm_winsys *ws,
                                  &surf_drm->stencil_level[i]);
 
         surf_ws->tiling_index[i] = surf_drm->tiling_index[i];
         surf_ws->stencil_tiling_index[i] = surf_drm->stencil_tiling_index[i];
     }
 
     set_micro_tile_mode(surf_ws, &ws->info);
 }
 
 static int radeon_winsys_surface_init(struct radeon_winsys *rws,
+                                      const struct pipe_resource *tex,
+                                      unsigned flags, unsigned bpe,
+                                      enum radeon_surf_mode mode,
                                       struct radeon_surf *surf_ws)
 {
     struct radeon_drm_winsys *ws = (struct radeon_drm_winsys*)rws;
     struct radeon_surface surf_drm;
     int r;
 
-    surf_winsys_to_drm(&surf_drm, surf_ws);
+    surf_winsys_to_drm(&surf_drm, tex, flags, bpe, mode, surf_ws);
 
     if (!(surf_ws->flags & RADEON_SURF_IMPORTED)) {
        r = radeon_surface_best(ws->surf_man, &surf_drm);
        if (r)
           return r;
     }
 
     r = radeon_surface_init(ws->surf_man, &surf_drm);
     if (r)
         return r;
-- 
2.7.4



More information about the mesa-dev mailing list