[Mesa-dev] [PATCH 06/10] gallium/radeon: add radeon_surf::is_linear

Marek Olšák maraeo at gmail.com
Sat Oct 29 11:17:21 UTC 2016


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

---
 src/gallium/drivers/radeon/r600_buffer_common.c    | 2 +-
 src/gallium/drivers/radeon/r600_test_dma.c         | 8 ++++----
 src/gallium/drivers/radeon/r600_texture.c          | 8 ++++----
 src/gallium/drivers/radeon/radeon_winsys.h         | 1 +
 src/gallium/drivers/radeonsi/si_blit.c             | 5 ++---
 src/gallium/drivers/radeonsi/si_state.c            | 2 +-
 src/gallium/winsys/amdgpu/drm/amdgpu_surface.c     | 1 +
 src/gallium/winsys/radeon/drm/radeon_drm_surface.c | 1 +
 8 files changed, 15 insertions(+), 13 deletions(-)

diff --git a/src/gallium/drivers/radeon/r600_buffer_common.c b/src/gallium/drivers/radeon/r600_buffer_common.c
index 74bec26..c6f4d0d 100644
--- a/src/gallium/drivers/radeon/r600_buffer_common.c
+++ b/src/gallium/drivers/radeon/r600_buffer_common.c
@@ -153,21 +153,21 @@ void r600_init_resource_fields(struct r600_common_screen *rscreen,
 		 */
 		if (rscreen->info.drm_major == 2 &&
 		    rscreen->info.drm_minor < 40)
 			res->domains = RADEON_DOMAIN_GTT;
 		else if (res->domains & RADEON_DOMAIN_VRAM)
 			res->flags |= RADEON_FLAG_CPU_ACCESS;
 	}
 
 	/* Tiled textures are unmappable. Always put them in VRAM. */
 	if (res->b.b.target != PIPE_BUFFER &&
-	    rtex->surface.level[0].mode >= RADEON_SURF_MODE_1D) {
+	    !rtex->surface.is_linear) {
 		res->domains = RADEON_DOMAIN_VRAM;
 		res->flags &= ~RADEON_FLAG_CPU_ACCESS;
 		res->flags |= RADEON_FLAG_NO_CPU_ACCESS |
 			 RADEON_FLAG_GTT_WC;
 	}
 
 	/* If VRAM is just stolen system memory, allow both VRAM and
 	 * GTT, whichever has free space. If a buffer is evicted from
 	 * VRAM to GTT, it will stay there.
 	 */
