[Mesa-dev] [PATCH 04/30] r600: refactor out CB setup.

Dave Airlie airlied at gmail.com
Thu Mar 31 07:03:33 UTC 2016


From: Dave Airlie <airlied at redhat.com>

This moves the code to create CB info out into
a separate function so it can be reused in images
code to create RATs.

Signed-off-by: Dave Airlie <airlied at redhat.com>
---
 src/gallium/drivers/r600/evergreen_state.c | 257 +++++++++++++++++------------
 1 file changed, 147 insertions(+), 110 deletions(-)

diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c
index 356e708..c151a1b 100644
--- a/src/gallium/drivers/r600/evergreen_state.c
+++ b/src/gallium/drivers/r600/evergreen_state.c
@@ -1042,105 +1042,72 @@ static void evergreen_emit_scissor_state(struct r600_context *rctx, struct r600_
 	rstate->atom.num_dw = 0;
 }
 
-/**
- * This function intializes the CB* register values for RATs.  It is meant
- * to be used for 1D aligned buffers that do not have an associated
- * radeon_surf.
- */
-void evergreen_init_color_surface_rat(struct r600_context *rctx,
-					struct r600_surface *surf)
-{
-	struct pipe_resource *pipe_buffer = surf->base.texture;
-	unsigned format = r600_translate_colorformat(rctx->b.chip_class,
-						     surf->base.format);
-	unsigned endian = r600_colorformat_endian_swap(format);
-	unsigned swap = r600_translate_colorswap(surf->base.format);
-	unsigned block_size =
-		align(util_format_get_blocksize(pipe_buffer->format), 4);
-	unsigned pitch_alignment =
-		MAX2(64, rctx->screen->b.info.pipe_interleave_bytes / block_size);
-	unsigned pitch = align(pipe_buffer->width0, pitch_alignment);
-
-	surf->cb_color_base = r600_resource(pipe_buffer)->gpu_address >> 8;
-
-	surf->cb_color_pitch = (pitch / 8) - 1;
-
-	surf->cb_color_slice = 0;
-
-	surf->cb_color_view = 0;
-
-	surf->cb_color_info =
-		  S_028C70_ENDIAN(endian)
-		| S_028C70_FORMAT(format)
-		| S_028C70_ARRAY_MODE(V_028C70_ARRAY_LINEAR_ALIGNED)
-		| S_028C70_NUMBER_TYPE(V_028C70_NUMBER_UINT)
-		| S_028C70_COMP_SWAP(swap)
-		| S_028C70_BLEND_BYPASS(1) /* We must set this bit because we
-					    * are using NUMBER_UINT */
-		| S_028C70_RAT(1)
-		;
-
-	surf->cb_color_attrib = S_028C74_NON_DISP_TILING_ORDER(1);
-
-	/* For buffers, CB_COLOR0_DIM needs to be set to the number of
-	 * elements. */
-	surf->cb_color_dim = pipe_buffer->width0;
-
-	/* Set the buffer range the GPU will have access to: */
-	util_range_add(&r600_resource(pipe_buffer)->valid_buffer_range,
-		       0, pipe_buffer->width0);
-
-	surf->cb_color_fmask = surf->cb_color_base;
-	surf->cb_color_fmask_slice = 0;
-}
+struct r600_tex_color_info {
+	unsigned info;
+	unsigned view;
+	unsigned dim;
+	unsigned pitch;
+	unsigned slice;
+	unsigned attrib;
+	unsigned ntype;
+	unsigned fmask;
+	unsigned fmask_slice;
+	uint64_t offset;
+	boolean export_16bpc;
+};
 
