[Mesa-dev] [PATCH 4/7] radeonsi: handle pipe_blend_state::srgb_enable for draw calls

Marek Olšák maraeo at gmail.com
Mon Jun 12 16:56:56 UTC 2017


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

---
 src/gallium/drivers/radeon/r600_pipe_common.h |  1 +
 src/gallium/drivers/radeonsi/si_state.c       | 18 ++++++++++++++++++
 src/gallium/drivers/radeonsi/si_state.h       |  1 +
 3 files changed, 20 insertions(+)

diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h
index 56056fa..053c928 100644
--- a/src/gallium/drivers/radeon/r600_pipe_common.h
+++ b/src/gallium/drivers/radeon/r600_pipe_common.h
@@ -284,20 +284,21 @@ struct r600_surface {
 
 	bool color_initialized;
 	bool depth_initialized;
 
 	/* Misc. color flags. */
 	bool alphatest_bypass;
 	bool export_16bpc;
 	bool color_is_int8;
 	bool color_is_int10;
 	bool dcc_incompatible;
+	bool srgb_allowed;
 
 	/* Color registers. */
 	unsigned cb_color_info;
 	unsigned cb_color_base;
 	unsigned cb_color_view;
 	unsigned cb_color_size;		/* R600 only */
 	unsigned cb_color_dim;		/* EG only */
 	unsigned cb_color_pitch;	/* EG and later */
 	unsigned cb_color_slice;	/* EG and later */
 	unsigned cb_color_attrib;	/* EG and later */
diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
index 1cd1f91..4c81c9a 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -421,20 +421,21 @@ static void *si_create_blend_state_mode(struct pipe_context *ctx,
 	struct si_pm4_state *pm4 = &blend->pm4;
 	uint32_t sx_mrt_blend_opt[8] = {0};
 	uint32_t color_control = 0;
 
 	if (!blend)
 		return NULL;
 
 	blend->alpha_to_coverage = state->alpha_to_coverage;
 	blend->alpha_to_one = state->alpha_to_one;
 	blend->dual_src_blend = util_blend_state_is_dual(state, 0);
+	blend->srgb_enable = state->srgb_enable;
 
 	if (state->logicop_enable) {
 		color_control |= S_028808_ROP3(state->logicop_func | (state->logicop_func << 4));
 	} else {
 		color_control |= S_028808_ROP3(0xcc);
 	}
 
 	si_pm4_set_reg(pm4, R_028B70_DB_ALPHA_TO_MASK,
 		       S_028B70_ALPHA_TO_MASK_ENABLE(state->alpha_to_coverage) |
 		       S_028B70_ALPHA_TO_MASK_OFFSET0(2) |
@@ -617,20 +618,27 @@ static void si_bind_blend_state(struct pipe_context *ctx, void *state)
 	si_pm4_bind_state(sctx, blend, state);
 
 	if (!old_blend ||
 	    old_blend->cb_target_mask != blend->cb_target_mask ||
 	    old_blend->alpha_to_coverage != blend->alpha_to_coverage ||
 	    old_blend->alpha_to_one != blend->alpha_to_one ||
 	    old_blend->dual_src_blend != blend->dual_src_blend ||
 	    old_blend->blend_enable_4bit != blend->blend_enable_4bit ||
 	    old_blend->need_src_alpha_4bit != blend->need_src_alpha_4bit)
 		sctx->do_update_shaders = true;
+
+	if (!old_blend ||
+	    old_blend->srgb_enable != blend->srgb_enable) {
+		sctx->framebuffer.dirty_cbufs =
+			(1 << sctx->framebuffer.state.nr_cbufs) - 1;
+		si_mark_atom_dirty(sctx, &sctx->framebuffer.atom);
+	}
 }
 
 static void si_delete_blend_state(struct pipe_context *ctx, void *state)
 {
 	struct si_context *sctx = (struct si_context *)ctx;
 	si_pm4_delete_state(sctx, blend, (struct si_state_blend *)state);
 }
 
 static void si_set_blend_color(struct pipe_context *ctx,
 			       const struct pipe_blend_color *state)
@@ -2175,20 +2183,23 @@ static void si_initialize_color_surface(struct si_context *sctx,
 		} else if (desc->channel[i].type == UTIL_FORMAT_TYPE_UNSIGNED) {
 			if (desc->channel[i].pure_integer) {
 				ntype = V_028C70_NUMBER_UINT;
 			} else {
 				assert(desc->channel[i].normalized);
 				ntype = V_028C70_NUMBER_UNORM;
 			}
 		}
 	}
 
+	surf->srgb_allowed = ntype == V_028C70_NUMBER_UNORM &&
+			     desc->channel[i].size == 8;
+
 	format = si_translate_colorformat(surf->base.format);
 	if (format == V_028C70_COLOR_INVALID) {
 		R600_ERR("Invalid CB format: %d, disabling CB.\n", surf->base.format);
 	}
 	assert(format != V_028C70_COLOR_INVALID);
 	swap = r600_translate_colorswap(surf->base.format, false);
 	endian = si_colorformat_endian_swap(format);
 
 	/* blend clamp should be set for all NORM/SRGB types */
 	if (ntype == V_028C70_NUMBER_UNORM ||
@@ -2659,20 +2670,22 @@ static void si_set_framebuffer_state(struct pipe_context *ctx,
 		sctx->need_check_render_feedback = true;
 		sctx->framebuffer.do_update_surf_dirtiness = true;
 	}
 }
 
 static void si_emit_framebuffer_state(struct si_context *sctx, struct r600_atom *atom)
 {
 	struct radeon_winsys_cs *cs = sctx->b.gfx.cs;
 	struct pipe_framebuffer_state *state = &sctx->framebuffer.state;
 	unsigned i, nr_cbufs = state->nr_cbufs;
+	struct si_state_blend *blend = sctx->queued.named.blend;
+	ubyte srgb_enable = blend ? blend->srgb_enable : 0;
 	struct r600_texture *tex = NULL;
 	struct r600_surface *cb = NULL;
 	unsigned cb_color_info = 0;
 
 	/* Colorbuffers. */
 	for (i = 0; i < nr_cbufs; i++) {
 		uint64_t cb_color_base, cb_color_fmask, cb_dcc_base;
 		unsigned cb_color_attrib;
 
 		if (!(sctx->framebuffer.dirty_cbufs & (1 << i)))
@@ -2704,20 +2717,25 @@ static void si_emit_framebuffer_state(struct si_context *sctx, struct r600_atom
 						  RADEON_USAGE_READWRITE,
 						  RADEON_PRIO_DCC);
 
 		/* Compute mutable surface parameters. */
 		cb_color_base = tex->resource.gpu_address >> 8;
 		cb_color_fmask = cb_color_base;
 		cb_dcc_base = 0;
 		cb_color_info = cb->cb_color_info | tex->cb_color_info;
 		cb_color_attrib = cb->cb_color_attrib;
 
+		if (cb->srgb_allowed && srgb_enable & (1 << i)) {
+			cb_color_info &= C_028C70_NUMBER_TYPE;
+			cb_color_info |= S_028C70_NUMBER_TYPE(V_028C70_NUMBER_SRGB);
+		}
+
 		if (tex->fmask.size)
 			cb_color_fmask = (tex->resource.gpu_address + tex->fmask.offset) >> 8;
 
 		/* Set up DCC. */
 		if (vi_dcc_enabled(tex, cb->base.u.tex.level)) {
 			bool is_msaa_resolve_dst = state->cbufs[0] &&
 						   state->cbufs[0]->texture->nr_samples > 1 &&
 						   state->cbufs[1] == &cb->base &&
 						   state->cbufs[1]->texture->nr_samples <= 1;
 
diff --git a/src/gallium/drivers/radeonsi/si_state.h b/src/gallium/drivers/radeonsi/si_state.h
index d8bf13e..991d90d 100644
--- a/src/gallium/drivers/radeonsi/si_state.h
+++ b/src/gallium/drivers/radeonsi/si_state.h
@@ -43,20 +43,21 @@
 struct si_screen;
 struct si_shader;
 struct si_shader_selector;
 
 struct si_state_blend {
 	struct si_pm4_state	pm4;
 	uint32_t		cb_target_mask;
 	bool			alpha_to_coverage;
 	bool			alpha_to_one;
 	bool			dual_src_blend;
+	ubyte			srgb_enable;
 	/* Set 0xf or 0x0 (4 bits) per render target if the following is
 	 * true. ANDed with spi_shader_col_format.
 	 */
 	unsigned		blend_enable_4bit;
 	unsigned		need_src_alpha_4bit;
 };
 
 struct si_state_rasterizer {
 	struct si_pm4_state	pm4;
 	/* poly offset states for 16-bit, 24-bit, and 32-bit zbuffers */
-- 
2.7.4



More information about the mesa-dev mailing list