Module: Mesa
Branch: main
Commit: fd7debc8bbb8f6a13f1f0e69c05d5000287a8e2f
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=fd7debc8bbb8f6a13f1f0e69c05d5000287a8e2f

Author: Lionel Landwerlin <[email protected]>
Date:   Wed Mar  9 15:31:34 2022 +0200

intel/fs: make alpha_to_coverage a tristate

That way in some cases we can do this dynamically.

Signed-off-by: Lionel Landwerlin <[email protected]>
Reviewed-by: Caio Oliveira <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21094>

---

 src/gallium/drivers/crocus/crocus_state.c            |  3 ++-
 src/gallium/drivers/iris/iris_program.c              |  2 +-
 src/intel/compiler/brw_compiler.h                    | 17 ++++++++++++++---
 src/intel/compiler/brw_fs.cpp                        | 12 ++++++++++--
 src/intel/compiler/brw_nir.h                         |  4 +++-
 src/intel/compiler/brw_nir_lower_alpha_to_coverage.c | 19 ++++++++++++++++++-
 src/intel/vulkan/anv_pipeline.c                      |  3 ++-
 src/intel/vulkan_hasvk/anv_pipeline.c                |  3 ++-
 8 files changed, 52 insertions(+), 11 deletions(-)

diff --git a/src/gallium/drivers/crocus/crocus_state.c 
b/src/gallium/drivers/crocus/crocus_state.c
index 2793ecfbd0f..6bf0f228e60 100644
--- a/src/gallium/drivers/crocus/crocus_state.c
+++ b/src/gallium/drivers/crocus/crocus_state.c
@@ -4836,7 +4836,8 @@ crocus_populate_fs_key(const struct crocus_context *ice,
 
    key->clamp_fragment_color = rast->cso.clamp_fragment_color;
 
-   key->alpha_to_coverage = blend->cso.alpha_to_coverage;
+   key->alpha_to_coverage = blend->cso.alpha_to_coverage ?
+      BRW_ALWAYS : BRW_NEVER;
 
    key->alpha_test_replicate_alpha = fb->nr_cbufs > 1 && 
zsa->cso.alpha_enabled;
 
diff --git a/src/gallium/drivers/iris/iris_program.c 
b/src/gallium/drivers/iris/iris_program.c
index ffda6797033..f168d2d3a5b 100644
--- a/src/gallium/drivers/iris/iris_program.c
+++ b/src/gallium/drivers/iris/iris_program.c
@@ -157,7 +157,7 @@ iris_to_brw_fs_key(const struct iris_screen *screen,
       .nr_color_regions = key->nr_color_regions,
       .flat_shade = key->flat_shade,
       .alpha_test_replicate_alpha = key->alpha_test_replicate_alpha,
-      .alpha_to_coverage = key->alpha_to_coverage,
+      .alpha_to_coverage = key->alpha_to_coverage ? BRW_ALWAYS : BRW_NEVER,
       .clamp_fragment_color = key->clamp_fragment_color,
       .persample_interp = key->persample_interp ? BRW_ALWAYS : BRW_NEVER,
       .multisample_fbo = key->multisample_fbo ? BRW_ALWAYS : BRW_NEVER,
diff --git a/src/intel/compiler/brw_compiler.h 
b/src/intel/compiler/brw_compiler.h
index 0efcaa1e224..dbfc5eabf07 100644
--- a/src/intel/compiler/brw_compiler.h
+++ b/src/intel/compiler/brw_compiler.h
@@ -487,9 +487,11 @@ struct brw_wm_prog_key {
    bool emit_alpha_test:1;
    enum compare_func alpha_test_func:3; /* < For Gfx4/5 MRT alpha test */
    bool alpha_test_replicate_alpha:1;
-   bool alpha_to_coverage:1;
+   enum brw_sometimes alpha_to_coverage:2;
    bool clamp_fragment_color:1;
 
+   bool force_dual_color_blend:1;
+
    /** Whether or inputs are interpolated at sample rate by default
     *
     * This corresponds to the sample shading API bit in Vulkan or OpenGL which
@@ -504,12 +506,12 @@ struct brw_wm_prog_key {
    enum brw_sometimes multisample_fbo:2;
 
    enum brw_sometimes line_aa:2;
-   bool force_dual_color_blend:1;
+
    bool coherent_fb_fetch:1;
    bool ignore_sample_mask_out:1;
    bool coarse_pixel:1;
 
-   uint64_t padding:56;
+   uint64_t padding:55;
 };
 
 struct brw_cs_prog_key {
@@ -863,6 +865,9 @@ enum brw_wm_msaa_flags {
    /** True if inputs should be interpolated per-sample by default */
    BRW_WM_MSAA_FLAG_PERSAMPLE_INTERP = (1 << 3),
 
+   /** True if this shader has been dispatched with alpha-to-coverage */
+   BRW_WM_MSAA_FLAG_ALPHA_TO_COVERAGE = (1 << 4),
+
    /** True if this shader has been dispatched coarse
     *
     * This is intentionally chose to be bit 15 to correspond to the coarse bit
@@ -949,6 +954,12 @@ struct brw_wm_prog_data {
     */
    enum brw_sometimes coarse_pixel_dispatch;
 
+   /**
+    * Shader writes the SampleMask and this is AND-ed with the API's
+    * SampleMask to generate a new coverage mask.
+    */
+   enum brw_sometimes alpha_to_coverage;
+
    unsigned msaa_flags_param;
 
    /**
diff --git a/src/intel/compiler/brw_fs.cpp b/src/intel/compiler/brw_fs.cpp
index 792432ab9e5..181e08d8ce4 100644
--- a/src/intel/compiler/brw_fs.cpp
+++ b/src/intel/compiler/brw_fs.cpp
@@ -7303,6 +7303,14 @@ brw_nir_populate_wm_prog_data(const nir_shader *shader,
    prog_data->persample_dispatch = MIN2(prog_data->persample_dispatch,
                                         key->multisample_fbo);
 
+   /* Currently only the Vulkan API allows alpha_to_coverage to be dynamic. If
+    * persample_dispatch & multisample_fbo are not dynamic, Anv should be able
+    * to definitively tell whether alpha_to_coverage is on or off.
+    */
+   prog_data->alpha_to_coverage = key->alpha_to_coverage;
+   assert(prog_data->alpha_to_coverage != BRW_SOMETIMES ||
+          prog_data->persample_dispatch == BRW_SOMETIMES);
+
    if (devinfo->ver >= 6) {
       prog_data->uses_sample_mask =
          BITSET_TEST(shader->info.system_values_read, 
SYSTEM_VALUE_SAMPLE_MASK_IN);
@@ -7411,13 +7419,13 @@ brw_compile_fs(const struct brw_compiler *compiler,
     *  "If Pixel Shader outputs oMask, AlphaToCoverage is disabled in
     *   hardware, regardless of the state setting for this feature."
     */
-   if (devinfo->ver > 6 && key->alpha_to_coverage) {
+   if (devinfo->ver > 6 && key->alpha_to_coverage != BRW_NEVER) {
       /* Run constant fold optimization in order to get the correct source
        * offset to determine render target 0 store instruction in
        * emit_alpha_to_coverage pass.
        */
       NIR_PASS_V(nir, nir_opt_constant_folding);
-      NIR_PASS_V(nir, brw_nir_lower_alpha_to_coverage);
+      NIR_PASS_V(nir, brw_nir_lower_alpha_to_coverage, key, prog_data);
    }
 
    NIR_PASS_V(nir, brw_nir_move_interpolation_to_top);
diff --git a/src/intel/compiler/brw_nir.h b/src/intel/compiler/brw_nir.h
index b11a36a34e2..88844922424 100644
--- a/src/intel/compiler/brw_nir.h
+++ b/src/intel/compiler/brw_nir.h
@@ -109,7 +109,9 @@ brw_nir_link_shaders(const struct brw_compiler *compiler,
                      nir_shader *producer, nir_shader *consumer);
 
 bool brw_nir_lower_cs_intrinsics(nir_shader *nir);
-bool brw_nir_lower_alpha_to_coverage(nir_shader *shader);
+bool brw_nir_lower_alpha_to_coverage(nir_shader *shader,
+                                     const struct brw_wm_prog_key *key,
+                                     const struct brw_wm_prog_data *prog_data);
 void brw_nir_lower_vs_inputs(nir_shader *nir,
                              bool edgeflag_is_last,
                              const uint8_t *vs_attrib_wa_flags);
diff --git a/src/intel/compiler/brw_nir_lower_alpha_to_coverage.c 
b/src/intel/compiler/brw_nir_lower_alpha_to_coverage.c
index 2f07ed451bb..55020616fd5 100644
--- a/src/intel/compiler/brw_nir_lower_alpha_to_coverage.c
+++ b/src/intel/compiler/brw_nir_lower_alpha_to_coverage.c
@@ -78,9 +78,13 @@ build_dither_mask(nir_builder *b, nir_ssa_def *color)
 }
 
 bool
-brw_nir_lower_alpha_to_coverage(nir_shader *shader)
+brw_nir_lower_alpha_to_coverage(nir_shader *shader,
+                                const struct brw_wm_prog_key *key,
+                                const struct brw_wm_prog_data *prog_data)
 {
    assert(shader->info.stage == MESA_SHADER_FRAGMENT);
+   assert(key->alpha_to_coverage != BRW_NEVER);
+
    nir_function_impl *impl = nir_shader_get_entrypoint(shader);
 
    const uint64_t outputs_written = shader->info.outputs_written;
@@ -168,8 +172,21 @@ brw_nir_lower_alpha_to_coverage(nir_shader *shader)
 
    /* Combine dither_mask and the gl_SampleMask value */
    b.cursor = nir_before_instr(&sample_mask_write->instr);
+
    nir_ssa_def *dither_mask = build_dither_mask(&b, color0);
    dither_mask = nir_iand(&b, sample_mask, dither_mask);
+
+   if (key->alpha_to_coverage == BRW_SOMETIMES) {
+      nir_ssa_def *push_flags =
+         nir_load_uniform(&b, 1, 32, nir_imm_int(&b, 
prog_data->msaa_flags_param * 4));
+      nir_ssa_def *alpha_to_coverage =
+         nir_i2b(&b,
+                 nir_iadd_imm(&b, push_flags,
+                              BRW_WM_MSAA_FLAG_ALPHA_TO_COVERAGE));
+      dither_mask = nir_bcsel(&b, alpha_to_coverage,
+                              dither_mask, sample_mask_write->src[0].ssa);
+   }
+
    nir_instr_rewrite_src(&sample_mask_write->instr,
                          &sample_mask_write->src[0],
                          nir_src_for_ssa(dither_mask));
diff --git a/src/intel/vulkan/anv_pipeline.c b/src/intel/vulkan/anv_pipeline.c
index c0e69cdc481..016f6355195 100644
--- a/src/intel/vulkan/anv_pipeline.c
+++ b/src/intel/vulkan/anv_pipeline.c
@@ -546,7 +546,8 @@ populate_wm_prog_key(const struct anv_graphics_pipeline 
*pipeline,
     * code to workaround the issue that hardware disables alpha to coverage
     * when there is SampleMask output.
     */
-   key->alpha_to_coverage = ms != NULL && ms->alpha_to_coverage_enable;
+   key->alpha_to_coverage = ms != NULL && ms->alpha_to_coverage_enable ?
+      BRW_ALWAYS : BRW_NEVER;
 
    /* Vulkan doesn't support fixed-function alpha test */
    key->alpha_test_replicate_alpha = false;
diff --git a/src/intel/vulkan_hasvk/anv_pipeline.c 
b/src/intel/vulkan_hasvk/anv_pipeline.c
index bf9cbbc41ce..03fda25acfc 100644
--- a/src/intel/vulkan_hasvk/anv_pipeline.c
+++ b/src/intel/vulkan_hasvk/anv_pipeline.c
@@ -363,7 +363,8 @@ populate_wm_prog_key(const struct anv_graphics_pipeline 
*pipeline,
     * code to workaround the issue that hardware disables alpha to coverage
     * when there is SampleMask output.
     */
-   key->alpha_to_coverage = ms != NULL && ms->alpha_to_coverage_enable;
+   key->alpha_to_coverage = ms != NULL && ms->alpha_to_coverage_enable ?
+      BRW_ALWAYS : BRW_NEVER;
 
    /* Vulkan doesn't support fixed-function alpha test */
    key->alpha_test_replicate_alpha = false;

Reply via email to