[Mesa-dev] [PATCH 2/9] ac: change legacy_surf_level::slice_size to dword units

Nicolai Hähnle nhaehnle at gmail.com
Wed Nov 22 18:46:20 UTC 2017


On 21.11.2017 18:30, Marek Olšák wrote:
> From: Marek Olšák <marek.olsak at amd.com>
> 
> The next commit will reduce the size even more.
> ---
>   src/amd/common/ac_surface.c                        |  2 +-
>   src/amd/common/ac_surface.h                        |  2 +-
>   src/amd/vulkan/radv_image.c                        |  8 ++++----
>   src/gallium/drivers/r600/evergreen_state.c         |  8 ++++----
>   src/gallium/drivers/r600/r600_state.c              |  8 ++++----
>   src/gallium/drivers/r600/r600_texture.c            | 14 +++++++-------
>   src/gallium/drivers/r600/radeon_uvd.c              |  2 +-
>   src/gallium/drivers/radeon/r600_texture.c          | 14 +++++++-------
>   src/gallium/drivers/radeon/radeon_uvd.c            |  2 +-
>   src/gallium/drivers/radeonsi/cik_sdma.c            |  4 ++--
>   src/gallium/drivers/radeonsi/si_dma.c              |  8 ++++----
>   src/gallium/winsys/radeon/drm/radeon_drm_surface.c |  4 ++--
>   12 files changed, 38 insertions(+), 38 deletions(-)
> 
> diff --git a/src/amd/common/ac_surface.c b/src/amd/common/ac_surface.c
> index f7600a3..2b6c3fb 100644
> --- a/src/amd/common/ac_surface.c
> +++ b/src/amd/common/ac_surface.c
> @@ -297,21 +297,21 @@ static int gfx6_compute_level(ADDR_HANDLE addrlib,
>   
>   	ret = AddrComputeSurfaceInfo(addrlib,
>   				     AddrSurfInfoIn,
>   				     AddrSurfInfoOut);
>   	if (ret != ADDR_OK) {
>   		return ret;
>   	}
>   
>   	surf_level = is_stencil ? &surf->u.legacy.stencil_level[level] : &surf->u.legacy.level[level];
>   	surf_level->offset = align64(surf->surf_size, AddrSurfInfoOut->baseAlign);
> -	surf_level->slice_size = AddrSurfInfoOut->sliceSize;
> +	surf_level->slice_size_dw = AddrSurfInfoOut->sliceSize / 4;
>   	surf_level->nblk_x = AddrSurfInfoOut->pitch;
>   	surf_level->nblk_y = AddrSurfInfoOut->height;
>   
>   	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;
>   		break;
> diff --git a/src/amd/common/ac_surface.h b/src/amd/common/ac_surface.h
> index 1dc95cd..ec89f6b 100644
> --- a/src/amd/common/ac_surface.h
> +++ b/src/amd/common/ac_surface.h
> @@ -64,21 +64,21 @@ enum radeon_micro_mode {
>   /* bits 19 and 20 are reserved for libdrm_radeon, don't use them */
>   #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_OPTIMIZE_FOR_SPACE          (1 << 25)
>   #define RADEON_SURF_SHAREABLE                   (1 << 26)
>   
>   struct legacy_surf_level {
>       uint64_t                    offset;
> -    uint64_t                    slice_size;
> +    uint32_t                    slice_size_dw; /* in dwords; max = 4GB / 4. */
>       uint32_t                    dcc_offset; /* relative offset within DCC mip tree */
>       uint32_t                    dcc_fast_clear_size;
>       uint16_t                    nblk_x;
>       uint16_t                    nblk_y;
>       enum radeon_surf_mode       mode;
>   };
>   
>   struct legacy_surf_layout {
>       unsigned                    bankw:4;  /* max 8 */
>       unsigned                    bankh:4;  /* max 8 */
> diff --git a/src/amd/vulkan/radv_image.c b/src/amd/vulkan/radv_image.c
> index b532aa9..fb7bbde 100644
> --- a/src/amd/vulkan/radv_image.c
> +++ b/src/amd/vulkan/radv_image.c
> @@ -1149,25 +1149,25 @@ void radv_GetImageSubresourceLayout(
>   
>   	if (device->physical_device->rad_info.chip_class >= GFX9) {
>   		pLayout->offset = surface->u.gfx9.offset[level] + surface->u.gfx9.surf_slice_size * layer;
>   		pLayout->rowPitch = surface->u.gfx9.surf_pitch * surface->bpe;
>   		pLayout->arrayPitch = surface->u.gfx9.surf_slice_size;
>   		pLayout->depthPitch = surface->u.gfx9.surf_slice_size;
>   		pLayout->size = surface->u.gfx9.surf_slice_size;
>   		if (image->type == VK_IMAGE_TYPE_3D)
>   			pLayout->size *= u_minify(image->info.depth, level);
>   	} else {
> -		pLayout->offset = surface->u.legacy.level[level].offset + surface->u.legacy.level[level].slice_size * layer;
> +		pLayout->offset = surface->u.legacy.level[level].offset + surface->u.legacy.level[level].slice_size_dw * 4 * layer;

I believe the maximum slice size in bytes is (with an RGBA32 texture)

16384 * 16384 * 16 = 2^14 * 2^14 * 2^4 = 2^32

The problem with this code is that the multiplication is now performed 
as uint32_t and can therefore wrap-around. So an explicit cast to 
64-bits is required.

In practice, I guess this rather becomes an issue with smaller slice 
sizes but larger layer indices. We really need test case to exercise >= 
4 GB textures...

Cheers,
Nicolai


>   		pLayout->rowPitch = surface->u.legacy.level[level].nblk_x * surface->bpe;
> -		pLayout->arrayPitch = surface->u.legacy.level[level].slice_size;
> -		pLayout->depthPitch = surface->u.legacy.level[level].slice_size;
> -		pLayout->size = surface->u.legacy.level[level].slice_size;
> +		pLayout->arrayPitch = surface->u.legacy.level[level].slice_size_dw * 4;
> +		pLayout->depthPitch = surface->u.legacy.level[level].slice_size_dw * 4;
> +		pLayout->size = surface->u.legacy.level[level].slice_size_dw * 4;
>   		if (image->type == VK_IMAGE_TYPE_3D)
>   			pLayout->size *= u_minify(image->info.depth, level);
>   	}
>   }
>   
>   
>   VkResult
>   radv_CreateImageView(VkDevice _device,
>   		     const VkImageViewCreateInfo *pCreateInfo,
>   		     const VkAllocationCallbacks *pAllocator,
> diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c
> index dcbc686..a6edb76 100644
> --- a/src/gallium/drivers/r600/evergreen_state.c
> +++ b/src/gallium/drivers/r600/evergreen_state.c
> @@ -3660,21 +3660,21 @@ static void evergreen_dma_copy_tile(struct r600_context *rctx,
>   		 * dma packet will be using the copy_height which is always smaller or equal
>   		 * to the linear height
>   		 */
>   		height = u_minify(rsrc->resource.b.b.height0, src_level);
>   		detile = 1;
>   		x = src_x;
>   		y = src_y;
>   		z = src_z;
>   		base = rsrc->surface.u.legacy.level[src_level].offset;
>   		addr = rdst->surface.u.legacy.level[dst_level].offset;
> -		addr += rdst->surface.u.legacy.level[dst_level].slice_size * dst_z;
> +		addr += rdst->surface.u.legacy.level[dst_level].slice_size_dw * 4 * dst_z;
>   		addr += dst_y * pitch + dst_x * bpp;
>   		bank_h = eg_bank_wh(rsrc->surface.u.legacy.bankh);
>   		bank_w = eg_bank_wh(rsrc->surface.u.legacy.bankw);
>   		mt_aspect = eg_macro_tile_aspect(rsrc->surface.u.legacy.mtilea);
>   		tile_split = eg_tile_split(rsrc->surface.u.legacy.tile_split);
>   		base += rsrc->resource.gpu_address;
>   		addr += rdst->resource.gpu_address;
>   	} else {
>   		/* L2T */
>   		array_mode = evergreen_array_mode(dst_mode);
> @@ -3685,21 +3685,21 @@ static void evergreen_dma_copy_tile(struct r600_context *rctx,
>   		 * dma packet will be using the copy_height which is always smaller or equal
>   		 * to the linear height
>   		 */
>   		height = u_minify(rdst->resource.b.b.height0, dst_level);
>   		detile = 0;
>   		x = dst_x;
>   		y = dst_y;
>   		z = dst_z;
>   		base = rdst->surface.u.legacy.level[dst_level].offset;
>   		addr = rsrc->surface.u.legacy.level[src_level].offset;
> -		addr += rsrc->surface.u.legacy.level[src_level].slice_size * src_z;
> +		addr += rsrc->surface.u.legacy.level[src_level].slice_size_dw * 4 * src_z;
>   		addr += src_y * pitch + src_x * bpp;
>   		bank_h = eg_bank_wh(rdst->surface.u.legacy.bankh);
>   		bank_w = eg_bank_wh(rdst->surface.u.legacy.bankw);
>   		mt_aspect = eg_macro_tile_aspect(rdst->surface.u.legacy.mtilea);
>   		tile_split = eg_tile_split(rdst->surface.u.legacy.tile_split);
>   		base += rdst->resource.gpu_address;
>   		addr += rsrc->resource.gpu_address;
>   	}
>   
>   	size = (copy_height * pitch) / 4;
> @@ -3802,24 +3802,24 @@ static void evergreen_dma_copy(struct pipe_context *ctx,
>   	}
>   
>   	if (src_mode == dst_mode) {
>   		uint64_t dst_offset, src_offset;
>   		/* simple dma blit would do NOTE code here assume :
>   		 *   src_box.x/y == 0
>   		 *   dst_x/y == 0
>   		 *   dst_pitch == src_pitch
>   		 */
>   		src_offset= rsrc->surface.u.legacy.level[src_level].offset;
> -		src_offset += rsrc->surface.u.legacy.level[src_level].slice_size * src_box->z;
> +		src_offset += rsrc->surface.u.legacy.level[src_level].slice_size_dw * 4 * src_box->z;
>   		src_offset += src_y * src_pitch + src_x * bpp;
>   		dst_offset = rdst->surface.u.legacy.level[dst_level].offset;
> -		dst_offset += rdst->surface.u.legacy.level[dst_level].slice_size * dst_z;
> +		dst_offset += rdst->surface.u.legacy.level[dst_level].slice_size_dw * 4 * dst_z;
>   		dst_offset += dst_y * dst_pitch + dst_x * bpp;
>   		evergreen_dma_copy_buffer(rctx, dst, src, dst_offset, src_offset,
>   					src_box->height * src_pitch);
>   	} else {
>   		evergreen_dma_copy_tile(rctx, dst, dst_level, dst_x, dst_y, dst_z,
>   					src, src_level, src_x, src_y, src_box->z,
>   					copy_height, dst_pitch, bpp);
>   	}
>   	return;
>   
> diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c
> index 3102905..c90800b 100644
> --- a/src/gallium/drivers/r600/r600_state.c
> +++ b/src/gallium/drivers/r600/r600_state.c
> @@ -2874,40 +2874,40 @@ static boolean r600_dma_copy_tile(struct r600_context *rctx,
>   		 * dma packet will be using the copy_height which is always smaller or equal
>   		 * to the linear height
>   		 */
>   		height = u_minify(rsrc->resource.b.b.height0, src_level);
>   		detile = 1;
>   		x = src_x;
>   		y = src_y;
>   		z = src_z;
>   		base = rsrc->surface.u.legacy.level[src_level].offset;
>   		addr = rdst->surface.u.legacy.level[dst_level].offset;
> -		addr += rdst->surface.u.legacy.level[dst_level].slice_size * dst_z;
> +		addr += rdst->surface.u.legacy.level[dst_level].slice_size_dw * 4 * dst_z;
>   		addr += dst_y * pitch + dst_x * bpp;
>   	} else {
>   		/* L2T */
>   		array_mode = r600_array_mode(dst_mode);
>   		slice_tile_max = (rdst->surface.u.legacy.level[dst_level].nblk_x * rdst->surface.u.legacy.level[dst_level].nblk_y) / (8*8);
>   		slice_tile_max = slice_tile_max ? slice_tile_max - 1 : 0;
>   		/* linear height must be the same as the slice tile max height, it's ok even
>   		 * if the linear destination/source have smaller heigh as the size of the
>   		 * dma packet will be using the copy_height which is always smaller or equal
>   		 * to the linear height
>   		 */
>   		height = u_minify(rdst->resource.b.b.height0, dst_level);
>   		detile = 0;
>   		x = dst_x;
>   		y = dst_y;
>   		z = dst_z;
>   		base = rdst->surface.u.legacy.level[dst_level].offset;
>   		addr = rsrc->surface.u.legacy.level[src_level].offset;
> -		addr += rsrc->surface.u.legacy.level[src_level].slice_size * src_z;
> +		addr += rsrc->surface.u.legacy.level[src_level].slice_size_dw * 4 * src_z;
>   		addr += src_y * pitch + src_x * bpp;
>   	}
>   	/* check that we are in dw/base alignment constraint */
>   	if (addr % 4 || base % 256) {
>   		return FALSE;
>   	}
>   
>   	/* It's a r6xx/r7xx limitation, the blit must be on 8 boundary for number
>   	 * line in the blit. Compute max 8 line we can copy in the size limit
>   	 */
> @@ -2998,24 +2998,24 @@ static void r600_dma_copy(struct pipe_context *ctx,
>   
>   	if (src_mode == dst_mode) {
>   		uint64_t dst_offset, src_offset, size;
>   
>   		/* simple dma blit would do NOTE code here assume :
>   		 *   src_box.x/y == 0
>   		 *   dst_x/y == 0
>   		 *   dst_pitch == src_pitch
>   		 */
>   		src_offset= rsrc->surface.u.legacy.level[src_level].offset;
> -		src_offset += rsrc->surface.u.legacy.level[src_level].slice_size * src_box->z;
> +		src_offset += rsrc->surface.u.legacy.level[src_level].slice_size_dw * 4 * src_box->z;
>   		src_offset += src_y * src_pitch + src_x * bpp;
>   		dst_offset = rdst->surface.u.legacy.level[dst_level].offset;
> -		dst_offset += rdst->surface.u.legacy.level[dst_level].slice_size * dst_z;
> +		dst_offset += rdst->surface.u.legacy.level[dst_level].slice_size_dw * 4 * dst_z;
>   		dst_offset += dst_y * dst_pitch + dst_x * bpp;
>   		size = src_box->height * src_pitch;
>   		/* must be dw aligned */
>   		if (dst_offset % 4 || src_offset % 4 || size % 4) {
>   			goto fallback;
>   		}
>   		r600_dma_copy_buffer(rctx, dst, src, dst_offset, src_offset, size);
>   	} else {
>   		if (!r600_dma_copy_tile(rctx, dst, dst_level, dst_x, dst_y, dst_z,
>   					src, src_level, src_x, src_y, src_box->z,
> diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c
> index f7c9b63..cc15e53 100644
> --- a/src/gallium/drivers/r600/r600_texture.c
> +++ b/src/gallium/drivers/r600/r600_texture.c
> @@ -171,29 +171,29 @@ static void r600_copy_from_staging_texture(struct pipe_context *ctx, struct r600
>   }
>   
>   static unsigned r600_texture_get_offset(struct r600_common_screen *rscreen,
>   					struct r600_texture *rtex, unsigned level,
>   					const struct pipe_box *box,
>   					unsigned *stride,
>   					unsigned *layer_stride)
>   {
>   	*stride = rtex->surface.u.legacy.level[level].nblk_x *
>   		rtex->surface.bpe;
> -	*layer_stride = rtex->surface.u.legacy.level[level].slice_size;
> +	*layer_stride = 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 * rtex->surface.u.legacy.level[level].slice_size +
> +		box->z * 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,
>   			     struct radeon_surf *surface,
>   			     const struct pipe_resource *ptex,
>   			     enum radeon_surf_mode array_mode,
>   			     unsigned pitch_in_bytes_override,
> @@ -249,22 +249,22 @@ static int r600_init_surface(struct r600_common_screen *rscreen,
>   	if (r) {
>   		return r;
>   	}
>   
>   	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;
> +		surface->u.legacy.level[0].slice_size_dw =
> +			(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;
>   	}
>   
>   	return 0;
>   }
>   
> @@ -495,21 +495,21 @@ static boolean r600_texture_get_handle(struct pipe_screen* screen,
>   			if (rscreen->query_opaque_metadata)
>   				rscreen->query_opaque_metadata(rscreen, rtex,
>   							       &metadata);
>   
>   			rscreen->ws->buffer_set_metadata(res->buf, &metadata);
>   		}
>   
>   		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 = 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)) {
>   			assert(!res->b.is_shared);
>   
>   			/* Allocate a new buffer with PIPE_BIND_SHARED. */
>   			struct pipe_resource templ = res->b.b;
>   			templ.bind |= PIPE_BIND_SHARED;
>   
>   			struct pipe_resource *newb =
> @@ -840,39 +840,39 @@ void r600_print_texture_info(struct r600_common_screen *rscreen,
>   		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),
>   			rtex->surface.u.legacy.level[i].nblk_x,
>   			rtex->surface.u.legacy.level[i].nblk_y,
>   			rtex->surface.u.legacy.level[i].mode,
>   			rtex->surface.u.legacy.tiling_index[i]);
>   
>   	if (rtex->surface.has_stencil) {
>   		u_log_printf(log, "  StencilLayout: tilesplit=%u\n",
>   			rtex->surface.u.legacy.stencil_tile_split);
>   		for (i = 0; i <= rtex->resource.b.b.last_level; i++) {
>   			u_log_printf(log, "  StencilLevel[%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.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),
>   				rtex->surface.u.legacy.stencil_level[i].nblk_x,
>   				rtex->surface.u.legacy.stencil_level[i].nblk_y,
>   				rtex->surface.u.legacy.stencil_level[i].mode,
>   				rtex->surface.u.legacy.stencil_tiling_index[i]);
>   		}
>   	}
>   }
> diff --git a/src/gallium/drivers/r600/radeon_uvd.c b/src/gallium/drivers/r600/radeon_uvd.c
> index b0551d7..5083ef0 100644
> --- a/src/gallium/drivers/r600/radeon_uvd.c
> +++ b/src/gallium/drivers/r600/radeon_uvd.c
> @@ -1407,21 +1407,21 @@ error:
>   
>   	FREE(dec);
>   
>   	return NULL;
>   }
>   
>   /* calculate top/bottom offset */
>   static unsigned texture_offset(struct radeon_surf *surface, unsigned layer)
>   {
>   	return surface->u.legacy.level[0].offset +
> -		layer * surface->u.legacy.level[0].slice_size;
> +		layer * surface->u.legacy.level[0].slice_size_dw * 4;
>   }
>   
>   /* hw encode the aspect of macro tiles */
>   static unsigned macro_tile_aspect(unsigned macro_tile_aspect)
>   {
>   	switch (macro_tile_aspect) {
>   	default:
>   	case 1: macro_tile_aspect = 0;  break;
>   	case 2: macro_tile_aspect = 1;  break;
>   	case 4: macro_tile_aspect = 2;  break;
> diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c
> index 38d2470..a6f1735 100644
> --- a/src/gallium/drivers/radeon/r600_texture.c
> +++ b/src/gallium/drivers/radeon/r600_texture.c
> @@ -192,29 +192,29 @@ static unsigned r600_texture_get_offset(struct r600_common_screen *rscreen,
>   		/* 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;
> +		*layer_stride = 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 * rtex->surface.u.legacy.level[level].slice_size +
> +		       box->z * 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,
>   			     struct radeon_surf *surface,
>   			     const struct pipe_resource *ptex,
>   			     enum radeon_surf_mode array_mode,
> @@ -296,22 +296,22 @@ static int r600_init_surface(struct r600_common_screen *rscreen,
>   		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;
> +			surface->u.legacy.level[0].slice_size_dw =
> +				(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;
>   		}
>   	}
>   	return 0;
>   }
>   
> @@ -641,21 +641,21 @@ static boolean r600_texture_get_handle(struct pipe_screen* screen,
>   
>   		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 = 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)) {
>   			assert(!res->b.is_shared);
>   
>   			/* Allocate a new buffer with PIPE_BIND_SHARED. */
>   			struct pipe_resource templ = res->b.b;
>   			templ.bind |= PIPE_BIND_SHARED;
>   
> @@ -1069,39 +1069,39 @@ void si_print_texture_info(struct r600_common_screen *rscreen,
>   				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);
>   	}
>   
>   	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),
>   			rtex->surface.u.legacy.level[i].nblk_x,
>   			rtex->surface.u.legacy.level[i].nblk_y,
>   			rtex->surface.u.legacy.level[i].mode,
>   			rtex->surface.u.legacy.tiling_index[i]);
>   
>   	if (rtex->surface.has_stencil) {
>   		u_log_printf(log, "  StencilLayout: tilesplit=%u\n",
>   			rtex->surface.u.legacy.stencil_tile_split);
>   		for (i = 0; i <= rtex->resource.b.b.last_level; i++) {
>   			u_log_printf(log, "  StencilLevel[%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.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),
>   				rtex->surface.u.legacy.stencil_level[i].nblk_x,
>   				rtex->surface.u.legacy.stencil_level[i].nblk_y,
>   				rtex->surface.u.legacy.stencil_level[i].mode,
>   				rtex->surface.u.legacy.stencil_tiling_index[i]);
>   		}
>   	}
>   }
> diff --git a/src/gallium/drivers/radeon/radeon_uvd.c b/src/gallium/drivers/radeon/radeon_uvd.c
> index bf7a2ae..716df4f 100644
> --- a/src/gallium/drivers/radeon/radeon_uvd.c
> +++ b/src/gallium/drivers/radeon/radeon_uvd.c
> @@ -1500,21 +1500,21 @@ error:
>   }
>   
>   /* calculate top/bottom offset */
>   static unsigned texture_offset(struct radeon_surf *surface, unsigned layer,
>   				enum ruvd_surface_type type)
>   {
>   	switch (type) {
>   	default:
>   	case RUVD_SURFACE_TYPE_LEGACY:
>   		return surface->u.legacy.level[0].offset +
> -			layer * surface->u.legacy.level[0].slice_size;
> +			layer * surface->u.legacy.level[0].slice_size_dw * 4;
>   		break;
>   	case RUVD_SURFACE_TYPE_GFX9:
>   		return surface->u.gfx9.surf_offset +
>   			layer * surface->u.gfx9.surf_slice_size;
>   		break;
>   	}
>   }
>   
>   /* hw encode the aspect of macro tiles */
>   static unsigned macro_tile_aspect(unsigned macro_tile_aspect)
> diff --git a/src/gallium/drivers/radeonsi/cik_sdma.c b/src/gallium/drivers/radeonsi/cik_sdma.c
> index 374dfcf..9945923 100644
> --- a/src/gallium/drivers/radeonsi/cik_sdma.c
> +++ b/src/gallium/drivers/radeonsi/cik_sdma.c
> @@ -158,22 +158,22 @@ static bool cik_sdma_copy_texture(struct si_context *sctx,
>   	unsigned dst_tile_mode = info->si_tile_mode_array[dst_tile_index];
>   	unsigned src_tile_mode = info->si_tile_mode_array[src_tile_index];
>   	unsigned dst_micro_mode = G_009910_MICRO_TILE_MODE_NEW(dst_tile_mode);
>   	unsigned src_micro_mode = G_009910_MICRO_TILE_MODE_NEW(src_tile_mode);
>   	unsigned dst_tile_swizzle = dst_mode == RADEON_SURF_MODE_2D ?
>   					    rdst->surface.tile_swizzle : 0;
>   	unsigned src_tile_swizzle = src_mode == RADEON_SURF_MODE_2D ?
>   					    rsrc->surface.tile_swizzle : 0;
>   	unsigned dst_pitch = rdst->surface.u.legacy.level[dst_level].nblk_x;
>   	unsigned src_pitch = rsrc->surface.u.legacy.level[src_level].nblk_x;
> -	uint64_t dst_slice_pitch = rdst->surface.u.legacy.level[dst_level].slice_size / bpp;
> -	uint64_t src_slice_pitch = rsrc->surface.u.legacy.level[src_level].slice_size / bpp;
> +	uint64_t dst_slice_pitch = (rdst->surface.u.legacy.level[dst_level].slice_size_dw * 4) / bpp;
> +	uint64_t src_slice_pitch = (rsrc->surface.u.legacy.level[src_level].slice_size_dw * 4) / bpp;
>   	unsigned dst_width = minify_as_blocks(rdst->resource.b.b.width0,
>   					      dst_level, rdst->surface.blk_w);
>   	unsigned src_width = minify_as_blocks(rsrc->resource.b.b.width0,
>   					      src_level, rsrc->surface.blk_w);
>   	unsigned dst_height = minify_as_blocks(rdst->resource.b.b.height0,
>   					       dst_level, rdst->surface.blk_h);
>   	unsigned src_height = minify_as_blocks(rsrc->resource.b.b.height0,
>   					       src_level, rsrc->surface.blk_h);
>   	unsigned srcx = src_box->x / rsrc->surface.blk_w;
>   	unsigned srcy = src_box->y / rsrc->surface.blk_h;
> diff --git a/src/gallium/drivers/radeonsi/si_dma.c b/src/gallium/drivers/radeonsi/si_dma.c
> index d33ec6b..da8e58c 100644
> --- a/src/gallium/drivers/radeonsi/si_dma.c
> +++ b/src/gallium/drivers/radeonsi/si_dma.c
> @@ -168,21 +168,21 @@ static void si_dma_copy_tile(struct si_context *ctx,
>   	slice_tile_max = (rtiled->surface.u.legacy.level[tiled_lvl].nblk_x *
>   			  rtiled->surface.u.legacy.level[tiled_lvl].nblk_y) / (8*8) - 1;
>   	/* linear height must be the same as the slice tile max height, it's ok even
>   	 * if the linear destination/source have smaller heigh as the size of the
>   	 * dma packet will be using the copy_height which is always smaller or equal
>   	 * to the linear height
>   	 */
>   	height = rtiled->surface.u.legacy.level[tiled_lvl].nblk_y;
>   	base = rtiled->surface.u.legacy.level[tiled_lvl].offset;
>   	addr = rlinear->surface.u.legacy.level[linear_lvl].offset;
> -	addr += rlinear->surface.u.legacy.level[linear_lvl].slice_size * linear_z;
> +	addr += rlinear->surface.u.legacy.level[linear_lvl].slice_size_dw * 4 * linear_z;
>   	addr += linear_y * pitch + linear_x * bpp;
>   	bank_h = G_009910_BANK_HEIGHT(tile_mode);
>   	bank_w = G_009910_BANK_WIDTH(tile_mode);
>   	mt_aspect = G_009910_MACRO_TILE_ASPECT(tile_mode);
>   	/* Non-depth modes don't have TILE_SPLIT set. */
>   	tile_split = util_logbase2(rtiled->surface.u.legacy.tile_split >> 6);
>   	nbanks = G_009910_NUM_BANKS(tile_mode);
>   	base += rtiled->resource.gpu_address;
>   	addr += rlinear->resource.gpu_address;
>   
> @@ -294,27 +294,27 @@ static void si_dma_copy(struct pipe_context *ctx,
>   	}
>   
>   	if (src_mode == dst_mode) {
>   		uint64_t dst_offset, src_offset;
>   		/* simple dma blit would do NOTE code here assume :
>   		 *   src_box.x/y == 0
>   		 *   dst_x/y == 0
>   		 *   dst_pitch == src_pitch
>   		 */
>   		src_offset= rsrc->surface.u.legacy.level[src_level].offset;
> -		src_offset += rsrc->surface.u.legacy.level[src_level].slice_size * src_box->z;
> +		src_offset += rsrc->surface.u.legacy.level[src_level].slice_size_dw * 4 * src_box->z;
>   		src_offset += src_y * src_pitch + src_x * bpp;
>   		dst_offset = rdst->surface.u.legacy.level[dst_level].offset;
> -		dst_offset += rdst->surface.u.legacy.level[dst_level].slice_size * dst_z;
> +		dst_offset += rdst->surface.u.legacy.level[dst_level].slice_size_dw * 4 * dst_z;
>   		dst_offset += dst_y * dst_pitch + dst_x * bpp;
>   		si_dma_copy_buffer(sctx, dst, src, dst_offset, src_offset,
> -				   rsrc->surface.u.legacy.level[src_level].slice_size);
> +				   rsrc->surface.u.legacy.level[src_level].slice_size_dw * 4);
>   	} else {
>   		si_dma_copy_tile(sctx, dst, dst_level, dst_x, dst_y, dst_z,
>   				 src, src_level, src_x, src_y, src_box->z,
>   				 src_box->height / rsrc->surface.blk_h,
>   				 dst_pitch, bpp);
>   	}
>   	return;
>   
>   fallback:
>   	si_resource_copy_region(ctx, dst, dst_level, dstx, dsty, dstz,
> diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_surface.c b/src/gallium/winsys/radeon/drm/radeon_drm_surface.c
> index 43bf7ed..3a0c351 100644
> --- a/src/gallium/winsys/radeon/drm/radeon_drm_surface.c
> +++ b/src/gallium/winsys/radeon/drm/radeon_drm_surface.c
> @@ -61,33 +61,33 @@ static void set_micro_tile_mode(struct radeon_surf *surf,
>           surf->micro_tile_mode = G_009910_MICRO_TILE_MODE_NEW(tile_mode);
>       else
>           surf->micro_tile_mode = G_009910_MICRO_TILE_MODE(tile_mode);
>   }
>   
>   static void surf_level_winsys_to_drm(struct radeon_surface_level *level_drm,
>                                        const struct legacy_surf_level *level_ws,
>                                        unsigned bpe)
>   {
>       level_drm->offset = level_ws->offset;
> -    level_drm->slice_size = level_ws->slice_size;
> +    level_drm->slice_size = level_ws->slice_size_dw * 4;
>       level_drm->nblk_x = level_ws->nblk_x;
>       level_drm->nblk_y = level_ws->nblk_y;
>       level_drm->pitch_bytes = level_ws->nblk_x * bpe;
>       level_drm->mode = level_ws->mode;
>   }
>   
>   static void surf_level_drm_to_winsys(struct legacy_surf_level *level_ws,
>                                        const struct radeon_surface_level *level_drm,
>                                        unsigned bpe)
>   {
>       level_ws->offset = level_drm->offset;
> -    level_ws->slice_size = level_drm->slice_size;
> +    level_ws->slice_size_dw = level_drm->slice_size / 4;
>       level_ws->nblk_x = level_drm->nblk_x;
>       level_ws->nblk_y = level_drm->nblk_y;
>       level_ws->mode = level_drm->mode;
>       assert(level_drm->nblk_x * bpe == level_drm->pitch_bytes);
>   }
>   
>   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,
> 


-- 
Lerne, wie die Welt wirklich ist,
Aber vergiss niemals, wie sie sein sollte.


More information about the mesa-dev mailing list