summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/svga/svga_tgsi_decl_sm30.c40
-rw-r--r--src/gallium/drivers/svga/svga_tgsi_emit.h7
-rw-r--r--src/gallium/drivers/svga/svga_tgsi_insn.c52
3 files changed, 86 insertions, 13 deletions
diff --git a/src/gallium/drivers/svga/svga_tgsi_decl_sm30.c b/src/gallium/drivers/svga/svga_tgsi_decl_sm30.c
index 73102a72a83..6d6c7c27a44 100644
--- a/src/gallium/drivers/svga/svga_tgsi_decl_sm30.c
+++ b/src/gallium/drivers/svga/svga_tgsi_decl_sm30.c
@@ -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,
diff --git a/src/gallium/drivers/svga/svga_tgsi_emit.h b/src/gallium/drivers/svga/svga_tgsi_emit.h
index 63ef7f867a6..21bb8da44f8 100644
--- a/src/gallium/drivers/svga/svga_tgsi_emit.h
+++ b/src/gallium/drivers/svga/svga_tgsi_emit.h
@@ -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];
diff --git a/src/gallium/drivers/svga/svga_tgsi_insn.c b/src/gallium/drivers/svga/svga_tgsi_insn.c
index 99600cf5c00..ec1906eb619 100644
--- a/src/gallium/drivers/svga/svga_tgsi_insn.c
+++ b/src/gallium/drivers/svga/svga_tgsi_insn.c
@@ -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;