diff options
-rw-r--r-- | src/gallium/drivers/svga/svga_tgsi_decl_sm30.c | 40 | ||||
-rw-r--r-- | src/gallium/drivers/svga/svga_tgsi_emit.h | 7 | ||||
-rw-r--r-- | src/gallium/drivers/svga/svga_tgsi_insn.c | 52 |
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; |