[Mesa-dev] [PATCH 2/2] svga: implement MSAA alpha_to_one feature

Roland Scheidegger sroland at vmware.com
Tue Jul 25 05:59:44 UTC 2017


Reviewed-by: Roland Scheidegger <sroland at vmware.com>

Am 25.07.2017 um 05:05 schrieb Brian Paul:
> The device doesn't directly support this feature so we implement it with
> additional shader code which sets the color output(s) w component to
> 1.0 (or max_int or max_uint).
> 
> Fixes 16 Piglit ext_framebuffer_multisample/*alpha-to-one* tests.
> 
> v2: only support unorm/float buffers, not int/uint, per Roland.
> ---
>  src/gallium/drivers/svga/svga_context.h     |  1 +
>  src/gallium/drivers/svga/svga_pipe_blend.c  |  1 +
>  src/gallium/drivers/svga/svga_shader.h      |  1 +
>  src/gallium/drivers/svga/svga_state_fs.c    |  3 +++
>  src/gallium/drivers/svga/svga_tgsi_vgpu10.c | 41 ++++++++++++++++++++++++++++-
>  5 files changed, 46 insertions(+), 1 deletion(-)
> 
> diff --git a/src/gallium/drivers/svga/svga_context.h b/src/gallium/drivers/svga/svga_context.h
> index d0306c0..0d695a6 100644
> --- a/src/gallium/drivers/svga/svga_context.h
> +++ b/src/gallium/drivers/svga/svga_context.h
> @@ -106,6 +106,7 @@ struct svga_blend_state {
>     unsigned need_white_fragments:1;
>     unsigned independent_blend_enable:1;
>     unsigned alpha_to_coverage:1;
> +   unsigned alpha_to_one:1;
>     unsigned blend_color_alpha:1;  /**< set blend color to alpha value */
>  
>     /** Per-render target state */
> diff --git a/src/gallium/drivers/svga/svga_pipe_blend.c b/src/gallium/drivers/svga/svga_pipe_blend.c
> index 408e175..a29fbd3 100644
> --- a/src/gallium/drivers/svga/svga_pipe_blend.c
> +++ b/src/gallium/drivers/svga/svga_pipe_blend.c
> @@ -331,6 +331,7 @@ svga_create_blend_state(struct pipe_context *pipe,
>     blend->independent_blend_enable = templ->independent_blend_enable;
>  
>     blend->alpha_to_coverage = templ->alpha_to_coverage;
> +   blend->alpha_to_one = templ->alpha_to_one;
>  
>     if (svga_have_vgpu10(svga)) {
>        define_blend_state_object(svga, blend);
> diff --git a/src/gallium/drivers/svga/svga_shader.h b/src/gallium/drivers/svga/svga_shader.h
> index a594d12..dc462c9 100644
> --- a/src/gallium/drivers/svga/svga_shader.h
> +++ b/src/gallium/drivers/svga/svga_shader.h
> @@ -77,6 +77,7 @@ struct svga_compile_key
>        unsigned light_twoside:1;
>        unsigned front_ccw:1;
>        unsigned white_fragments:1;
> +      unsigned alpha_to_one:1;
>        unsigned flatshade:1;
>        unsigned pstipple:1;
>        unsigned alpha_func:4;  /**< SVGA3D_CMP_x */
> diff --git a/src/gallium/drivers/svga/svga_state_fs.c b/src/gallium/drivers/svga/svga_state_fs.c
> index bf45216..5e56899 100644
> --- a/src/gallium/drivers/svga/svga_state_fs.c
> +++ b/src/gallium/drivers/svga/svga_state_fs.c
> @@ -25,6 +25,7 @@
>  
>  #include "util/u_inlines.h"
>  #include "pipe/p_defines.h"
> +#include "util/u_format.h"
>  #include "util/u_math.h"
>  #include "util/u_memory.h"
>  #include "util/u_bitmask.h"
> @@ -234,6 +235,8 @@ make_fs_key(const struct svga_context *svga,
>      */
>     key->fs.white_fragments = svga->curr.blend->need_white_fragments;
>  
> +   key->fs.alpha_to_one = svga->curr.blend->alpha_to_one;
> +
>  #ifdef DEBUG
>     /*
>      * We expect a consistent set of samplers and sampler views.
> diff --git a/src/gallium/drivers/svga/svga_tgsi_vgpu10.c b/src/gallium/drivers/svga/svga_tgsi_vgpu10.c
> index 9f5cd4b..54b473d 100644
> --- a/src/gallium/drivers/svga/svga_tgsi_vgpu10.c
> +++ b/src/gallium/drivers/svga/svga_tgsi_vgpu10.c
> @@ -167,8 +167,8 @@ struct svga_shader_emitter_v10
>  
>     /* For fragment shaders only */
>     struct {
> -      /* apha test */
>        unsigned color_out_index[PIPE_MAX_COLOR_BUFS];  /**< the real color output regs */
> +      unsigned num_color_outputs;
>        unsigned color_tmp_index;  /**< fake/temp color output reg */
>        unsigned alpha_ref_index;  /**< immediate constant for alpha ref */
>  
> @@ -2499,6 +2499,9 @@ emit_output_declarations(struct svga_shader_emitter_v10 *emit)
>  
>              emit->fs.color_out_index[semantic_index] = index;
>  
> +            emit->fs.num_color_outputs = MAX2(emit->fs.num_color_outputs,
> +                                              index + 1);
> +
>              /* The semantic index is the shader's color output/buffer index */
>              emit_output_declaration(emit,
>                                      VGPU10_OPCODE_DCL_OUTPUT, semantic_index,
> @@ -2521,6 +2524,9 @@ emit_output_declarations(struct svga_shader_emitter_v10 *emit)
>                                          VGPU10_OPERAND_4_COMPONENT_MASK_ALL);
>                       emit->info.output_semantic_index[idx] = j;
>                    }
> +
> +                  emit->fs.num_color_outputs =
> +                     emit->key.fs.write_color0_to_n_cbufs;
>                 }
>              }
>              else {
> @@ -6378,6 +6384,36 @@ emit_pre_helpers(struct svga_shader_emitter_v10 *emit)
>  
>  
>  /**
> + * The device has no direct support for the pipe_blend_state::alpha_to_one
> + * option so we implement it here with shader code.
> + */
> +static void
> +emit_alpha_to_one_instructions(struct svga_shader_emitter_v10 *emit,
> +                               unsigned fs_color_tmp_index)
> +{
> +   struct tgsi_full_src_register one = make_immediate_reg_float(emit, 1.0f);
> +   unsigned i;
> +
> +   for (i = 0; i < emit->fs.num_color_outputs; i++) {
> +      struct tgsi_full_dst_register color_dst;
> +
> +      if (fs_color_tmp_index != INVALID_INDEX && i == 0) {
> +         /* write to the temp color register */
> +         color_dst = make_dst_temp_reg(fs_color_tmp_index);
> +      }
> +      else {
> +         /* write directly to the color[i] output */
> +         color_dst = make_dst_output_reg(emit->fs.color_out_index[i]);
> +      }
> +
> +      color_dst = writemask_dst(&color_dst, TGSI_WRITEMASK_W);
> +
> +      emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &color_dst, &one, FALSE);
> +   }
> +}
> +
> +
> +/**
>   * Emit alpha test code.  This compares TEMP[fs_color_tmp_index].w
>   * against the alpha reference value and discards the fragment if the
>   * comparison fails.
> @@ -6494,6 +6530,9 @@ emit_post_helpers(struct svga_shader_emitter_v10 *emit)
>         */
>        emit->fs.color_tmp_index = INVALID_INDEX;
>  
> +      if (emit->key.fs.alpha_to_one) {
> +         emit_alpha_to_one_instructions(emit, fs_color_tmp_index);
> +      }
>        if (emit->key.fs.alpha_func != SVGA3D_CMP_ALWAYS) {
>           emit_alpha_test_instructions(emit, fs_color_tmp_index);
>        }
> 



More information about the mesa-dev mailing list