tgsi/ureg: add support for output array declarations
[mesa.git] / src / gallium / state_trackers / nine / nine_shader.c
index 2ba625ebf716a3b00d225d615e2eda5a13b83641..22a58825f78d649820dc42e1cd820f34a1dfc20a 100644 (file)
@@ -27,6 +27,7 @@
 #include "nine_debug.h"
 #include "nine_state.h"
 
+#include "util/macros.h"
 #include "util/u_memory.h"
 #include "util/u_inlines.h"
 #include "pipe/p_shader_tokens.h"
@@ -1097,7 +1098,7 @@ _tx_dst_param(struct shader_translator *tx, const struct sm1_dst_param *param)
         if (ureg_dst_is_undef(tx->regs.oDepth))
            tx->regs.oDepth =
               ureg_DECL_output_masked(tx->ureg, TGSI_SEMANTIC_POSITION, 0,
-                                      TGSI_WRITEMASK_Z);
+                                      TGSI_WRITEMASK_Z, 0, 1);
         dst = tx->regs.oDepth; /* XXX: must write .z component */
         break;
     case D3DSPR_PREDICATE:
@@ -1965,7 +1966,7 @@ DECL_SPECIAL(DCL)
                 tx->info->position_t = TRUE;
             assert(sem.reg.idx < Elements(tx->regs.o));
             tx->regs.o[sem.reg.idx] = ureg_DECL_output_masked(
-                ureg, tgsi.Name, tgsi.Index, sem.reg.mask);
+                ureg, tgsi.Name, tgsi.Index, sem.reg.mask, 0, 1);
 
             if (tgsi.Name == TGSI_SEMANTIC_PSIZE)
                 tx->regs.oPts = tx->regs.o[sem.reg.idx];
@@ -1978,12 +1979,13 @@ DECL_SPECIAL(DCL)
                 ureg, tgsi.Name, tgsi.Index,
                 nine_tgsi_to_interp_mode(&tgsi),
                 0, /* cylwrap */
-                sem.reg.mod & NINED3DSPDM_CENTROID);
+                sem.reg.mod & NINED3DSPDM_CENTROID, 0, 1);
         } else
         if (!is_input && 0) { /* declare in COLOROUT/DEPTHOUT case */
             /* FragColor or FragDepth */
             assert(sem.reg.mask != 0);
-            ureg_DECL_output_masked(ureg, tgsi.Name, tgsi.Index, sem.reg.mask);
+            ureg_DECL_output_masked(ureg, tgsi.Name, tgsi.Index, sem.reg.mask,
+                                    0, 1);
         }
     }
     return D3D_OK;
@@ -2040,6 +2042,23 @@ DECL_SPECIAL(LOG)
     return D3D_OK;
 }
 
+DECL_SPECIAL(LIT)
+{
+    struct ureg_program *ureg = tx->ureg;
+    struct ureg_dst tmp = tx_scratch(tx);
+    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_LIT(ureg, tmp, src);
+    /* d3d9 LIT is the same than gallium LIT. One difference is that d3d9
+     * states that dst.z is 0 when src.y <= 0. Gallium definition can assign
+     * it 0^0 if src.w=0, which value is driver dependent. */
+    ureg_CMP(ureg, ureg_writemask(dst, TGSI_WRITEMASK_Z),
+             ureg_negate(ureg_scalar(src, TGSI_SWIZZLE_Y)),
+             ureg_src(tmp), ureg_imm1f(ureg, 0.0f));
+    ureg_MOV(ureg, ureg_writemask(dst, TGSI_WRITEMASK_XYW), ureg_src(tmp));
+    return D3D_OK;
+}
+
 DECL_SPECIAL(NRM)
 {
     struct ureg_program *ureg = tx->ureg;
@@ -2294,7 +2313,8 @@ DECL_SPECIAL(TEXM3x2DEPTH)
     ureg_CMP(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_X), ureg_negate(ureg_abs(ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_Y))),
              ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_X), ureg_imm1f(ureg, 1.0f));
     /* replace the depth for depth testing with the result */
-    tx->regs.oDepth = ureg_DECL_output_masked(ureg, TGSI_SEMANTIC_POSITION, 0, TGSI_WRITEMASK_Z);
+    tx->regs.oDepth = ureg_DECL_output_masked(ureg, TGSI_SEMANTIC_POSITION, 0,
+                                              TGSI_WRITEMASK_Z, 0, 1);
     ureg_MOV(ureg, tx->regs.oDepth, ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_X));
     /* note that we write nothing to the destination, since it's disallowed to use it afterward */
     return D3D_OK;