diff --git a/src/gallium/drivers/radeon/r600_test_dma.c b/src/gallium/drivers/radeon/r600_test_dma.c
index 7f4a8c0..f7e9eb5 100644
--- a/src/gallium/drivers/radeon/r600_test_dma.c
+++ b/src/gallium/drivers/radeon/r600_test_dma.c
@@ -324,22 +324,22 @@ void r600_test_dma(struct r600_common_screen *rscreen)
 				depth = max_depth;
 
 				srcx = srcy = srcz = dstx = dsty = dstz = 0;
 			} else {
 				/* random sub-rectangle copies from src to dst */
 				depth = (rand() % max_depth) + 1;
 				srcz = rand() % (tsrc.array_size - depth + 1);
 				dstz = rand() % (tdst.array_size - depth + 1);
 
 				/* special code path to hit the tiled partial copies */
-				if (rsrc->surface.level[0].mode >= RADEON_SURF_MODE_1D &&
-				    rdst->surface.level[0].mode >= RADEON_SURF_MODE_1D &&
+				if (!rsrc->surface.is_linear &&
+				    !rdst->surface.is_linear &&
 				    rand() & 1) {
 					if (max_width < 8 || max_height < 8)
 						continue;
 					width = ((rand() % (max_width / 8)) + 1) * 8;
 					height = ((rand() % (max_height / 8)) + 1) * 8;
 
 					srcx = rand() % (tsrc.width0 - width + 1) & ~0x7;
 					srcy = rand() % (tsrc.height0 - height + 1) & ~0x7;
 
 					dstx = rand() % (tdst.width0 - width + 1) & ~0x7;
@@ -352,22 +352,22 @@ void r600_test_dma(struct r600_common_screen *rscreen)
 					height = (rand() % max_height) + 1;
 
 					srcx = rand() % (tsrc.width0 - width + 1);
 					srcy = rand() % (tsrc.height0 - height + 1);
 
 					dstx = rand() % (tdst.width0 - width + 1);
 					dsty = rand() % (tdst.height0 - height + 1);
 				}
 
 				/* special code path to hit out-of-bounds reads in L2T */
-				if (rsrc->surface.level[0].mode == RADEON_SURF_MODE_LINEAR_ALIGNED &&
-				    rdst->surface.level[0].mode >= RADEON_SURF_MODE_1D &&
+				if (rsrc->surface.is_linear &&
+				    !rdst->surface.is_linear &&
 				    rand() % 4 == 0) {
 					srcx = 0;
 					srcy = 0;
 					srcz = 0;
 				}
 			}
 
 			/* GPU copy */
 			u_box_3d(srcx, srcy, srcz, width, height, depth, &box);
 			rctx->dma_copy(ctx, dst, 0, dstx, dsty, dstz, src, 0, &box);
diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c
index 065d075..ff45261 100644
--- a/src/gallium/drivers/radeon/r600_texture.c
+++ b/src/gallium/drivers/radeon/r600_texture.c
@@ -418,21 +418,21 @@ static void r600_degrade_tile_mode_to_linear(struct r600_common_context *rctx,
 	struct pipe_resource templ = rtex->resource.b.b;
 	unsigned i;
 
 	templ.bind |= PIPE_BIND_LINEAR;
 
 	/* r600g doesn't react to dirty_tex_descriptor_counter */
 	if (rctx->chip_class < SI)
 		return;
 
 	if (rtex->resource.is_shared ||
-	    rtex->surface.level[0].mode == RADEON_SURF_MODE_LINEAR_ALIGNED)
+	    rtex->surface.is_linear)
 		return;
 
 	/* This fails with MSAA, depth, and compressed textures. */
 	if (r600_choose_tiling(rctx->screen, &templ) !=
 	    RADEON_SURF_MODE_LINEAR_ALIGNED)
 		return;
 
 	new_tex = (struct r600_texture*)screen->resource_create(screen, &templ);
 	if (!new_tex)
 		return;
@@ -1399,21 +1399,21 @@ static bool r600_can_invalidate_texture(struct r600_common_screen *rscreen,
 						 box->depth);
 }
 
 static void r600_texture_invalidate_storage(struct r600_common_context *rctx,
 					    struct r600_texture *rtex)
 {
 	struct r600_common_screen *rscreen = rctx->screen;
 
 	/* There is no point in discarding depth and tiled buffers. */
 	assert(!rtex->is_depth);
-	assert(rtex->surface.level[0].mode == RADEON_SURF_MODE_LINEAR_ALIGNED);
+	assert(rtex->surface.is_linear);
 
 	/* Reallocate the buffer in the same pipe_resource. */
 	r600_alloc_resource(rscreen, &rtex->resource);
 
 	/* Initialize the CMASK base address (needed even without CMASK). */
 	rtex->cmask.base_address_reg =
 		(rtex->resource.gpu_address + rtex->cmask.offset) >> 8;
 
 	r600_dirty_all_framebuffer_states(rscreen);
 	p_atomic_inc(&rscreen->dirty_tex_descriptor_counter);
@@ -1458,21 +1458,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 is slow, always use the staging texture in
 		 * this case.
 		 *
 		 * Use the staging texture for uploads if the underlying BO
 		 * is busy.
 		 */
-		if (rtex->surface.level[0].mode >= RADEON_SURF_MODE_1D)
+		if (!rtex->surface.is_linear)
 			use_staging_texture = true;
 		else if (usage & PIPE_TRANSFER_READ)
 			use_staging_texture = (rtex->resource.domains &
 					       RADEON_DOMAIN_VRAM) != 0;
 		/* 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)) {
 			/* It's busy. */
@@ -2439,21 +2439,21 @@ void evergreen_do_fast_color_clear(struct r600_common_context *rctx,
 		    fb->cbufs[i]->u.tex.last_layer != util_max_layer(&tex->resource.b.b, 0)) {
 			continue;
 		}
 
 		/* cannot clear mipmapped textures */
 		if (fb->cbufs[i]->texture->last_level != 0) {
 			continue;
 		}
 
 		/* only supported on tiled surfaces */
-		if (tex->surface.level[0].mode < RADEON_SURF_MODE_1D) {
+		if (tex->surface.is_linear) {
 			continue;
 		}
 
 		/* shared textures can't use fast clear without an explicit flush,
 		 * because there is no way to communicate the clear color among
 		 * all clients
 		 */
 		if (tex->resource.is_shared &&
 		    !(tex->resource.external_usage & PIPE_HANDLE_USAGE_EXPLICIT_FLUSH))
 			continue;
diff --git a/src/gallium/drivers/radeon/radeon_winsys.h b/src/gallium/drivers/radeon/radeon_winsys.h
index 1e7035f..f65f669 100644
--- a/src/gallium/drivers/radeon/radeon_winsys.h
+++ b/src/gallium/drivers/radeon/radeon_winsys.h
@@ -287,20 +287,21 @@ struct radeon_surf_level {
 struct radeon_surf {
     /* Format properties. */
     unsigned                    blk_w:4;
     unsigned                    blk_h:4;
     unsigned                    bpe:5;
     /* Number of mipmap levels where DCC is enabled starting from level 0.
      * Non-zero levels may be disabled due to alignment constraints, but not
      * the first level.
      */
     unsigned                    num_dcc_levels:4;
+    unsigned                    is_linear:1;
     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                    surf_size;
     uint64_t                    dcc_size;
     uint64_t                    htile_size;
 
diff --git a/src/gallium/drivers/radeonsi/si_blit.c b/src/gallium/drivers/radeonsi/si_blit.c
index fe17f73..0fd1106 100644
--- a/src/gallium/drivers/radeonsi/si_blit.c
+++ b/src/gallium/drivers/radeonsi/si_blit.c
@@ -1005,21 +1005,21 @@ static bool do_hardware_msaa_resolve(struct pipe_context *ctx,
 	    info->dst.box.x == 0 &&
 	    info->dst.box.y == 0 &&
 	    info->dst.box.width == dst_width &&
 	    info->dst.box.height == dst_height &&
 	    info->dst.box.depth == 1 &&
 	    info->src.box.x == 0 &&
 	    info->src.box.y == 0 &&
 	    info->src.box.width == dst_width &&
 	    info->src.box.height == dst_height &&
 	    info->src.box.depth == 1 &&
-	    dst->surface.level[info->dst.level].mode >= RADEON_SURF_MODE_1D &&
+	    !dst->surface.is_linear &&
 	    (!dst->cmask.size || !dst->dirty_level_mask)) { /* dst cannot be fast-cleared */
 		/* Check the last constraint. */
 		if (src->surface.micro_tile_mode != dst->surface.micro_tile_mode) {
 			/* The next fast clear will switch to this mode to
 			 * get direct hw resolve next time if the mode is
 			 * different now.
 			 */
 			src->last_msaa_resolve_target_micro_mode =
 				dst->surface.micro_tile_mode;
 			goto resolve_to_temp;
@@ -1109,22 +1109,21 @@ static void si_blit(struct pipe_context *ctx,
 	if (do_hardware_msaa_resolve(ctx, info)) {
 		return;
 	}
 
 	/* Using SDMA for copying to a linear texture in GTT is much faster.
 	 * This improves DRI PRIME performance.
 	 *
 	 * resource_copy_region can't do this yet, because dma_copy calls it
 	 * on failure (recursion).
 	 */
-	if (rdst->surface.level[info->dst.level].mode ==
-	    RADEON_SURF_MODE_LINEAR_ALIGNED &&
+	if (rdst->surface.is_linear &&
 	    sctx->b.dma_copy &&
 	    util_can_blit_via_copy_region(info, false)) {
 		sctx->b.dma_copy(ctx, info->dst.resource, info->dst.level,
 				 info->dst.box.x, info->dst.box.y,
 				 info->dst.box.z,
 				 info->src.resource, info->src.level,
 				 &info->src.box);
 		return;
 	}
 
diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
index bf89d8b..ab3397c 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -2353,21 +2353,21 @@ static void si_set_framebuffer_state(struct pipe_context *ctx,
 		sctx->framebuffer.spi_shader_col_format_blend_alpha |=
 			surf->spi_shader_col_format_blend_alpha << (i * 4);
 
 		if (surf->color_is_int8)
 			sctx->framebuffer.color_is_int8 |= 1 << i;
 
 		if (rtex->fmask.size) {
 			sctx->framebuffer.compressed_cb_mask |= 1 << i;
 		}
 
-		if (surf->level_info->mode == RADEON_SURF_MODE_LINEAR_ALIGNED)
+		if (rtex->surface.is_linear)
 			sctx->framebuffer.any_dst_linear = true;
 
 		r600_context_add_resource_size(ctx, surf->base.texture);
 
 		p_atomic_inc(&rtex->framebuffers_bound);
 
 		if (rtex->dcc_gather_statistics) {
 			/* Dirty tracking must be enabled for DCC usage analysis. */
 			sctx->framebuffer.compressed_cb_mask |= 1 << i;
 			vi_separate_dcc_start_query(ctx, rtex);
diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c b/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c
index deae4dd..d65dae7 100644
--- a/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c
+++ b/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c
@@ -559,17 +559,18 @@ static int amdgpu_surface_init(struct radeon_winsys *rws,
                                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 && tex->last_level)
 	   surf->htile_size *= 2;
 
+   surf->is_linear = surf->level[0].mode == RADEON_SURF_MODE_LINEAR_ALIGNED;
    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 95ec0eb..c6fa475 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_surface.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_surface.c
@@ -171,20 +171,21 @@ 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->blk_w = surf_drm->blk_w;
     surf_ws->blk_h = surf_drm->blk_h;
     surf_ws->bpe = surf_drm->bpe;
+    surf_ws->is_linear = surf_drm->level[0].mode <= RADEON_SURF_MODE_LINEAR_ALIGNED;
     surf_ws->flags = surf_drm->flags;
 
     surf_ws->surf_size = surf_drm->bo_size;
     surf_ws->surf_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;
-- 
2.7.4



More information about the mesa-dev mailing list