From 71d3b69b239c2e2eb8b154229c5defc013b7c7b5 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 21 Jul 2017 09:38:10 -0600 Subject: [PATCH] svga: rework the FS white fragments code When we forcibly write white to FS outputs (for XOR mode emulation) we were using a temp register. But that's not really necessary. This also fixes the case of writing white to multiple color buffers. Subsequent changes will build on this. Reviewed-by: Charmaine Lee --- src/gallium/drivers/svga/svga_state_fs.c | 11 +++--- src/gallium/drivers/svga/svga_tgsi_vgpu10.c | 43 ++++++++------------- 2 files changed, 21 insertions(+), 33 deletions(-) diff --git a/src/gallium/drivers/svga/svga_state_fs.c b/src/gallium/drivers/svga/svga_state_fs.c index 07a3614d79d..bf452163049 100644 --- a/src/gallium/drivers/svga/svga_state_fs.c +++ b/src/gallium/drivers/svga/svga_state_fs.c @@ -232,9 +232,7 @@ make_fs_key(const struct svga_context *svga, * * SVGA_NEW_BLEND */ - if (svga->curr.blend->need_white_fragments) { - key->fs.white_fragments = 1; - } + key->fs.white_fragments = svga->curr.blend->need_white_fragments; #ifdef DEBUG /* @@ -349,9 +347,10 @@ make_fs_key(const struct svga_context *svga, } } - /* SVGA_NEW_FRAME_BUFFER */ - if (fs->base.info.properties[TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS]) { - /* Replicate color0 output to N colorbuffers */ + /* SVGA_NEW_FRAME_BUFFER | SVGA_NEW_BLEND */ + if (fs->base.info.properties[TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS] || + svga->curr.blend->need_white_fragments) { + /* Replicate color0 output (or white) to N colorbuffers */ key->fs.write_color0_to_n_cbufs = svga->curr.framebuffer.nr_cbufs; } diff --git a/src/gallium/drivers/svga/svga_tgsi_vgpu10.c b/src/gallium/drivers/svga/svga_tgsi_vgpu10.c index d9b76c265ab..9f5cd4b285b 100644 --- a/src/gallium/drivers/svga/svga_tgsi_vgpu10.c +++ b/src/gallium/drivers/svga/svga_tgsi_vgpu10.c @@ -2707,7 +2707,6 @@ emit_temporaries_declaration(struct svga_shader_emitter_v10 *emit) } else if (emit->unit == PIPE_SHADER_FRAGMENT) { if (emit->key.fs.alpha_func != SVGA3D_CMP_ALWAYS || - emit->key.fs.white_fragments || emit->key.fs.write_color0_to_n_cbufs > 1) { /* Allocate a temp to hold the output color */ emit->fs.color_tmp_index = total_temps; @@ -6414,11 +6413,9 @@ emit_alpha_test_instructions(struct svga_shader_emitter_v10 *emit, emit_src_register(emit, &tmp_src_x); end_emit_instruction(emit); - /* If we don't need to broadcast the color below or set fragments to - * white, emit final color here. + /* If we don't need to broadcast the color below, emit the final color here. */ - if (emit->key.fs.write_color0_to_n_cbufs <= 1 && - !emit->key.fs.white_fragments) { + if (emit->key.fs.write_color0_to_n_cbufs <= 1) { /* MOV output.color, tempcolor */ emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &color_dst, &color_src, FALSE); /* XXX saturate? */ @@ -6428,23 +6425,6 @@ emit_alpha_test_instructions(struct svga_shader_emitter_v10 *emit, } -/** - * When we need to emit white for all fragments (for emulating XOR logicop - * mode), this function copies white into the temporary color output register. - */ -static void -emit_set_color_white(struct svga_shader_emitter_v10 *emit, - unsigned fs_color_tmp_index) -{ - struct tgsi_full_dst_register color_dst = - make_dst_temp_reg(fs_color_tmp_index); - struct tgsi_full_src_register white = - make_immediate_reg_float(emit, 1.0f); - - emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &color_dst, &white, FALSE); -} - - /** * Emit instructions for writing a single color output to multiple * color buffers. @@ -6460,8 +6440,17 @@ emit_broadcast_color_instructions(struct svga_shader_emitter_v10 *emit, { const unsigned n = emit->key.fs.write_color0_to_n_cbufs; unsigned i; - struct tgsi_full_src_register color_src = - make_src_temp_reg(fs_color_tmp_index); + struct tgsi_full_src_register color_src; + + if (emit->key.fs.white_fragments) { + /* set all color outputs to white */ + color_src = make_immediate_reg_float(emit, 1.0f); + } + else { + /* set all color outputs to TEMP[fs_color_tmp_index] */ + assert(fs_color_tmp_index != INVALID_INDEX); + color_src = make_src_temp_reg(fs_color_tmp_index); + } assert(emit->unit == PIPE_SHADER_FRAGMENT); @@ -6497,6 +6486,9 @@ emit_post_helpers(struct svga_shader_emitter_v10 *emit) else if (emit->unit == PIPE_SHADER_FRAGMENT) { const unsigned fs_color_tmp_index = emit->fs.color_tmp_index; + assert(!(emit->key.fs.white_fragments && + emit->key.fs.write_color0_to_n_cbufs == 0)); + /* We no longer want emit_dst_register() to substitute the * temporary fragment color register for the real color output. */ @@ -6505,9 +6497,6 @@ emit_post_helpers(struct svga_shader_emitter_v10 *emit) if (emit->key.fs.alpha_func != SVGA3D_CMP_ALWAYS) { emit_alpha_test_instructions(emit, fs_color_tmp_index); } - if (emit->key.fs.white_fragments) { - emit_set_color_white(emit, fs_color_tmp_index); - } if (emit->key.fs.write_color0_to_n_cbufs > 1 || emit->key.fs.white_fragments) { emit_broadcast_color_instructions(emit, fs_color_tmp_index); -- 2.30.2