Reviewed-by: Roland Scheidegger <srol...@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); > } >
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev