From: Brian Paul Date: Fri, 17 Jan 2014 02:32:47 +0000 (-0800) Subject: svga: implement TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=b9f68d927ea;p=mesa.git svga: implement TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS Fixes several colorbuffer tests, including piglit "fbo-drawbuffers-none" for "gl_FragColor" and "glDrawPixels" cases. v2: rework patch to only avoid creating extra shader variants when TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS is not specified. Per Jose. Use a write_color0_to_n_cbufs key field to replicate color0 to N color buffers only when N > 0 and WRITES_ALL_CBUFS is set. Reviewed-by: José Fonseca --- diff --git a/src/gallium/drivers/svga/svga_state_fs.c b/src/gallium/drivers/svga/svga_state_fs.c index 51d0eb5bacb..1e9fb43f868 100644 --- a/src/gallium/drivers/svga/svga_state_fs.c +++ b/src/gallium/drivers/svga/svga_state_fs.c @@ -276,6 +276,12 @@ make_fs_key(const struct svga_context *svga, key->sprite_origin_lower_left = (svga->curr.rast->templ.sprite_coord_mode == PIPE_SPRITE_COORD_LOWER_LEFT); + /* SVGA_NEW_FRAME_BUFFER */ + if (fs->base.info.color0_writes_all_cbufs) { + /* Replicate color0 output to N colorbuffers */ + key->write_color0_to_n_cbufs = svga->curr.framebuffer.nr_cbufs; + } + return PIPE_OK; } @@ -296,6 +302,7 @@ emit_hw_fs(struct svga_context *svga, unsigned dirty) * SVGA_NEW_RAST * SVGA_NEW_NEED_SWTNL * SVGA_NEW_SAMPLER + * SVGA_NEW_FRAME_BUFFER */ ret = make_fs_key( svga, fs, &key ); if (ret != PIPE_OK) @@ -335,6 +342,7 @@ struct svga_tracked_state svga_hw_fs = SVGA_NEW_NEED_SWTNL | SVGA_NEW_RAST | SVGA_NEW_SAMPLER | + SVGA_NEW_FRAME_BUFFER | SVGA_NEW_BLEND), emit_hw_fs }; diff --git a/src/gallium/drivers/svga/svga_tgsi.h b/src/gallium/drivers/svga/svga_tgsi.h index 0e06dbf9919..591dd6a3917 100644 --- a/src/gallium/drivers/svga/svga_tgsi.h +++ b/src/gallium/drivers/svga/svga_tgsi.h @@ -56,6 +56,7 @@ struct svga_fs_compile_key unsigned light_twoside:1; unsigned front_ccw:1; unsigned white_fragments:1; + unsigned write_color0_to_n_cbufs:3; unsigned num_textures:8; unsigned num_unnormalized_coords:8; unsigned sprite_origin_lower_left:1; diff --git a/src/gallium/drivers/svga/svga_tgsi_decl_sm30.c b/src/gallium/drivers/svga/svga_tgsi_decl_sm30.c index e0a30a5248e..137afd60583 100644 --- a/src/gallium/drivers/svga/svga_tgsi_decl_sm30.c +++ b/src/gallium/drivers/svga/svga_tgsi_decl_sm30.c @@ -327,14 +327,35 @@ ps30_output(struct svga_shader_emitter *emit, { switch (semantic.Name) { case TGSI_SEMANTIC_COLOR: - if (emit->unit == PIPE_SHADER_FRAGMENT && - emit->key.fkey.white_fragments) { - - emit->output_map[idx] = dst_register( SVGA3DREG_TEMP, - emit->nr_hw_temp++ ); - emit->temp_color_output[idx] = emit->output_map[idx]; - emit->true_color_output[idx] = dst_register(SVGA3DREG_COLOROUT, - semantic.Index); + if (emit->unit == PIPE_SHADER_FRAGMENT) { + if (emit->key.fkey.white_fragments) { + /* Used for XOR logicop mode */ + emit->output_map[idx] = dst_register( SVGA3DREG_TEMP, + emit->nr_hw_temp++ ); + emit->temp_color_output[idx] = emit->output_map[idx]; + emit->true_color_output[idx] = dst_register(SVGA3DREG_COLOROUT, + semantic.Index); + } + else if (emit->key.fkey.write_color0_to_n_cbufs) { + /* We'll write color output [0] to all render targets. + * Prepare all the output registers here, but only when the + * semantic.Index == 0 so we don't do this more than once. + */ + if (semantic.Index == 0) { + unsigned i; + for (i = 0; i < emit->key.fkey.write_color0_to_n_cbufs; i++) { + emit->output_map[i] = dst_register(SVGA3DREG_TEMP, + emit->nr_hw_temp++); + emit->temp_color_output[i] = emit->output_map[i]; + emit->true_color_output[i] = dst_register(SVGA3DREG_COLOROUT, + i); + } + } + } + else { + emit->output_map[idx] = + dst_register(SVGA3DREG_COLOROUT, semantic.Index); + } } else { emit->output_map[idx] = dst_register( SVGA3DREG_COLOROUT, diff --git a/src/gallium/drivers/svga/svga_tgsi_insn.c b/src/gallium/drivers/svga/svga_tgsi_insn.c index 21435462293..ce00da6fc0b 100644 --- a/src/gallium/drivers/svga/svga_tgsi_insn.c +++ b/src/gallium/drivers/svga/svga_tgsi_insn.c @@ -3074,6 +3074,15 @@ emit_ps_postamble(struct svga_shader_emitter *emit) one )) return FALSE; } + else if (emit->unit == PIPE_SHADER_FRAGMENT && + i < emit->key.fkey.write_color0_to_n_cbufs) { + /* Write temp color output [0] to true output [i] */ + if (!submit_op1(emit, inst_token(SVGA3DOP_MOV), + emit->true_color_output[i], + src(emit->temp_color_output[0]))) { + return FALSE; + } + } else { if (!submit_op1( emit, inst_token(SVGA3DOP_MOV),