mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-27 14:10:25 +01:00
llvmpipe: implement alpha-to-coverage dithering
Reviewed-by: Konstantin Seurer <konstantin.seurer@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31373>
This commit is contained in:
parent
6d6d5b869c
commit
ad4635d6ef
3 changed files with 48 additions and 2 deletions
|
|
@ -329,7 +329,7 @@ lp_build_alpha_to_coverage(struct gallivm_state *gallivm,
|
|||
|
||||
lp_build_context_init(&bld, gallivm, type);
|
||||
|
||||
alpha_ref_value = lp_build_const_vec(gallivm, type, 0.5);
|
||||
alpha_ref_value = lp_build_const_vec(gallivm, type, 0);
|
||||
|
||||
test = lp_build_cmp(&bld, PIPE_FUNC_GREATER, alpha, alpha_ref_value);
|
||||
|
||||
|
|
|
|||
|
|
@ -390,6 +390,8 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
|
|||
return LLVM_VERSION_MAJOR >= 15;
|
||||
case PIPE_CAP_NIR_IMAGES_AS_DEREF:
|
||||
return 0;
|
||||
case PIPE_CAP_ALPHA_TO_COVERAGE_DITHER_CONTROL:
|
||||
return 1;
|
||||
default:
|
||||
return u_pipe_screen_get_param_defaults(screen, param);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -403,6 +403,45 @@ lp_build_depth_clamp(struct gallivm_state *gallivm,
|
|||
}
|
||||
|
||||
|
||||
static LLVMValueRef
|
||||
lp_build_alpha_to_coverage_dither(struct gallivm_state *gallivm,
|
||||
struct lp_type type,
|
||||
unsigned coverage_samples,
|
||||
const LLVMValueRef* pos,
|
||||
LLVMValueRef alpha)
|
||||
{
|
||||
LLVMBuilderRef builder = gallivm->builder;
|
||||
/* Standard ordered dithering 2x2 threshold matrix. */
|
||||
LLVMValueRef elems[] = {
|
||||
lp_build_const_elem(gallivm, type, 0.125 / coverage_samples),
|
||||
lp_build_const_elem(gallivm, type, 0.625 / coverage_samples),
|
||||
lp_build_const_elem(gallivm, type, 0.875 / coverage_samples),
|
||||
lp_build_const_elem(gallivm, type, 0.375 / coverage_samples),
|
||||
};
|
||||
LLVMValueRef dither_thresholds = LLVMConstVector(elems, ARRAY_SIZE(elems));
|
||||
/* Get a two bit mask, where each bit is even/odd on X and Y. */
|
||||
LLVMTypeRef int_vec_type = lp_build_int_vec_type(gallivm, type);
|
||||
LLVMValueRef frag_int_pos_x = LLVMBuildFPToSI(builder, pos[0], int_vec_type, "frag_int_pos_x");
|
||||
LLVMValueRef frag_int_pos_y = LLVMBuildFPToSI(builder, pos[1], int_vec_type, "frag_int_pos_y");
|
||||
LLVMValueRef odd_bitmask = lp_build_const_int_vec(gallivm, type, 1);
|
||||
LLVMValueRef dither_index = LLVMBuildOr(builder, LLVMBuildAnd(builder, frag_int_pos_x, odd_bitmask, ""),
|
||||
LLVMBuildShl(builder, LLVMBuildAnd(builder, frag_int_pos_y, odd_bitmask, ""),
|
||||
lp_build_const_int_vec(gallivm, type, 1), ""), "dither_index");
|
||||
/* Use the bit mask as an index in the threshold matrix, subtract it from the alpha value. */
|
||||
LLVMValueRef offsets = LLVMGetUndef(lp_build_vec_type(gallivm, type));
|
||||
for (unsigned i = 0; i < type.length; i++) {
|
||||
LLVMValueRef index = lp_build_const_int32(gallivm, i);
|
||||
offsets = LLVMBuildInsertElement(builder, offsets,
|
||||
LLVMBuildExtractElement(builder, dither_thresholds,
|
||||
LLVMBuildExtractElement(builder, dither_index,
|
||||
index, "threshold"),
|
||||
""), index, "");
|
||||
}
|
||||
/* Alpha value is only used in a comparison, no need to clamp to [0, 1]. */
|
||||
return LLVMBuildFSub(builder, alpha, offsets, "");
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
lp_build_sample_alpha_to_coverage(struct gallivm_state *gallivm,
|
||||
struct lp_type type,
|
||||
|
|
@ -1100,13 +1139,18 @@ generate_fs_loop(struct gallivm_state *gallivm,
|
|||
}
|
||||
}
|
||||
|
||||
/* Emulate Alpha to Coverage with Alpha test */
|
||||
/* Alpha to coverage */
|
||||
if (key->blend.alpha_to_coverage) {
|
||||
int color0 = find_output_by_frag_result(nir, FRAG_RESULT_DATA0);
|
||||
|
||||
if (color0 != -1 && outputs[color0][3]) {
|
||||
LLVMValueRef alpha = LLVMBuildLoad2(builder, vec_type, outputs[color0][3], "alpha");
|
||||
|
||||
if (key->blend.alpha_to_coverage_dither) {
|
||||
alpha = lp_build_alpha_to_coverage_dither(gallivm, type, key->coverage_samples,
|
||||
interp->pos, alpha);
|
||||
}
|
||||
|
||||
if (!key->multisample) {
|
||||
lp_build_alpha_to_coverage(gallivm, type,
|
||||
&mask, alpha,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue