From 303d23e10d2caad69b2d122f45c78fee2906fc09 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Sun, 15 Mar 2015 18:11:19 +0100 Subject: [PATCH] radeonsi: add shader code for smoothing MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit The fragment shader multiplies the alpha channel with gl_SampleMaskIn. If blending is enabled, it looks like MSAA. Reviewed-by: Michel Dänzer --- 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 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]; -- 2.30.2