svga: Share one texcoord between depth and fog
authorJakob Bornecrantz <jakob@vmware.com>
Thu, 7 Apr 2011 16:23:48 +0000 (17:23 +0100)
committerBrian Paul <brianp@vmware.com>
Fri, 23 Sep 2011 13:58:46 +0000 (07:58 -0600)
src/gallium/drivers/svga/svga_tgsi_decl_sm30.c
src/gallium/drivers/svga/svga_tgsi_emit.h
src/gallium/drivers/svga/svga_tgsi_insn.c

index 3b70a3a7635200c961f2553d946e5a473000d65d..ed4b000e4f32a913c13417175f69767abd9d273e 100644 (file)
@@ -58,8 +58,7 @@ static boolean translate_vs_ps_semantic( struct tgsi_declaration_semantic semant
       *usage = SVGA3D_DECLUSAGE_PSIZE;
       break;
    case TGSI_SEMANTIC_GENERIC:   
-      *idx = semantic.Index + 2; /* texcoord[0] is reserved for fog,
-                                    texcoord[1] is reserved for position */
+      *idx = semantic.Index + 1; /* texcoord[0] is reserved for fog & position */
       *usage = SVGA3D_DECLUSAGE_TEXCOORD;
       break;
    case TGSI_SEMANTIC_NORMAL:    
@@ -113,6 +112,28 @@ static boolean emit_vface_decl( struct svga_shader_emitter *emit )
    return TRUE;
 }
 
+static boolean
+ps30_input_emit_depth_fog( struct svga_shader_emitter *emit,
+                           struct src_register *out )
+{
+   struct src_register reg;
+
+
+   if (emit->emitted_depth_fog) {
+      *out = emit->ps_depth_fog;
+      return TRUE;
+   }
+
+   reg = src_register( SVGA3DREG_INPUT,
+                       emit->ps30_input_count++ );
+
+   *out = emit->ps_depth_fog = reg;
+
+   emit->emitted_depth_fog = TRUE;
+
+   return emit_decl( emit, dst( reg ), SVGA3D_DECLUSAGE_TEXCOORD, 0 );
+}
+
 static boolean ps30_input( struct svga_shader_emitter *emit,
                            struct tgsi_declaration_semantic semantic,
                            unsigned idx )
