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

Marek Olšák maraeo at gmail.com
Thu Mar 30 17:16:01 UTC 2017


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;
 	} 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);
-- 
2.7.4



More information about the mesa-dev mailing list