[Mesa-dev] [PATCH 05/10] radeonsi: add shader code for smoothing

Marek Olšák maraeo at gmail.com
Sun Mar 15 12:48:25 PDT 2015


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

The fragment shader multiplies the alpha channel with gl_SampleMaskIn.
If blending is enabled, it looks like MSAA.
---
 src/gallium/drivers/radeonsi/si_pipe.h   |  1 +
 src/gallium/drivers/radeonsi/si_shader.c | 38 +++++++++++++++++++++++++++++++-
 src/gallium/drivers/radeonsi/si_shader.h |  1 +
 3 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h
index 1496d5f..1bc664a 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.h
+++ b/src/gallium/drivers/radeonsi/si_pipe.h
@@ -41,6 +41,7 @@
  * the number shouldn't be a commonly-used one. */
 #define SI_BASE_VERTEX_UNKNOWN INT_MIN
 #define SI_RESTART_INDEX_UNKNOWN INT_MIN
+#define SI_NUM_SMOOTH_AA_SAMPLES 8
 
 #define SI_TRACE_CS 0
 #define SI_TRACE_CS_DWORDS		6
diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
index 3cd6166..de889ed 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -662,7 +662,12 @@ static void declare_system_value(
 	}
 
 	case TGSI_SEMANTIC_SAMPLEMASK:
-		value = LLVMGetParam(radeon_bld->main_fn, SI_PARAM_SAMPLE_COVERAGE);
+		/* Smoothing isn't MSAA in GL, but it's MSAA in hardware.
+		 * Therefore, force gl_SampleMaskIn to 1 for GL. */
+		if (si_shader_ctx->shader->key.ps.poly_line_smoothing)
+			value = uint_bld->one;
+		else
+			value = LLVMGetParam(radeon_bld->main_fn, SI_PARAM_SAMPLE_COVERAGE);
 		break;
 
 	default:
@@ -846,6 +851,34 @@ static void si_alpha_test(struct lp_build_tgsi_context *bld_base,
 	si_shader_ctx->shader->db_shader_control |= S_02880C_KILL_ENABLE(1);
 }
 
+static void si_scale_alpha_by_sample_mask(struct lp_build_tgsi_context *bld_base,
+					  LLVMValueRef alpha_ptr)
+{
+	struct si_shader_context *si_shader_ctx = si_shader_context(bld_base);
+	struct gallivm_state *gallivm = bld_base->base.gallivm;
+	LLVMValueRef coverage, alpha;
+
+	/* alpha = alpha * popcount(coverage) / SI_NUM_SMOOTH_AA_SAMPLES */
+	coverage = LLVMGetParam(si_shader_ctx->radeon_bld.main_fn,
+				SI_PARAM_SAMPLE_COVERAGE);
+	coverage = bitcast(bld_base, TGSI_TYPE_SIGNED, coverage);
+
+	coverage = build_intrinsic(gallivm->builder, "llvm.ctpop.i32",
+				   bld_base->int_bld.elem_type,
+				   &coverage, 1, LLVMReadNoneAttribute);
+
+	coverage = LLVMBuildUIToFP(gallivm->builder, coverage,
+				   bld_base->base.elem_type, "");
+
+	coverage = LLVMBuildFMul(gallivm->builder, coverage,
+				 lp_build_const_float(gallivm,
+					1.0 / SI_NUM_SMOOTH_AA_SAMPLES), "");
+
+	alpha = LLVMBuildLoad(gallivm->builder, alpha_ptr, "");
+	alpha = LLVMBuildFMul(gallivm->builder, alpha, coverage, "");
+	LLVMBuildStore(gallivm->builder, alpha, alpha_ptr);
+}
+
 static void si_llvm_emit_clipvertex(struct lp_build_tgsi_context * bld_base,
 				    LLVMValueRef (*pos)[9], LLVMValueRef *out_elts)
 {
@@ -1372,6 +1405,9 @@ static void si_llvm_emit_fs_epilogue(struct lp_build_tgsi_context * bld_base)
 			if (semantic_index == 0 &&
 			    si_shader_ctx->shader->key.ps.alpha_func != PIPE_FUNC_ALWAYS)
 				si_alpha_test(bld_base, alpha_ptr);
+
+			if (si_shader_ctx->shader->key.ps.poly_line_smoothing)
+				si_scale_alpha_by_sample_mask(bld_base, alpha_ptr);
 			break;
 		default:
 			target = 0;
diff --git a/src/gallium/drivers/radeonsi/si_shader.h b/src/gallium/drivers/radeonsi/si_shader.h
index 4f2bb91..5b602ac 100644
--- a/src/gallium/drivers/radeonsi/si_shader.h
+++ b/src/gallium/drivers/radeonsi/si_shader.h
@@ -126,6 +126,7 @@ union si_shader_key {
 		unsigned	alpha_func:3;
 		unsigned	alpha_to_one:1;
 		unsigned	poly_stipple:1;
+		unsigned	poly_line_smoothing:1;
 	} ps;
 	struct {
 		unsigned	instance_divisors[SI_NUM_VERTEX_BUFFERS];
-- 
2.1.0



More information about the mesa-dev mailing list