summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2015-03-15 18:11:19 +0100
committerMarek Olšák <[email protected]>2015-03-16 12:54:19 +0100
commit303d23e10d2caad69b2d122f45c78fee2906fc09 (patch)
tree58078e4d5617f812ea9fb43b6407866b3da9c14b /src
parent4f20a8f278aa92fb0dc6abc6998171b3ddea7dc1 (diff)
radeonsi: add shader code for smoothing
The fragment shader multiplies the alpha channel with gl_SampleMaskIn. If blending is enabled, it looks like MSAA. Reviewed-by: Michel Dänzer <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/radeonsi/si_pipe.h1
-rw-r--r--src/gallium/drivers/radeonsi/si_shader.c38
-rw-r--r--src/gallium/drivers/radeonsi/si_shader.h1
3 files changed, 39 insertions, 1 deletions
diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h
index 1496d5fedd7..1bc664a50ec 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 a57fdf4e1bd..2703704a7fe 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -644,7 +644,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:
@@ -828,6 +833,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)
{
@@ -1361,6 +1394,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 4f2bb911160..5b602ac3428 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];