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 <michel.daenzer@amd.com>
This commit is contained in:
Marek Olšák 2015-03-15 18:11:19 +01:00
parent 4f20a8f278
commit 303d23e10d
3 changed files with 39 additions and 1 deletions

View File

@ -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

View File

@ -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;

View File

@ -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];