[Mesa-dev] [PATCH 1/3] radeonsi: implement fragment color clamping

Marek Olšák maraeo at gmail.com
Sat Oct 10 18:17:28 PDT 2015


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

using the shader key for now.
---
 src/gallium/drivers/radeonsi/si_pipe.c          |  2 +-
 src/gallium/drivers/radeonsi/si_shader.c        | 13 +++++++++++++
 src/gallium/drivers/radeonsi/si_shader.h        |  1 +
 src/gallium/drivers/radeonsi/si_state.c         |  2 +-
 src/gallium/drivers/radeonsi/si_state.h         |  1 +
 src/gallium/drivers/radeonsi/si_state_shaders.c |  1 +
 6 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c
index aa5a9ea..894fc59 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.c
+++ b/src/gallium/drivers/radeonsi/si_pipe.c
@@ -271,6 +271,7 @@ static int si_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
 	case PIPE_CAP_START_INSTANCE:
 	case PIPE_CAP_NPOT_TEXTURES:
 	case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:
+	case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
         case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
 	case PIPE_CAP_TGSI_INSTANCEID:
 	case PIPE_CAP_COMPUTE:
@@ -330,7 +331,6 @@ static int si_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
 	/* Unsupported features. */
 	case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
 	case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
-	case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
 	case PIPE_CAP_VERTEX_COLOR_CLAMPED:
 	case PIPE_CAP_USER_VERTEX_BUFFERS:
 	case PIPE_CAP_FAKE_SW_MSAA:
diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
index 012d708..1f9b2b6 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -2109,6 +2109,7 @@ static void si_llvm_emit_fs_epilogue(struct lp_build_tgsi_context * bld_base)
 	struct lp_build_context * base = &bld_base->base;
 	struct lp_build_context * uint = &bld_base->uint_bld;
 	struct tgsi_shader_info *info = &shader->selector->info;
+	LLVMBuilderRef builder = base->gallivm->builder;
 	LLVMValueRef args[9];
 	LLVMValueRef last_args[9] = { 0 };
 	int depth_index = -1, stencil_index = -1, samplemask_index = -1;
@@ -2135,6 +2136,16 @@ static void si_llvm_emit_fs_epilogue(struct lp_build_tgsi_context * bld_base)
 			target = V_008DFC_SQ_EXP_MRT + semantic_index;
 			alpha_ptr = si_shader_ctx->radeon_bld.soa.outputs[i][3];
 
+			if (si_shader_ctx->shader->key.ps.clamp_color) {
+				for (int j = 0; j < 4; j++) {
+					LLVMValueRef ptr = si_shader_ctx->radeon_bld.soa.outputs[i][j];
+					LLVMValueRef result = LLVMBuildLoad(builder, ptr, "");
+
+					result = radeon_llvm_saturate(bld_base, result);
+					LLVMBuildStore(builder, result, ptr);
+				}
+			}
+
 			if (si_shader_ctx->shader->key.ps.alpha_to_one)
 				LLVMBuildStore(base->gallivm->builder,
 					       base->one, alpha_ptr);
@@ -2145,6 +2156,7 @@ static void si_llvm_emit_fs_epilogue(struct lp_build_tgsi_context * bld_base)
 
 			if (si_shader_ctx->shader->key.ps.poly_line_smoothing)
 				si_scale_alpha_by_sample_mask(bld_base, alpha_ptr);
+
 			break;
 		default:
 			target = 0;
@@ -3999,6 +4011,7 @@ void si_dump_shader_key(unsigned shader, union si_shader_key *key, FILE *f)
 		fprintf(f, "  alpha_func = %u\n", key->ps.alpha_func);
 		fprintf(f, "  alpha_to_one = %u\n", key->ps.alpha_to_one);
 		fprintf(f, "  poly_stipple = %u\n", key->ps.poly_stipple);
+		fprintf(f, "  clamp_color = %u\n", key->ps.clamp_color);
 		break;
 
 	default:
diff --git a/src/gallium/drivers/radeonsi/si_shader.h b/src/gallium/drivers/radeonsi/si_shader.h
index cccc460..fa5930a 100644
--- a/src/gallium/drivers/radeonsi/si_shader.h
+++ b/src/gallium/drivers/radeonsi/si_shader.h
@@ -227,6 +227,7 @@ union si_shader_key {
 		unsigned	alpha_to_one:1;
 		unsigned	poly_stipple:1;
 		unsigned	poly_line_smoothing:1;
+		unsigned	clamp_color:1;
 	} ps;
 	struct {
 		unsigned	instance_divisors[SI_NUM_VERTEX_BUFFERS];
diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
index 00d4bc1..3aafe8a 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -694,7 +694,7 @@ static void *si_create_rs_state(struct pipe_context *ctx,
 	rs->poly_smooth = state->poly_smooth;
 	rs->uses_poly_offset = state->offset_point || state->offset_line ||
 			       state->offset_tri;
-
+	rs->clamp_fragment_color = state->clamp_fragment_color;
 	rs->flatshade = state->flatshade;
 	rs->sprite_coord_enable = state->sprite_coord_enable;
 	rs->pa_sc_line_stipple = state->line_stipple_enable ?
diff --git a/src/gallium/drivers/radeonsi/si_state.h b/src/gallium/drivers/radeonsi/si_state.h
index 6a56768..fba6619 100644
--- a/src/gallium/drivers/radeonsi/si_state.h
+++ b/src/gallium/drivers/radeonsi/si_state.h
@@ -60,6 +60,7 @@ struct si_state_rasterizer {
 	bool			line_smooth;
 	bool			poly_smooth;
 	bool			uses_poly_offset;
+	bool			clamp_fragment_color;
 };
 
 struct si_dsa_stencil_ref_part {
diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c b/src/gallium/drivers/radeonsi/si_state_shaders.c
index 71349a5..c00f8f4 100644
--- a/src/gallium/drivers/radeonsi/si_state_shaders.c
+++ b/src/gallium/drivers/radeonsi/si_state_shaders.c
@@ -572,6 +572,7 @@ static inline void si_shader_selector_key(struct pipe_context *ctx,
 			key->ps.poly_line_smoothing = ((is_poly && rs->poly_smooth) ||
 						       (is_line && rs->line_smooth)) &&
 						      sctx->framebuffer.nr_samples <= 1;
+			key->ps.clamp_color = rs->clamp_fragment_color;
 		}
 
 		key->ps.alpha_func = PIPE_FUNC_ALWAYS;
-- 
2.1.4



More information about the mesa-dev mailing list