summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBrian Paul <[email protected]>2014-01-16 18:32:47 -0800
committerBrian Paul <[email protected]>2014-01-21 10:53:51 -0800
commitb9f68d927ea5e114b6019c807ce65674d9fa1d1d (patch)
tree66516d8234dc8bbf843ddc500d047bbeed94964c /src
parent384fd64ab1533df8256600733a1fc8413af3514a (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')
-rw-r--r--src/gallium/drivers/svga/svga_state_fs.c8
-rw-r--r--src/gallium/drivers/svga/svga_tgsi.h1
-rw-r--r--src/gallium/drivers/svga/svga_tgsi_decl_sm30.c37
-rw-r--r--src/gallium/drivers/svga/svga_tgsi_insn.c9
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),