diff options
author | Brian Paul <[email protected]> | 2014-01-16 18:32:47 -0800 |
---|---|---|
committer | Brian Paul <[email protected]> | 2014-01-21 10:53:51 -0800 |
commit | b9f68d927ea5e114b6019c807ce65674d9fa1d1d (patch) | |
tree | 66516d8234dc8bbf843ddc500d047bbeed94964c /src/gallium | |
parent | 384fd64ab1533df8256600733a1fc8413af3514a (diff) |
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 <[email protected]>
Diffstat (limited to 'src/gallium')
-rw-r--r-- | src/gallium/drivers/svga/svga_state_fs.c | 8 | ||||
-rw-r--r-- | src/gallium/drivers/svga/svga_tgsi.h | 1 | ||||
-rw-r--r-- | src/gallium/drivers/svga/svga_tgsi_decl_sm30.c | 37 | ||||
-rw-r--r-- | src/gallium/drivers/svga/svga_tgsi_insn.c | 9 |
4 files changed, 47 insertions, 8 deletions
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), |