@@ -135,16 +156,18 @@ static boolean ps30_input( struct svga_shader_emitter *emit,
       if (emit->info.reads_z) {
          emit->ps_temp_pos = dst_register( SVGA3DREG_TEMP,
                                            emit->nr_hw_temp );
-         emit->ps_depth_pos = src_register( SVGA3DREG_INPUT,
-                                            emit->ps30_input_count++ );
 
          emit->input_map[idx] = src_register( SVGA3DREG_TEMP,
                                               emit->nr_hw_temp );
          emit->nr_hw_temp++;
 
-         if (!emit_decl( emit, dst( emit->ps_depth_pos ),
-                         SVGA3D_DECLUSAGE_TEXCOORD, 1 ))
+         if (!ps30_input_emit_depth_fog( emit, &emit->ps_depth_pos ))
             return FALSE;
+
+         emit->ps_depth_pos.base.swizzle = TRANSLATE_SWIZZLE( TGSI_SWIZZLE_Z,
+                                                              TGSI_SWIZZLE_Z,
+                                                              TGSI_SWIZZLE_Z,
+                                                              TGSI_SWIZZLE_W );
       }
       else {
          emit->input_map[idx] = emit->ps_true_pos;
@@ -189,6 +212,20 @@ static boolean ps30_input( struct svga_shader_emitter *emit,
       emit->internal_frontface_idx = idx;
       return TRUE;
    }
+   else if (semantic.Name == TGSI_SEMANTIC_FOG) {
+
+      assert(semantic.Index == 0);
+
+      if (!ps30_input_emit_depth_fog( emit, &emit->input_map[idx] ))
+         return FALSE;
+
+      emit->input_map[idx].base.swizzle = TRANSLATE_SWIZZLE( TGSI_SWIZZLE_X,
+                                                             TGSI_SWIZZLE_X,
+                                                             TGSI_SWIZZLE_X,
+                                                             TGSI_SWIZZLE_X );
+
+      return TRUE;
+   }
    else {
 
       if (!translate_vs_ps_semantic( semantic, &usage, &index ))
@@ -289,6 +326,25 @@ static boolean vs30_input( struct svga_shader_emitter *emit,
    return TRUE;
 }
 
+static boolean vs30_output_emit_depth_fog( struct svga_shader_emitter *emit,
+                                           SVGA3dShaderDestToken *out )
+{
+   SVGA3dShaderDestToken reg;
+
+   if (emit->emitted_depth_fog) {
+      *out = emit->vs_depth_fog;
+      return TRUE;
+   }
+
+   reg = dst_register( SVGA3DREG_OUTPUT, emit->vs30_output_count++ );
+
+   *out = emit->vs_depth_fog = reg;
+
+   emit->emitted_depth_fog = TRUE;
+
+   return emit_decl( emit, reg, SVGA3D_DECLUSAGE_TEXCOORD, 0 );
+}
+
 /* VS3.0 outputs have proper declarations and semantic info for
  * matching against PS inputs.
  */
@@ -318,13 +374,11 @@ static boolean vs30_output( struct svga_shader_emitter *emit,
                                             emit->nr_hw_temp++ );
       emit->temp_pos = emit->output_map[idx];
       emit->true_pos = dcl.dst;
+
       /* Grab an extra output for the depth output */
-      emit->depth_pos = dst_register( SVGA3DREG_OUTPUT,
-                                      emit->vs30_output_count++ );
-      emit->info.num_outputs++;
+      if (!vs30_output_emit_depth_fog( emit, &emit->depth_pos ))
+         return FALSE;
 
-      emit_decl( emit, emit->depth_pos,
-                 SVGA3D_DECLUSAGE_TEXCOORD, 1 );
    }
    else if (semantic.Name == TGSI_SEMANTIC_PSIZE) {
       emit->output_map[idx] = dst_register( SVGA3DREG_TEMP,
@@ -339,6 +393,18 @@ static boolean vs30_output( struct svga_shader_emitter *emit,
 
       emit->true_psiz = dcl.dst;
    }
+   else if (semantic.Name == TGSI_SEMANTIC_FOG) {
+      /*
+       * Fog is shared with depth.
+       * So we need to decrement out_count since emit_depth_fog will increment it.
+       */
+      emit->vs30_output_count--;
+
+      if (!vs30_output_emit_depth_fog( emit, &emit->output_map[idx] ))
+         return FALSE;
+
+      return TRUE;
+   }
    else {
       emit->output_map[idx] = dcl.dst;
    }
index 21bb8da44f8ffbc120007a5ce0f74f0dfeef0bae..b1300dc8ecdd4738132b95fce59161ec3d48f9f8 100644 (file)
@@ -101,15 +101,22 @@ struct svga_shader_emitter
    SVGA3dShaderDestToken output_map[PIPE_MAX_ATTRIBS];
 
    boolean ps_reads_pos;
+   boolean emitted_depth_fog;
    struct src_register ps_true_pos;
    struct src_register ps_depth_pos;
    SVGA3dShaderDestToken ps_temp_pos;
 
+   /* shared input for depth and fog */
+   struct src_register ps_depth_fog;
+
    struct src_register imm_0055;
    SVGA3dShaderDestToken temp_pos;
    SVGA3dShaderDestToken true_pos;
    SVGA3dShaderDestToken depth_pos;
 
+   /* shared output for depth and fog */
+   SVGA3dShaderDestToken vs_depth_fog;
+
    SVGA3dShaderDestToken temp_col[PIPE_MAX_COLOR_BUFS];
    SVGA3dShaderDestToken true_col[PIPE_MAX_COLOR_BUFS];
 
index e6ec5966eaa255197fc411b31cce3b224fdd0e26..10688accdaaabcfc44b603a1c376e177cda0c5f1 100644 (file)
@@ -2692,7 +2692,7 @@ static boolean emit_vs_postamble( struct svga_shader_emitter *emit )
       /* Also write to depth value */
       if (!submit_op3( emit,
                        inst_token(SVGA3DOP_MAD),
-                       writemask(depth, TGSI_WRITEMASK_XYZ),
+                       writemask(depth, TGSI_WRITEMASK_Z),
                        swizzle(src(temp_pos), 3, 3, 3, 3),
                        prescale_trans,
                        src(temp_pos) ))
@@ -2725,7 +2725,7 @@ static boolean emit_vs_postamble( struct svga_shader_emitter *emit )
       /* Move the manipulated depth into the extra texcoord reg */
       if (!submit_op1( emit,
                        inst_token(SVGA3DOP_MOV),
-                       depth,
+                       writemask(depth, TGSI_WRITEMASK_ZW),
                        src(temp_pos) ))
          return FALSE;
    }