[Mesa-dev] [PATCH 44/53] st/nine: Implement ps3 advanced input definition feature

Axel Davy axel.davy at ens.fr
Wed Jan 7 08:36:54 PST 2015


ps3 allows definitions of the inputs like:
DCL_TEXCOORD0 v0.xy;
DCL_NORMAL2 v0.z;
DCL_NORMAL3 v0.w;

Nine wouldn't have handled this situation properly.

Apparently very few applications use this feature.

Still remain an issue with this new implementation:
It is allowed to do indirect addressing on the ps inputs.

Since here the inputs are not contiguous (we allocate temps)
it cannot be implemented (we have an assert for that currently
in the code, and at least one app was reported to need this to
work)

Signed-off-by: Axel Davy <axel.davy at ens.fr>
---
 src/gallium/state_trackers/nine/nine_shader.c | 31 ++++++++++++++++++++++++++-
 1 file changed, 30 insertions(+), 1 deletion(-)

diff --git a/src/gallium/state_trackers/nine/nine_shader.c b/src/gallium/state_trackers/nine/nine_shader.c
index 9d4fb2f..69e35a2 100644
--- a/src/gallium/state_trackers/nine/nine_shader.c
+++ b/src/gallium/state_trackers/nine/nine_shader.c
@@ -1900,6 +1900,29 @@ nine_tgsi_to_interp_mode(struct tgsi_declaration_semantic *sem)
     }
 }
 
+static void ps3_concat_inputs(struct shader_translator *tx,
+                              struct sm1_semantic *sem,
+                              struct ureg_src src)
+{
+    unsigned idx = sem->reg.idx;
+    struct ureg_src previous_reg = tx->regs.v[idx];
+    struct ureg_dst tmp = ureg_DECL_temporary(tx->ureg);
+    BYTE swizzle[4] = {TGSI_SWIZZLE_X, TGSI_SWIZZLE_Y, TGSI_SWIZZLE_Z, TGSI_SWIZZLE_W};
+    BYTE mask = sem->reg.mask;
+
+    assert (mask);
+    while (!(mask & 0x01)) {
+        swizzle[0] = swizzle[1];
+        swizzle[1] = swizzle[2];
+        swizzle[2] = swizzle[3];
+        mask = mask > 1;
+    }
+    ureg_MOV(tx->ureg, tmp, previous_reg);
+    ureg_MOV(tx->ureg, ureg_writemask(tmp, sem->reg.mask),
+             ureg_swizzle(src, swizzle[0], swizzle[1], swizzle[2], swizzle[3]));
+    tx->regs.v[idx] = ureg_src(tmp);
+}
+
 DECL_SPECIAL(DCL)
 {
     struct ureg_program *ureg = tx->ureg;
@@ -1907,6 +1930,7 @@ DECL_SPECIAL(DCL)
     boolean is_sampler;
     struct tgsi_declaration_semantic tgsi;
     struct sm1_semantic sem;
+    struct ureg_src src;
     sm1_read_semantic(tx, &sem);
 
     is_input = sem.reg.file == D3DSPR_INPUT;
@@ -1962,11 +1986,16 @@ DECL_SPECIAL(DCL)
         if (is_input && tx->version.major >= 3) {
             /* SM3 only, SM2 input semantic determined by file */
             assert(sem.reg.idx < Elements(tx->regs.v));
-            tx->regs.v[sem.reg.idx] = ureg_DECL_fs_input_cyl_centroid(
+            src = ureg_DECL_fs_input_cyl_centroid(
                 ureg, tgsi.Name, tgsi.Index,
                 nine_tgsi_to_interp_mode(&tgsi),
                 0, /* cylwrap */
                 sem.reg.mod & NINED3DSPDM_CENTROID);
+            if (sem.reg.mask == NINED3DSP_WRITEMASK_ALL ||
+                ureg_src_is_undef(tx->regs.v[sem.reg.idx]))
+                tx->regs.v[sem.reg.idx] = src;
+            else
+                ps3_concat_inputs(tx, &sem, src);
         } else
         if (!is_input && 0) { /* declare in COLOROUT/DEPTHOUT case */
             /* FragColor or FragDepth */
-- 
2.1.3



More information about the mesa-dev mailing list