svga: Wip for passing depth in a texcoord
authorJakob Bornecrantz <jakob@vmware.com>
Fri, 25 Mar 2011 02:59:07 +0000 (02:59 +0000)
committerBrian Paul <brianp@vmware.com>
Fri, 23 Sep 2011 13:58:45 +0000 (07:58 -0600)
TODO: Can we pass this as the same texcoord as fog?

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 73102a72a8379910ac749d301cad4cfc4f4c2780..6d6c7c27a441f2d4869d177cb0c4b5e80b190bb3 100644 (file)
@@ -58,7 +58,8 @@ static boolean translate_vs_ps_semantic( struct tgsi_declaration_semantic semant
       *usage = SVGA3D_DECLUSAGE_PSIZE;
       break;
    case TGSI_SEMANTIC_GENERIC:   
-      *idx = semantic.Index + 1; /* texcoord[0] is reserved for fog */
+      *idx = semantic.Index + 2; /* texcoord[0] is reserved for fog,
+                                    texcoord[1] is reserved for position */
       *usage = SVGA3D_DECLUSAGE_TEXCOORD;
       break;
    case TGSI_SEMANTIC_NORMAL:    
@@ -120,17 +121,23 @@ static boolean ps30_input( struct svga_shader_emitter *emit,
    SVGA3dShaderDestToken reg;
 
    if (semantic.Name == TGSI_SEMANTIC_POSITION) {
-      emit->input_map[idx] = src_register( SVGA3DREG_MISCTYPE,
-                                           SVGA3DMISCREG_POSITION );
-
-      emit->input_map[idx].base.swizzle = TRANSLATE_SWIZZLE( TGSI_SWIZZLE_X,
-                                                             TGSI_SWIZZLE_Y,
-                                                             TGSI_SWIZZLE_Y,
-                                                             TGSI_SWIZZLE_Y );
-
-      reg = writemask( dst(emit->input_map[idx]),
-                       TGSI_WRITEMASK_XY );
-
+      emit->ps_true_pos = src_register( SVGA3DREG_MISCTYPE,
+                                        SVGA3DMISCREG_POSITION );
+      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++;
+
+      reg = writemask( dst(emit->ps_true_pos),
+                       TGSI_WRITEMASK_XYZW );
+
+      emit->ps_reads_pos = TRUE;
+      if (!emit_decl( emit, dst(emit->ps_depth_pos),
+                      SVGA3D_DECLUSAGE_TEXCOORD, 1 ))
+         return FALSE;
       return emit_decl( emit, reg, 0, 0 );
    }
    else if (emit->key.fkey.light_twoside &&
@@ -288,7 +295,7 @@ static boolean vs30_output( struct svga_shader_emitter *emit,
    if (!translate_vs_ps_semantic( semantic, &usage, &index ))
       return FALSE;
 
-   dcl.dst = dst_register( SVGA3DREG_OUTPUT, idx );
+   dcl.dst = dst_register( SVGA3DREG_OUTPUT, emit->vs30_output_count++ );
    dcl.usage = usage;
    dcl.index = index;
    dcl.values[0] |= 1<<31;
@@ -299,6 +306,13 @@ 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++;
+
+      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,
index 63ef7f867a64d5954f069ca06bef95867f82e19b..21bb8da44f8ffbc120007a5ce0f74f0dfeef0bae 100644 (file)
@@ -79,6 +79,7 @@ struct svga_shader_emitter
    int internal_frontface_idx;
 
    int ps30_input_count;
+   int vs30_output_count;
 
    int dynamic_branching_level;
 
@@ -99,9 +100,15 @@ struct svga_shader_emitter
    struct src_register input_map[PIPE_MAX_ATTRIBS];
    SVGA3dShaderDestToken output_map[PIPE_MAX_ATTRIBS];
 
+   boolean ps_reads_pos;
+   struct src_register ps_true_pos;
+   struct src_register ps_depth_pos;
+   SVGA3dShaderDestToken ps_temp_pos;
+
    struct src_register imm_0055;
    SVGA3dShaderDestToken temp_pos;
    SVGA3dShaderDestToken true_pos;
+   SVGA3dShaderDestToken depth_pos;
 
    SVGA3dShaderDestToken temp_col[PIPE_MAX_COLOR_BUFS];
    SVGA3dShaderDestToken true_col[PIPE_MAX_COLOR_BUFS];
index 99600cf5c0066f321ffc4f042f408f8a7bc4f220..ec1906eb6190905f5ca019adf03b0649acea9e84 100644 (file)
@@ -2550,6 +2550,34 @@ static boolean emit_ps_preamble( struct svga_shader_emitter *emit )
                return FALSE;
          }
       }
+   } else if (emit->ps_reads_pos) {
+      /*
+       * Assemble the position from various bits of inputs. Depth and W are
+       * passed in a texcoord this is due to D3D's vPos not hold Z or W.
+       * Also fixup the perspective interpolation.
+       *
+       * temp_pos.xy = vPos.xy
+       * temp_pos.w = rcp(texcoord1.w);
+       * temp_pos.z = texcoord1.z * temp_pos.w;
+       */
+      if (!submit_op1( emit,
+                       inst_token(SVGA3DOP_MOV),
+                       writemask( emit->ps_temp_pos, TGSI_WRITEMASK_XY ),
+                       emit->ps_true_pos ))
+         return FALSE;
+
+      if (!submit_op1( emit,
+                       inst_token(SVGA3DOP_RCP),
+                       writemask( emit->ps_temp_pos, TGSI_WRITEMASK_W ),
+                       scalar( emit->ps_depth_pos, TGSI_SWIZZLE_W ) ))
+         return FALSE;
+
+      if (!submit_op2( emit,
+                       inst_token(SVGA3DOP_MUL),
+                       writemask( emit->ps_temp_pos, TGSI_WRITEMASK_Z ),
+                       scalar( emit->ps_depth_pos, TGSI_SWIZZLE_Z ),
+                       scalar( src(emit->ps_temp_pos), TGSI_SWIZZLE_W ) ))
+         return FALSE;
    }
    
    return TRUE;
@@ -2628,6 +2656,7 @@ static boolean emit_vs_postamble( struct svga_shader_emitter *emit )
     */
    if (emit->key.vkey.need_prescale) {
       SVGA3dShaderDestToken temp_pos = emit->temp_pos;
+      SVGA3dShaderDestToken depth = emit->depth_pos;
       SVGA3dShaderDestToken pos = emit->true_pos;
       unsigned offset = emit->info.file_max[TGSI_FILE_CONSTANT] + 1;
       struct src_register prescale_scale = src_register( SVGA3DREG_CONST, 
@@ -2635,6 +2664,12 @@ static boolean emit_vs_postamble( struct svga_shader_emitter *emit )
       struct src_register prescale_trans = src_register( SVGA3DREG_CONST, 
                                                          offset + 1 ); 
 
+      if (!submit_op1( emit,
+                       inst_token(SVGA3DOP_MOV),
+                       writemask(depth, TGSI_WRITEMASK_W),
+                       scalar(src(temp_pos), TGSI_SWIZZLE_W) ))
+         return FALSE;
+
       /* MUL temp_pos.xyz,    temp_pos,      prescale.scale
        * MAD result.position, temp_pos.wwww, prescale.trans, temp_pos
        *   --> Note that prescale.trans.w == 0
@@ -2653,9 +2688,19 @@ static boolean emit_vs_postamble( struct svga_shader_emitter *emit )
                        prescale_trans,
                        src(temp_pos)))
          return FALSE;
+
+      /* Also write to depth value */
+      if (!submit_op3( emit,
+                       inst_token(SVGA3DOP_MAD),
+                       writemask(depth, TGSI_WRITEMASK_XYZ),
+                       swizzle(src(temp_pos), 3, 3, 3, 3),
+                       prescale_trans,
+                       src(temp_pos) ))
+         return FALSE;
    }
    else {
       SVGA3dShaderDestToken temp_pos = emit->temp_pos;
+      SVGA3dShaderDestToken depth = emit->depth_pos;
       SVGA3dShaderDestToken pos = emit->true_pos;
       struct src_register imm_0055 = emit->imm_0055;
 
@@ -2676,6 +2721,13 @@ static boolean emit_vs_postamble( struct svga_shader_emitter *emit )
                        pos,
                        src(temp_pos) ))
          return FALSE;
+
+      /* Move the manipulated depth into the extra texcoord reg */
+      if (!submit_op1( emit,
+                       inst_token(SVGA3DOP_MOV),
+                       depth,
+                       src(temp_pos) ))
+         return FALSE;
    }
 
    return TRUE;