[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