[Mesa-dev] [PATCH 04/10] radeonsi/gfx9: fix linear mipmap CPU access

Nicolai Hähnle nhaehnle at gmail.com
Fri Mar 31 06:17:23 UTC 2017


On 30.03.2017 19:16, Marek Olšák wrote:
> From: Marek Olšák <marek.olsak at amd.com>
>
> ---
>  src/gallium/drivers/radeon/r600_texture.c      | 8 +++-----
>  src/gallium/drivers/radeon/radeon_winsys.h     | 4 ++--
>  src/gallium/winsys/amdgpu/drm/amdgpu_surface.c | 2 +-
>  3 files changed, 6 insertions(+), 8 deletions(-)
>
> diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c
> index 877f555..77e9bec 100644
> --- a/src/gallium/drivers/radeon/r600_texture.c
> +++ b/src/gallium/drivers/radeon/r600_texture.c
> @@ -186,22 +186,22 @@ static unsigned r600_texture_get_offset(struct r600_common_screen *rscreen,
>  	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.surf_ymip_offset[level] +
> -			 box->y / rtex->surface.blk_h) *
> +		       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;

Does this part of the formula really not depend on the mip level? It 
looks like each mip level uses the same amount of memory and pitch?

Thanks,
Nicolai


>  	} 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;
>
> @@ -1616,23 +1616,21 @@ static void *r600_texture_transfer_map(struct pipe_context *ctx,
>
>  		/* Tiled textures need to be converted into a linear texture for CPU
>  		 * access. The staging texture is always linear and is placed in GART.
>  		 *
>  		 * Reading from VRAM or GTT WC is slow, always use the staging
>  		 * texture in this case.
>  		 *
>  		 * Use the staging texture for uploads if the underlying BO
>  		 * is busy.
>  		 */
> -		/* TODO: Linear CPU mipmap addressing is broken on GFX9: */
> -		if (!rtex->surface.is_linear ||
> -		    (rctx->chip_class == GFX9 && level))
> +		if (!rtex->surface.is_linear)
>  			use_staging_texture = true;
>  		else if (usage & PIPE_TRANSFER_READ)
>  			use_staging_texture =
>  				rtex->resource.domains & RADEON_DOMAIN_VRAM ||
>  				rtex->resource.flags & RADEON_FLAG_GTT_WC;
>  		/* Write & linear only: */
>  		else if (r600_rings_is_buffer_referenced(rctx, rtex->resource.buf,
>  							 RADEON_USAGE_READWRITE) ||
>  			 !rctx->ws->buffer_wait(rtex->resource.buf, 0,
>  						RADEON_USAGE_READWRITE)) {
> diff --git a/src/gallium/drivers/radeon/radeon_winsys.h b/src/gallium/drivers/radeon/radeon_winsys.h
> index 43f74f6..a19ece6 100644
> --- a/src/gallium/drivers/radeon/radeon_winsys.h
> +++ b/src/gallium/drivers/radeon/radeon_winsys.h
> @@ -357,22 +357,22 @@ struct gfx9_surf_layout {
>      struct gfx9_surf_meta_flags dcc;   /* metadata of color */
>      struct gfx9_surf_meta_flags htile; /* metadata of depth and stencil */
>      struct gfx9_surf_meta_flags cmask; /* metadata of fmask */
>
>      enum gfx9_resource_type     resource_type; /* 1D, 2D or 3D */
>      uint64_t                    surf_offset; /* 0 unless imported with an offset */
>      /* The size of the 2D plane containing all mipmap levels. */
>      uint64_t                    surf_slice_size;
>      uint16_t                    surf_pitch; /* in blocks */
>      uint16_t                    surf_height;
> -    /* Y mipmap level offset in blocks. Only valid for LINEAR. */
> -    uint16_t                    surf_ymip_offset[RADEON_SURF_MAX_LEVELS];
> +    /* Mipmap level offset within the slice in bytes. Only valid for LINEAR. */
> +    uint32_t                    offset[RADEON_SURF_MAX_LEVELS];
>
>      uint16_t                    dcc_pitch_max;  /* (mip chain pitch - 1) */
>
>      uint64_t                    stencil_offset; /* separate stencil */
>      uint64_t                    fmask_size;
>      uint64_t                    cmask_size;
>
>      uint32_t                    fmask_alignment;
>      uint32_t                    cmask_alignment;
>  };
> diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c b/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c
> index 7dfd6d2..7566087 100644
> --- a/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c
> +++ b/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c
> @@ -656,21 +656,21 @@ static int gfx9_compute_miptree(struct amdgpu_winsys *ws,
>     surf->u.gfx9.surf.epitch = out.epitchIsHeight ? out.mipChainHeight - 1 :
>                                                     out.mipChainPitch - 1;
>     surf->u.gfx9.surf_slice_size = out.sliceSize;
>     surf->u.gfx9.surf_pitch = out.pitch;
>     surf->u.gfx9.surf_height = out.height;
>     surf->surf_size = out.surfSize;
>     surf->surf_alignment = out.baseAlign;
>
>     if (in->swizzleMode == ADDR_SW_LINEAR) {
>        for (unsigned i = 0; i < in->numMipLevels; i++)
> -         surf->u.gfx9.surf_ymip_offset[i] = mip_info[i].mipOffsetYPixel;
> +         surf->u.gfx9.offset[i] = mip_info[i].offset;
>     }
>
>     if (in->flags.depth) {
>        assert(in->swizzleMode != ADDR_SW_LINEAR);
>
>        /* HTILE */
>        ADDR2_COMPUTE_HTILE_INFO_INPUT hin = {0};
>        ADDR2_COMPUTE_HTILE_INFO_OUTPUT hout = {0};
>
>        hin.size = sizeof(ADDR2_COMPUTE_HTILE_INFO_INPUT);
>


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


More information about the mesa-dev mailing list