@@ -2392,7 +2412,8 @@ DECL_SPECIAL(TEXDEPTH)
     ureg_CMP(ureg, ureg_writemask(r5, TGSI_WRITEMASK_X), ureg_negate(ureg_abs(r5g)),
              r5r, ureg_imm1f(ureg, 1.0f));
     /* replace the depth for depth testing with the result */
-    tx->regs.oDepth = ureg_DECL_output_masked(ureg, TGSI_SEMANTIC_POSITION, 0, TGSI_WRITEMASK_Z);
+    tx->regs.oDepth = ureg_DECL_output_masked(ureg, TGSI_SEMANTIC_POSITION, 0,
+                                              TGSI_WRITEMASK_Z, 0, 1);
     ureg_MOV(ureg, tx->regs.oDepth, r5r);
 
     return D3D_OK;
@@ -2476,8 +2497,8 @@ DECL_SPECIAL(TEXLDD)
         tx_src_param(tx, &tx->insn.src[2]),
         tx_src_param(tx, &tx->insn.src[3])
     };
-    assert(tx->insn.src[3].idx >= 0 &&
-           tx->insn.src[3].idx < Elements(tx->sampler_targets));
+    assert(tx->insn.src[1].idx >= 0 &&
+           tx->insn.src[1].idx < Elements(tx->sampler_targets));
     target = tx->sampler_targets[tx->insn.src[1].idx];
 
     ureg_TXD(tx->ureg, dst, target, src[0], src[2], src[3], src[1]);
@@ -2492,8 +2513,8 @@ DECL_SPECIAL(TEXLDL)
        tx_src_param(tx, &tx->insn.src[0]),
        tx_src_param(tx, &tx->insn.src[1])
     };
-    assert(tx->insn.src[3].idx >= 0 &&
-           tx->insn.src[3].idx < Elements(tx->sampler_targets));
+    assert(tx->insn.src[1].idx >= 0 &&
+           tx->insn.src[1].idx < Elements(tx->sampler_targets));
     target = tx->sampler_targets[tx->insn.src[1].idx];
 
     ureg_TXL(tx->ureg, dst, target, src[0], src[1]);
@@ -2543,7 +2564,7 @@ struct sm1_op_info inst_table[] =
     _OPI(SGE, SGE, V(0,0), V(3,0), V(0,0), V(3,0), 1, 2, NULL), /* 13 */
     _OPI(EXP, EX2, V(0,0), V(3,0), V(0,0), V(3,0), 1, 1, NULL), /* 14 */
     _OPI(LOG, LG2, V(0,0), V(3,0), V(0,0), V(3,0), 1, 1, SPECIAL(LOG)), /* 15 */
-    _OPI(LIT, LIT, V(0,0), V(3,0), V(0,0), V(0,0), 1, 1, NULL), /* 16 */
+    _OPI(LIT, LIT, V(0,0), V(3,0), V(0,0), V(0,0), 1, 1, SPECIAL(LIT)), /* 16 */
     _OPI(DST, DST, V(0,0), V(3,0), V(0,0), V(3,0), 1, 2, NULL), /* 17 */
     _OPI(LRP, LRP, V(0,0), V(3,0), V(0,0), V(3,0), 1, 3, NULL), /* 18 */
     _OPI(FRC, FRC, V(0,0), V(3,0), V(0,0), V(3,0), 1, 1, NULL), /* 19 */
@@ -3065,6 +3086,7 @@ nine_translate_shader(struct NineDevice9 *device, struct nine_shader_info *info)
     HRESULT hr = D3D_OK;
     const unsigned processor = tgsi_processor_from_type(info->type);
     unsigned s, slot_max;
+    unsigned max_const_f;
 
     user_assert(processor != ~0, D3DERR_INVALIDCALL);
 
@@ -3204,11 +3226,12 @@ nine_translate_shader(struct NineDevice9 *device, struct nine_shader_info *info)
     if (tx->indirect_const_access) /* vs only */
         info->const_float_slots = device->max_vs_const_f;
 
+    max_const_f = IS_VS ? device->max_vs_const_f : device->max_ps_const_f;
     slot_max = info->const_bool_slots > 0 ?
-                   device->max_vs_const_f + NINE_MAX_CONST_I
-                   + info->const_bool_slots :
+                   max_const_f + NINE_MAX_CONST_I
+                   + DIV_ROUND_UP(info->const_bool_slots, 4) :
                        info->const_int_slots > 0 ?
-                           device->max_vs_const_f + info->const_int_slots :
+                           max_const_f + info->const_int_slots :
                                info->const_float_slots;
     info->const_used_size = sizeof(float[4]) * slot_max; /* slots start from 1 */