mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-04-21 18:30:42 +02:00
nir/alpha_to_coverage: Add an intrinsic for better dithering
Reviewed-by: Iago Toral Quiroga <itoral@igalia.com> Reviewed-by: Alyssa Rosenzweig <alyssa@rosenzweig.io> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33942>
This commit is contained in:
parent
a6f67d5b69
commit
b38c4e8982
5 changed files with 26 additions and 12 deletions
|
|
@ -447,7 +447,7 @@ agx_nir_fs_epilog(nir_builder *b, const void *key_)
|
|||
|
||||
/* Alpha-to-coverage must be lowered before alpha-to-one */
|
||||
if (key->blend.alpha_to_coverage)
|
||||
NIR_PASS(_, b->shader, nir_lower_alpha_to_coverage, tib.nr_samples);
|
||||
NIR_PASS(_, b->shader, nir_lower_alpha_to_coverage, tib.nr_samples, false);
|
||||
|
||||
/* Depth/stencil writes must be deferred until after all discards,
|
||||
* particularly alpha-to-coverage.
|
||||
|
|
|
|||
|
|
@ -5224,7 +5224,8 @@ bool nir_lower_alpha_test(nir_shader *shader, enum compare_func func,
|
|||
const gl_state_index16 *alpha_ref_state_tokens);
|
||||
|
||||
bool nir_lower_alpha_to_coverage(nir_shader *shader,
|
||||
uint8_t nr_samples);
|
||||
uint8_t nr_samples,
|
||||
bool has_intrinsic);
|
||||
|
||||
bool nir_lower_alpha_to_one(nir_shader *shader);
|
||||
|
||||
|
|
|
|||
|
|
@ -817,6 +817,7 @@ visit_intrinsic(nir_intrinsic_instr *instr, struct divergence_state *state)
|
|||
case nir_intrinsic_task_payload_atomic_swap:
|
||||
case nir_intrinsic_global_atomic:
|
||||
case nir_intrinsic_global_atomic_swap:
|
||||
case nir_intrinsic_alpha_to_coverage:
|
||||
case nir_intrinsic_global_atomic_amd:
|
||||
case nir_intrinsic_global_atomic_agx:
|
||||
case nir_intrinsic_global_atomic_swap_amd:
|
||||
|
|
|
|||
|
|
@ -1124,6 +1124,10 @@ intrinsic("load_sample_pos_from_id", src_comp=[1], dest_comp=2,
|
|||
# per-sample demote, or an inverted accumulating gl_SampleMask write.
|
||||
intrinsic("demote_samples", src_comp=[1])
|
||||
|
||||
# Convert float value to coverage mask.
|
||||
intrinsic("alpha_to_coverage", src_comp=[1], dest_comp=1, indices=[],
|
||||
flags=[CAN_ELIMINATE, CAN_REORDER], bit_sizes=[16])
|
||||
|
||||
intrinsic("load_persp_center_rhw_ir3", dest_comp=1,
|
||||
flags=[CAN_ELIMINATE, CAN_REORDER])
|
||||
|
||||
|
|
|
|||
|
|
@ -7,12 +7,28 @@
|
|||
#include "nir.h"
|
||||
#include "nir_builder.h"
|
||||
|
||||
static nir_def *
|
||||
alpha_to_coverage(nir_builder *b, nir_def *alpha, uint8_t nr_samples, bool has_intrinsic)
|
||||
{
|
||||
if (has_intrinsic)
|
||||
return nir_alpha_to_coverage(b, alpha);
|
||||
|
||||
/* Calculate a coverage mask (alpha * nr_samples) bits set. The way we do
|
||||
* this isn't particularly clever:
|
||||
*
|
||||
* # of bits = (unsigned int) (alpha * nr_samples)
|
||||
* mask = (1 << (# of bits)) - 1
|
||||
*/
|
||||
nir_def *bits = nir_f2u32(b, nir_fmul_imm(b, alpha, nr_samples));
|
||||
return nir_iadd_imm(b, nir_ishl(b, nir_imm_intN_t(b, 1, 16), bits), -1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Lower alpha-to-coverage to sample_mask and some math. May run on either a
|
||||
* monolithic pixel shader or a fragment epilogue.
|
||||
*/
|
||||
bool
|
||||
nir_lower_alpha_to_coverage(nir_shader *shader, uint8_t nr_samples)
|
||||
nir_lower_alpha_to_coverage(nir_shader *shader, uint8_t nr_samples, bool has_intrinsic)
|
||||
{
|
||||
/* nir_lower_io_to_temporaries ensures that stores are in the last block */
|
||||
nir_function_impl *impl = nir_shader_get_entrypoint(shader);
|
||||
|
|
@ -52,16 +68,8 @@ nir_lower_alpha_to_coverage(nir_shader *shader, uint8_t nr_samples)
|
|||
nir_builder _b = nir_builder_at(nir_before_instr(&store->instr));
|
||||
nir_builder *b = &_b;
|
||||
|
||||
/* Calculate a coverage mask (alpha * nr_samples) bits set. The way we do
|
||||
* this isn't particularly clever:
|
||||
*
|
||||
* # of bits = (unsigned int) (alpha * nr_samples)
|
||||
* mask = (1 << (# of bits)) - 1
|
||||
*/
|
||||
nir_def *alpha = nir_channel(b, rgba, 3);
|
||||
nir_def *bits = nir_f2u32(b, nir_fmul_imm(b, alpha, nr_samples));
|
||||
nir_def *mask =
|
||||
nir_iadd_imm(b, nir_ishl(b, nir_imm_intN_t(b, 1, 16), bits), -1);
|
||||
nir_def *mask = alpha_to_coverage(b, alpha, nr_samples, has_intrinsic);
|
||||
|
||||
/* Discard samples that aren't covered */
|
||||
nir_demote_samples(b, nir_inot(b, mask));
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue