[Mesa-dev] [PATCH 3/3] svga: implement TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS

Brian Paul brianp at vmware.com
Mon Jan 20 12:04:47 PST 2014


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.
---
 src/gallium/drivers/svga/svga_state_fs.c       |    8 +++++
 src/gallium/drivers/svga/svga_tgsi.h           |    1 +
 src/gallium/drivers/svga/svga_tgsi_decl_sm30.c |   37 +++++++++++++++++++-----
 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 51d0eb5..1e9fb43 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 0e06dbf..591dd6a 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 e0a30a5..137afd6 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 2143546..ce00da6 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),
-- 
1.7.10.4



More information about the mesa-dev mailing list