gallium: remove TGSI opcode BREAKC
[mesa.git] / src / gallium / state_trackers / nine / nine_shader.c
index 0f8bcdd7d7f30dd7bdb528389a27c198267fd184..50750cb547b796b40fc612c46e3b8fd2fc059152 100644 (file)
@@ -456,7 +456,6 @@ struct shader_translator
 
     boolean native_integers;
     boolean inline_subroutines;
-    boolean lower_preds;
     boolean want_texcoord;
     boolean shift_wpos;
     boolean wpos_is_sysval;
@@ -735,14 +734,6 @@ tx_addr_alloc(struct shader_translator *tx, INT idx)
         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.
@@ -984,9 +975,7 @@ tx_src_param(struct shader_translator *tx, const struct sm1_src_param *param)
         }
         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);
@@ -1082,8 +1071,8 @@ tx_src_param(struct shader_translator *tx, const struct sm1_src_param *param)
            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;
@@ -1127,14 +1116,14 @@ tx_src_param(struct shader_translator *tx, const struct sm1_src_param *param)
     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;
@@ -1161,12 +1150,12 @@ tx_src_param(struct shader_translator *tx, const struct sm1_src_param *param)
         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:
@@ -1179,7 +1168,7 @@ tx_src_param(struct shader_translator *tx, const struct sm1_src_param *param)
         /* 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:
@@ -1305,9 +1294,7 @@ _tx_dst_param(struct shader_translator *tx, const struct sm1_dst_param *param)
         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);
@@ -1573,6 +1560,57 @@ d3dsio_to_string( unsigned opcode )
 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);
@@ -1864,7 +1902,7 @@ DECL_SPECIAL(IFC)
     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;
 }
@@ -1882,7 +1920,7 @@ DECL_SPECIAL(BREAKC)
     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);
@@ -2524,7 +2562,7 @@ DECL_SPECIAL(TEXM3x3SPEC)
     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;
@@ -2663,7 +2701,7 @@ DECL_SPECIAL(TEXM3x3)
         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:
@@ -2863,10 +2901,10 @@ DECL_SPECIAL(COMMENT)
 
 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 */
@@ -2900,9 +2938,9 @@ struct sm1_op_info inst_table[] =
     _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)),
@@ -2916,7 +2954,7 @@ struct sm1_op_info inst_table[] =
     _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),
@@ -3014,7 +3052,7 @@ NineTranslateInstruction_Generic(struct shader_translator *tx)
 
     ureg_insn(tx->ureg, tx->insn.info->opcode,
               dst, tx->insn.ndst,
-              src, tx->insn.nsrc);
+              src, tx->insn.nsrc, 0);
     return D3D_OK;
 }
 
@@ -3361,11 +3399,6 @@ tx_ctor(struct shader_translator *tx, struct nine_shader_info *info)
     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;
@@ -3431,7 +3464,7 @@ shader_add_ps_fog_stage(struct shader_translator *tx, struct ureg_src src_col)
     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);
@@ -3462,13 +3495,12 @@ shader_add_ps_fog_stage(struct shader_translator *tx, struct ureg_src src_col)
       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);
 
@@ -3499,7 +3531,6 @@ nine_translate_shader(struct NineDevice9 *device, struct nine_shader_info *info)
 
     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 ?
@@ -3542,6 +3573,9 @@ nine_translate_shader(struct NineDevice9 *device, struct nine_shader_info *info)
             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 */
@@ -3680,8 +3714,7 @@ nine_translate_shader(struct NineDevice9 *device, struct nine_shader_info *info)
         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);
     }