diff options
author | Marek Olšák <[email protected]> | 2015-03-15 18:11:19 +0100 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2015-03-16 12:54:19 +0100 |
commit | 303d23e10d2caad69b2d122f45c78fee2906fc09 (patch) | |
tree | 58078e4d5617f812ea9fb43b6407866b3da9c14b /src/gallium | |
parent | 4f20a8f278aa92fb0dc6abc6998171b3ddea7dc1 (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/gallium')
-rw-r--r-- | src/gallium/drivers/radeonsi/si_pipe.h | 1 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/si_shader.c | 38 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/si_shader.h | 1 |
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]; |