-void evergreen_init_color_surface(struct r600_context *rctx,
-				  struct r600_surface *surf)
+static void evergreen_set_color_surface_common(struct r600_context *rctx,
+					       struct r600_texture *rtex,
+					       unsigned level,
+					       unsigned first_layer,
+					       unsigned last_layer,
+					       enum pipe_format pformat,
+					       struct r600_tex_color_info *color)
 {
 	struct r600_screen *rscreen = rctx->screen;
-	struct r600_texture *rtex = (struct r600_texture*)surf->base.texture;
-	unsigned level = surf->base.u.tex.level;
 	unsigned pitch, slice;
-	unsigned color_info, color_attrib, color_dim = 0, color_view;
-	unsigned format, swap, ntype, endian;
-	uint64_t offset, base_offset;
 	unsigned non_disp_tiling, macro_aspect, tile_split, bankh, bankw, fmask_bankh, nbanks;
+	unsigned format, swap, ntype, endian;
 	const struct util_format_description *desc;
-	int i;
 	bool blend_clamp = 0, blend_bypass = 0;
+	int i;
 
-	offset = rtex->surface.level[level].offset;
+	color->offset = rtex->surface.level[level].offset;
 	if (rtex->surface.level[level].mode == RADEON_SURF_MODE_LINEAR) {
-		assert(surf->base.u.tex.first_layer == surf->base.u.tex.last_layer);
-		offset += rtex->surface.level[level].slice_size *
-			  surf->base.u.tex.first_layer;
-		color_view = 0;
+		color->offset += (rtex->surface.level[level].slice_size *
+				  first_layer);
+		color->view = 0;
 	} else
-		color_view = S_028C6C_SLICE_START(surf->base.u.tex.first_layer) |
-			     S_028C6C_SLICE_MAX(surf->base.u.tex.last_layer);
+		color->view = S_028C6C_SLICE_START(first_layer) |
+			S_028C6C_SLICE_MAX(last_layer);
 
+	color->offset += rtex->resource.gpu_address;
+	color->offset >>= 8;
+
+	color->dim = 0;
 	pitch = (rtex->surface.level[level].nblk_x) / 8 - 1;
 	slice = (rtex->surface.level[level].nblk_x * rtex->surface.level[level].nblk_y) / 64;
 	if (slice) {
 		slice = slice - 1;
 	}
-	color_info = 0;
+
+	color->info = 0;
 	switch (rtex->surface.level[level].mode) {
 	case RADEON_SURF_MODE_LINEAR_ALIGNED:
-		color_info = S_028C70_ARRAY_MODE(V_028C70_ARRAY_LINEAR_ALIGNED);
+		color->info = S_028C70_ARRAY_MODE(V_028C70_ARRAY_LINEAR_ALIGNED);
 		non_disp_tiling = 1;
 		break;
 	case RADEON_SURF_MODE_1D:
-		color_info = S_028C70_ARRAY_MODE(V_028C70_ARRAY_1D_TILED_THIN1);
+		color->info = S_028C70_ARRAY_MODE(V_028C70_ARRAY_1D_TILED_THIN1);
 		non_disp_tiling = rtex->non_disp_tiling;
 		break;
 	case RADEON_SURF_MODE_2D:
-		color_info = S_028C70_ARRAY_MODE(V_028C70_ARRAY_2D_TILED_THIN1);
+		color->info = S_028C70_ARRAY_MODE(V_028C70_ARRAY_2D_TILED_THIN1);
 		non_disp_tiling = rtex->non_disp_tiling;
 		break;
 	case RADEON_SURF_MODE_LINEAR:
 	default:
-		color_info = S_028C70_ARRAY_MODE(V_028C70_ARRAY_LINEAR_GENERAL);
+		color->info = S_028C70_ARRAY_MODE(V_028C70_ARRAY_LINEAR_GENERAL);
 		non_disp_tiling = 1;
 		break;
 	}
@@ -1158,34 +1125,32 @@ void evergreen_init_color_surface(struct r600_context *rctx,
 	bankh = eg_bank_wh(bankh);
 	fmask_bankh = eg_bank_wh(fmask_bankh);
 
-	/* 128 bit formats require tile type = 1 */
 	if (rscreen->b.chip_class == CAYMAN) {
-		if (util_format_get_blocksize(surf->base.format) >= 16)
+		if (util_format_get_blocksize(pformat) >= 16)
 			non_disp_tiling = 1;
 	}
 	nbanks = eg_num_banks(rscreen->b.info.r600_num_banks);
-	desc = util_format_description(surf->base.format);
+	desc = util_format_description(pformat);
 	for (i = 0; i < 4; i++) {
 		if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) {
 			break;
 		}
 	}
-
-	color_attrib = S_028C74_TILE_SPLIT(tile_split)|
-			S_028C74_NUM_BANKS(nbanks) |
-			S_028C74_BANK_WIDTH(bankw) |
-			S_028C74_BANK_HEIGHT(bankh) |
-			S_028C74_MACRO_TILE_ASPECT(macro_aspect) |
-			S_028C74_NON_DISP_TILING_ORDER(non_disp_tiling) |
-		        S_028C74_FMASK_BANK_HEIGHT(fmask_bankh);
+	color->attrib = S_028C74_TILE_SPLIT(tile_split)|
+		S_028C74_NUM_BANKS(nbanks) |
+		S_028C74_BANK_WIDTH(bankw) |
+		S_028C74_BANK_HEIGHT(bankh) |
+		S_028C74_MACRO_TILE_ASPECT(macro_aspect) |
+		S_028C74_NON_DISP_TILING_ORDER(non_disp_tiling) |
+		S_028C74_FMASK_BANK_HEIGHT(fmask_bankh);
 
 	if (rctx->b.chip_class == CAYMAN) {
-		color_attrib |=	S_028C74_FORCE_DST_ALPHA_1(desc->swizzle[3] ==
+		color->attrib |= S_028C74_FORCE_DST_ALPHA_1(desc->swizzle[3] ==
 							   UTIL_FORMAT_SWIZZLE_1);
 
 		if (rtex->resource.b.b.nr_samples > 1) {
 			unsigned log_samples = util_logbase2(rtex->resource.b.b.nr_samples);
-			color_attrib |= S_028C74_NUM_SAMPLES(log_samples) |
+			color->attrib |= S_028C74_NUM_SAMPLES(log_samples) |
 					S_028C74_NUM_FRAGMENTS(log_samples);
 		}
 	}
@@ -1205,11 +1170,8 @@ void evergreen_init_color_surface(struct r600_context *rctx,
 			ntype = V_028C70_NUMBER_UINT;
 	}
 
-	format = r600_translate_colorformat(rctx->b.chip_class, surf->base.format);
-	assert(format != ~0);
-
-	swap = r600_translate_colorswap(surf->base.format);
-	assert(swap != ~0);
+	format = r600_translate_colorformat(rctx->b.chip_class, pformat);
+	swap = r600_translate_colorswap(pformat);
 
 	endian = r600_colorformat_endian_swap(format);
 
@@ -1227,52 +1189,127 @@ void evergreen_init_color_surface(struct r600_context *rctx,
 		blend_bypass = 1;
 	}
 
-	surf->alphatest_bypass = ntype == V_028C70_NUMBER_UINT || ntype == V_028C70_NUMBER_SINT;
-
-	color_info |= S_028C70_FORMAT(format) |
+	color->ntype = ntype;
+	color->info |= S_028C70_FORMAT(format) |
 		S_028C70_COMP_SWAP(swap) |
 		S_028C70_BLEND_CLAMP(blend_clamp) |
 		S_028C70_BLEND_BYPASS(blend_bypass) |
 		S_028C70_NUMBER_TYPE(ntype) |
 		S_028C70_ENDIAN(endian);
 
+	if (rtex->fmask.size) {
+		color->info |= S_028C70_COMPRESSION(1);
+	}
+
 	/* EXPORT_NORM is an optimzation that can be enabled for better
 	 * performance in certain cases.
 	 * EXPORT_NORM can be enabled if:
 	 * - 11-bit or smaller UNORM/SNORM/SRGB
 	 * - 16-bit or smaller FLOAT
 	 */
+	color->export_16bpc = false;
 	if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS &&
 	    ((desc->channel[i].size < 12 &&
 	      desc->channel[i].type != UTIL_FORMAT_TYPE_FLOAT &&
 	      ntype != V_028C70_NUMBER_UINT && ntype != V_028C70_NUMBER_SINT) ||
 	     (desc->channel[i].size < 17 &&
 	      desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT))) {
-		color_info |= S_028C70_SOURCE_FORMAT(V_028C70_EXPORT_4C_16BPC);
-		surf->export_16bpc = true;
+		color->info |= S_028C70_SOURCE_FORMAT(V_028C70_EXPORT_4C_16BPC);
+		color->export_16bpc = true;
 	}
 
+	color->pitch = S_028C64_PITCH_TILE_MAX(pitch);
+	color->slice = S_028C68_SLICE_TILE_MAX(slice);
+
 	if (rtex->fmask.size) {
-		color_info |= S_028C70_COMPRESSION(1);
+		color->fmask = (rtex->resource.gpu_address + rtex->fmask.offset) >> 8;
+		color->fmask_slice = S_028C88_TILE_MAX(rtex->fmask.slice_tile_max);
+	} else {
+		color->fmask = color->offset;
+		color->fmask_slice = S_028C88_TILE_MAX(slice);
 	}
+}
+
+/**
+ * This function intializes the CB* register values for RATs.  It is meant
+ * to be used for 1D aligned buffers that do not have an associated
+ * radeon_surf.
+ */
+void evergreen_init_color_surface_rat(struct r600_context *rctx,
+					struct r600_surface *surf)
+{
+	struct pipe_resource *pipe_buffer = surf->base.texture;
+	unsigned format = r600_translate_colorformat(rctx->b.chip_class,
+						     surf->base.format);
+	unsigned endian = r600_colorformat_endian_swap(format);
+	unsigned swap = r600_translate_colorswap(surf->base.format);
+	unsigned block_size =
+		align(util_format_get_blocksize(pipe_buffer->format), 4);
+	unsigned pitch_alignment =
+		MAX2(64, rctx->screen->b.info.pipe_interleave_bytes / block_size);
+	unsigned pitch = align(pipe_buffer->width0, pitch_alignment);
+
+	surf->cb_color_base = r600_resource(pipe_buffer)->gpu_address >> 8;
+
+	surf->cb_color_pitch = (pitch / 8) - 1;
+
+	surf->cb_color_slice = 0;
+
+	surf->cb_color_view = 0;
+
+	surf->cb_color_info =
+		  S_028C70_ENDIAN(endian)
+		| S_028C70_FORMAT(format)
+		| S_028C70_ARRAY_MODE(V_028C70_ARRAY_LINEAR_ALIGNED)
+		| S_028C70_NUMBER_TYPE(V_028C70_NUMBER_UINT)
+		| S_028C70_COMP_SWAP(swap)
+		| S_028C70_BLEND_BYPASS(1) /* We must set this bit because we
+					    * are using NUMBER_UINT */
+		| S_028C70_RAT(1)
+		;
+
+	surf->cb_color_attrib = S_028C74_NON_DISP_TILING_ORDER(1);
+
+	/* For buffers, CB_COLOR0_DIM needs to be set to the number of
+	 * elements. */
+	surf->cb_color_dim = pipe_buffer->width0;
+
+	/* Set the buffer range the GPU will have access to: */
+	util_range_add(&r600_resource(pipe_buffer)->valid_buffer_range,
+		       0, pipe_buffer->width0);
 
-	base_offset = rtex->resource.gpu_address;
+	surf->cb_color_fmask = surf->cb_color_base;
+	surf->cb_color_fmask_slice = 0;
+}
+
+
+void evergreen_init_color_surface(struct r600_context *rctx,
+				  struct r600_surface *surf)
+{
+	struct r600_texture *rtex = (struct r600_texture*)surf->base.texture;
+	unsigned level = surf->base.u.tex.level;
+	struct r600_tex_color_info color;
+
+	evergreen_set_color_surface_common(rctx, rtex, level,
+					   surf->base.u.tex.first_layer,
+					   surf->base.u.tex.last_layer,
+					   surf->base.format,
+					   &color);
+
+	surf->alphatest_bypass = color.ntype == V_028C70_NUMBER_UINT ||
+		color.ntype == V_028C70_NUMBER_SINT;
+	surf->export_16bpc = color.export_16bpc;
 
 	/* XXX handle enabling of CB beyond BASE8 which has different offset */
-	surf->cb_color_base = (base_offset + offset) >> 8;
-	surf->cb_color_dim = color_dim;
-	surf->cb_color_info = color_info;
-	surf->cb_color_pitch = S_028C64_PITCH_TILE_MAX(pitch);
-	surf->cb_color_slice = S_028C68_SLICE_TILE_MAX(slice);
-	surf->cb_color_view = color_view;
-	surf->cb_color_attrib = color_attrib;
-	if (rtex->fmask.size) {
-		surf->cb_color_fmask = (base_offset + rtex->fmask.offset) >> 8;
-		surf->cb_color_fmask_slice = S_028C88_TILE_MAX(rtex->fmask.slice_tile_max);
-	} else {
-		surf->cb_color_fmask = surf->cb_color_base;
-		surf->cb_color_fmask_slice = S_028C88_TILE_MAX(slice);
-	}
+	surf->cb_color_base = color.offset;
+	surf->cb_color_dim = color.dim;
+	surf->cb_color_info = color.info;
+	surf->cb_color_pitch = color.pitch;
+	surf->cb_color_slice = color.slice;
+	surf->cb_color_view = color.view;
+	surf->cb_color_attrib = color.attrib;
+	surf->cb_color_fmask = color.fmask;
+	surf->cb_color_fmask_slice = color.fmask_slice;
 
 	surf->color_initialized = true;
 }
-- 
2.5.0



More information about the mesa-dev mailing list