boolean native_integers;
boolean inline_subroutines;
- boolean lower_preds;
boolean want_texcoord;
boolean shift_wpos;
boolean wpos_is_sysval;
tx->regs.a0 = ureg_DECL_temporary(tx->ureg);
}
-static inline void
-tx_pred_alloc(struct shader_translator *tx, INT idx)
-{
- assert(idx == 0);
- if (ureg_dst_is_undef(tx->regs.p))
- tx->regs.p = ureg_DECL_predicate(tx->ureg);
-}
-
/* NOTE: It's not very clear on which ps1.1-ps1.3 instructions
* the projection should be applied on the texture. It doesn't
* apply on texkill.
}
break;
case D3DSPR_PREDICATE:
- assert(!param->rel);
- tx_pred_alloc(tx, param->idx);
- src = ureg_src(tx->regs.p);
+ assert(!"D3DSPR_PREDICATE");
break;
case D3DSPR_SAMPLER:
assert(param->mod == NINED3DSPSM_NONE);
if (tx->shift_wpos) {
/* TODO: do this only once */
struct ureg_dst wpos = tx_scratch(tx);
- ureg_SUB(ureg, wpos, tx->regs.vPos,
- ureg_imm4f(ureg, 0.5f, 0.5f, 0.0f, 0.0f));
+ ureg_ADD(ureg, wpos, tx->regs.vPos,
+ ureg_imm4f(ureg, -0.5f, -0.5f, 0.0f, 0.0f));
src = ureg_src(wpos);
} else {
src = tx->regs.vPos;
case NINED3DSPSM_DW:
tmp = tx_scratch(tx);
/* NOTE: app is not allowed to read w with this modifier */
- ureg_RCP(ureg, ureg_writemask(tmp, NINED3DSP_WRITEMASK_3), src);
+ ureg_RCP(ureg, ureg_writemask(tmp, NINED3DSP_WRITEMASK_3), ureg_scalar(src, TGSI_SWIZZLE_W));
ureg_MUL(ureg, tmp, src, ureg_swizzle(ureg_src(tmp), NINE_SWIZZLE4(W,W,W,W)));
src = ureg_src(tmp);
break;
case NINED3DSPSM_DZ:
tmp = tx_scratch(tx);
/* NOTE: app is not allowed to read z with this modifier */
- ureg_RCP(ureg, ureg_writemask(tmp, NINED3DSP_WRITEMASK_2), src);
+ ureg_RCP(ureg, ureg_writemask(tmp, NINED3DSP_WRITEMASK_2), ureg_scalar(src, TGSI_SWIZZLE_Z));
ureg_MUL(ureg, tmp, src, ureg_swizzle(ureg_src(tmp), NINE_SWIZZLE4(Z,Z,Z,Z)));
src = ureg_src(tmp);
break;
break;
case NINED3DSPSM_BIAS:
tmp = tx_scratch(tx);
- ureg_SUB(ureg, tmp, src, ureg_imm1f(ureg, 0.5f));
+ ureg_ADD(ureg, tmp, src, ureg_imm1f(ureg, -0.5f));
src = ureg_src(tmp);
break;
case NINED3DSPSM_BIASNEG:
tmp = tx_scratch(tx);
- ureg_SUB(ureg, tmp, ureg_imm1f(ureg, 0.5f), src);
+ ureg_ADD(ureg, tmp, ureg_imm1f(ureg, 0.5f), ureg_negate(src));
src = ureg_src(tmp);
break;
case NINED3DSPSM_NOT:
/* fall through */
case NINED3DSPSM_COMP:
tmp = tx_scratch(tx);
- ureg_SUB(ureg, tmp, ureg_imm1f(ureg, 1.0f), src);
+ ureg_ADD(ureg, tmp, ureg_imm1f(ureg, 1.0f), ureg_negate(src));
src = ureg_src(tmp);
break;
case NINED3DSPSM_DZ:
dst = tx->regs.oDepth; /* XXX: must write .z component */
break;
case D3DSPR_PREDICATE:
- assert(!param->rel);
- tx_pred_alloc(tx, param->idx);
- dst = tx->regs.p;
+ assert(!"D3DSPR_PREDICATE");
break;
case D3DSPR_TEMPFLOAT16:
DBG("unhandled D3DSPR: %u\n", param->file);
static HRESULT
NineTranslateInstruction_Generic(struct shader_translator *);
+DECL_SPECIAL(NOP)
+{
+ /* Nothing to do. NOP was used to avoid hangs
+ * with very old d3d drivers. */
+ return D3D_OK;
+}
+
+DECL_SPECIAL(SUB)
+{
+ struct ureg_program *ureg = tx->ureg;
+ struct ureg_dst dst = tx_dst_param(tx, &tx->insn.dst[0]);
+ struct ureg_src src0 = tx_src_param(tx, &tx->insn.src[0]);
+ struct ureg_src src1 = tx_src_param(tx, &tx->insn.src[1]);
+
+ ureg_ADD(ureg, dst, src0, ureg_negate(src1));
+ return D3D_OK;
+}
+
+DECL_SPECIAL(ABS)
+{
+ struct ureg_program *ureg = tx->ureg;
+ struct ureg_dst dst = tx_dst_param(tx, &tx->insn.dst[0]);
+ struct ureg_src src = tx_src_param(tx, &tx->insn.src[0]);
+
+ ureg_MOV(ureg, dst, ureg_abs(src));
+ return D3D_OK;
+}
+
+DECL_SPECIAL(XPD)
+{
+ struct ureg_program *ureg = tx->ureg;
+ struct ureg_dst dst = tx_dst_param(tx, &tx->insn.dst[0]);
+ struct ureg_src src0 = tx_src_param(tx, &tx->insn.src[0]);
+ struct ureg_src src1 = tx_src_param(tx, &tx->insn.src[1]);
+
+ ureg_MUL(ureg, ureg_writemask(dst, TGSI_WRITEMASK_XYZ),
+ ureg_swizzle(src0, TGSI_SWIZZLE_Y, TGSI_SWIZZLE_Z,
+ TGSI_SWIZZLE_X, 0),
+ ureg_swizzle(src1, TGSI_SWIZZLE_Z, TGSI_SWIZZLE_X,
+ TGSI_SWIZZLE_Y, 0));
+ ureg_MAD(ureg, ureg_writemask(dst, TGSI_WRITEMASK_XYZ),
+ ureg_swizzle(src0, TGSI_SWIZZLE_Z, TGSI_SWIZZLE_X,
+ TGSI_SWIZZLE_Y, 0),
+ ureg_negate(ureg_swizzle(src1, TGSI_SWIZZLE_Y,
+ TGSI_SWIZZLE_Z, TGSI_SWIZZLE_X, 0)),
+ ureg_src(dst));
+ ureg_MOV(ureg, ureg_writemask(dst, TGSI_WRITEMASK_W),
+ ureg_imm1f(ureg, 1));
+ return D3D_OK;
+}
+
DECL_SPECIAL(M4x4)
{
return NineTranslateInstruction_Mkxn(tx, 4, 4);
struct ureg_dst tmp = ureg_writemask(tx_scratch(tx), TGSI_WRITEMASK_X);
src[0] = tx_src_param(tx, &tx->insn.src[0]);
src[1] = tx_src_param(tx, &tx->insn.src[1]);
- ureg_insn(tx->ureg, cmp_op, &tmp, 1, src, 2);
+ ureg_insn(tx->ureg, cmp_op, &tmp, 1, src, 2, 0);
ureg_IF(tx->ureg, ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_X), tx_cond(tx));
return D3D_OK;
}
struct ureg_dst tmp = ureg_writemask(tx_scratch(tx), TGSI_WRITEMASK_X);
src[0] = tx_src_param(tx, &tx->insn.src[0]);
src[1] = tx_src_param(tx, &tx->insn.src[1]);
- ureg_insn(tx->ureg, cmp_op, &tmp, 1, src, 2);
+ ureg_insn(tx->ureg, cmp_op, &tmp, 1, src, 2, 0);
ureg_IF(tx->ureg, ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_X), tx_cond(tx));
ureg_BRK(tx->ureg);
tx_endcond(tx);
ureg_MUL(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_X), ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_X), ureg_imm1f(ureg, 2.0f));
ureg_MUL(ureg, tmp, ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_X), ureg_src(dst));
/* at this step tmp.xyz = 2 * (N.E / N.N) * N */
- ureg_SUB(ureg, tmp, ureg_src(tmp), E);
+ ureg_ADD(ureg, tmp, ureg_src(tmp), ureg_negate(E));
ureg_TEX(ureg, dst, ps1x_sampler_type(tx->info, m + 2), ureg_src(tmp), sample);
return D3D_OK;
ureg_MUL(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_X), ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_X), ureg_imm1f(ureg, 2.0f));
ureg_MUL(ureg, tmp, ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_X), ureg_src(dst));
/* at this step tmp.xyz = 2 * (N.E / N.N) * N */
- ureg_SUB(ureg, tmp, ureg_src(tmp), ureg_src(E));
+ ureg_ADD(ureg, tmp, ureg_src(tmp), ureg_negate(ureg_src(E)));
ureg_TEX(ureg, dst, ps1x_sampler_type(tx->info, m + 2), ureg_src(tmp), sample);
break;
default:
struct sm1_op_info inst_table[] =
{
- _OPI(NOP, NOP, V(0,0), V(3,0), V(0,0), V(3,0), 0, 0, NULL), /* 0 */
+ _OPI(NOP, NOP, V(0,0), V(3,0), V(0,0), V(3,0), 0, 0, SPECIAL(NOP)), /* 0 */
_OPI(MOV, MOV, V(0,0), V(3,0), V(0,0), V(3,0), 1, 1, NULL),
_OPI(ADD, ADD, V(0,0), V(3,0), V(0,0), V(3,0), 1, 2, NULL), /* 2 */
- _OPI(SUB, SUB, V(0,0), V(3,0), V(0,0), V(3,0), 1, 2, NULL), /* 3 */
+ _OPI(SUB, NOP, V(0,0), V(3,0), V(0,0), V(3,0), 1, 2, SPECIAL(SUB)), /* 3 */
_OPI(MAD, MAD, V(0,0), V(3,0), V(0,0), V(3,0), 1, 3, NULL), /* 4 */
_OPI(MUL, MUL, V(0,0), V(3,0), V(0,0), V(3,0), 1, 2, NULL), /* 5 */
_OPI(RCP, RCP, V(0,0), V(3,0), V(0,0), V(3,0), 1, 1, NULL), /* 6 */
_OPI(DCL, NOP, V(0,0), V(3,0), V(0,0), V(3,0), 0, 0, SPECIAL(DCL)),
_OPI(POW, POW, V(0,0), V(3,0), V(0,0), V(3,0), 1, 2, SPECIAL(POW)),
- _OPI(CRS, XPD, V(0,0), V(3,0), V(0,0), V(3,0), 1, 2, NULL), /* XXX: .w */
+ _OPI(CRS, NOP, V(0,0), V(3,0), V(0,0), V(3,0), 1, 2, SPECIAL(XPD)), /* XXX: .w */
_OPI(SGN, SSG, V(2,0), V(3,0), V(0,0), V(0,0), 1, 3, SPECIAL(SGN)), /* ignore src1,2 */
- _OPI(ABS, ABS, V(0,0), V(3,0), V(0,0), V(3,0), 1, 1, NULL),
+ _OPI(ABS, NOP, V(0,0), V(3,0), V(0,0), V(3,0), 1, 1, SPECIAL(ABS)),
_OPI(NRM, NOP, V(0,0), V(3,0), V(0,0), V(3,0), 1, 1, SPECIAL(NRM)), /* NRM doesn't fit */
_OPI(SINCOS, SCS, V(2,0), V(2,1), V(2,0), V(2,1), 1, 3, SPECIAL(SINCOS)),
_OPI(ELSE, ELSE, V(2,0), V(3,0), V(2,1), V(3,0), 0, 0, SPECIAL(ELSE)),
_OPI(ENDIF, ENDIF, V(2,0), V(3,0), V(2,1), V(3,0), 0, 0, SPECIAL(ENDIF)),
_OPI(BREAK, BRK, V(2,1), V(3,0), V(2,1), V(3,0), 0, 0, NULL),
- _OPI(BREAKC, BREAKC, V(2,1), V(3,0), V(2,1), V(3,0), 0, 2, SPECIAL(BREAKC)),
+ _OPI(BREAKC, NOP, V(2,1), V(3,0), V(2,1), V(3,0), 0, 2, SPECIAL(BREAKC)),
/* we don't write to the address register, but a normal register (copied
* when needed to the address register), thus we don't use ARR */
_OPI(MOVA, MOV, V(2,0), V(3,0), V(0,0), V(0,0), 1, 1, NULL),
ureg_insn(tx->ureg, tx->insn.info->opcode,
dst, tx->insn.ndst,
- src, tx->insn.nsrc);
+ src, tx->insn.nsrc, 0);
return D3D_OK;
}
for (i = 0; i < ARRAY_SIZE(tx->regs.vT); ++i)
tx->regs.vT[i] = ureg_src_undef();
- for (i = 0; i < ARRAY_SIZE(tx->lconsti); ++i)
- tx->lconsti[i].idx = -1;
- for (i = 0; i < ARRAY_SIZE(tx->lconstb); ++i)
- tx->lconstb[i].idx = -1;
-
sm1_read_version(tx);
info->version = (tx->version.major << 4) | tx->version.minor;
if (tx->info->fog_mode == D3DFOG_LINEAR) {
fog_end = NINE_CONSTANT_SRC_SWIZZLE(33, X);
fog_coeff = NINE_CONSTANT_SRC_SWIZZLE(33, Y);
- ureg_SUB(ureg, fog_factor, fog_end, depth);
+ ureg_ADD(ureg, fog_factor, fog_end, ureg_negate(depth));
ureg_MUL(ureg, ureg_saturate(fog_factor), tx_src_scalar(fog_factor), fog_coeff);
} else if (tx->info->fog_mode == D3DFOG_EXP) {
fog_density = NINE_CONSTANT_SRC_SWIZZLE(33, X);
screen, info->type, PIPE_SHADER_CAP_##n)
HRESULT
-nine_translate_shader(struct NineDevice9 *device, struct nine_shader_info *info)
+nine_translate_shader(struct NineDevice9 *device, struct nine_shader_info *info, struct pipe_context *pipe)
{
struct shader_translator *tx;
HRESULT hr = D3D_OK;
const unsigned processor = info->type;
struct pipe_screen *screen = info->process_vertices ? device->screen_sw : device->screen;
- struct pipe_context *pipe = info->process_vertices ? device->pipe_sw : device->pipe;
user_assert(processor != ~0, D3DERR_INVALIDCALL);
tx->native_integers = GET_SHADER_CAP(INTEGERS);
tx->inline_subroutines = !GET_SHADER_CAP(SUBROUTINES);
- tx->lower_preds = !GET_SHADER_CAP(MAX_PREDS);
tx->want_texcoord = GET_CAP(TGSI_TEXCOORD);
tx->shift_wpos = !GET_CAP(TGSI_FS_COORD_PIXEL_CENTER_INTEGER);
tx->texcoord_sn = tx->want_texcoord ?
ureg_property(tx->ureg, TGSI_PROPERTY_FS_COORD_PIXEL_CENTER, TGSI_FS_COORD_PIXEL_CENTER_INTEGER);
}
+ if (GET_CAP(TGSI_MUL_ZERO_WINS))
+ ureg_property(tx->ureg, TGSI_PROPERTY_MUL_ZERO_WINS, 1);
+
while (!sm1_parse_eof(tx) && !tx->failure)
sm1_parse_instruction(tx);
tx->parse++; /* for byte_size */
ureg_DECL_constant2D(tx->ureg, 0, 2, 4); /* Viewport data */
if (debug_get_bool_option("NINE_TGSI_DUMP", FALSE)) {
- unsigned count;
- const struct tgsi_token *toks = ureg_get_tokens(tx->ureg, &count);
+ const struct tgsi_token *toks = ureg_get_tokens(tx->ureg, NULL);
tgsi_dump(toks, 0);
ureg_free_tokens(toks);
}