Signed-off-by: Christian Gmeiner <christian.gmei...@gmail.com>
---
 src/gallium/auxiliary/tgsi/tgsi_lowering.c | 54 ++++++++++++++++++++++++++++++
 src/gallium/auxiliary/tgsi/tgsi_lowering.h |  1 +
 2 files changed, 55 insertions(+)

diff --git a/src/gallium/auxiliary/tgsi/tgsi_lowering.c 
b/src/gallium/auxiliary/tgsi/tgsi_lowering.c
index a3b90bd..cd5bdc2 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_lowering.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_lowering.c
@@ -258,6 +258,50 @@ transform_dst(struct tgsi_transform_context *tctx,
    }
 }
 
+/* FLR - Floor
+ *
+ *   dst.x = \lfloor src.x\rfloor
+ *   dst.y = \lfloor src.y\rfloor
+ *   dst.z = \lfloor src.z\rfloor
+ *   dst.w = \lfloor src.w\rfloor
+ *
+ * ; needs: 1 tmp
+ * FRC tmpA, src
+ * SUB dst, src, tmpA
+ */
+#define FLR_GROW (NINST(1) + NINST(2) - OINST(1))
+#define FLR_TMP  1
+static void
+transform_flr(struct tgsi_transform_context *tctx,
+              struct tgsi_full_instruction *inst)
+{
+    struct tgsi_lowering_context *ctx = tgsi_lowering_context(tctx);
+    struct tgsi_full_dst_register *dst = &inst->Dst[0];
+    struct tgsi_full_src_register *src = &inst->Src[0];
+    struct tgsi_full_instruction new_inst;
+
+    if (dst->Register.WriteMask & TGSI_WRITEMASK_XYZW) {
+       /* FRC tmpA, src */
+       new_inst = tgsi_default_full_instruction();
+       new_inst.Instruction.Opcode = TGSI_OPCODE_FRC;
+       new_inst.Instruction.NumDstRegs = 1;
+       reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, TGSI_WRITEMASK_XYZW);
+       new_inst.Instruction.NumSrcRegs = 1;
+       reg_src(&new_inst.Src[0], src, SWIZ(X, Y, Z, W));
+       tctx->emit_instruction(tctx, &new_inst);
+
+       /* SUB dst, src, tmpA */
+       new_inst = tgsi_default_full_instruction();
+       new_inst.Instruction.Opcode = TGSI_OPCODE_SUB;
+       new_inst.Instruction.NumDstRegs = 1;
+       reg_dst(&new_inst.Dst[0], dst, TGSI_WRITEMASK_XYZW);
+       new_inst.Instruction.NumSrcRegs = 2;
+       reg_src(&new_inst.Src[0], src, SWIZ(X, Y, Z, W));
+       reg_src(&new_inst.Src[1], &ctx->tmp[A].src, SWIZ(X, Y, Z, W));
+       tctx->emit_instruction(tctx, &new_inst);
+    }
+}
+
 /* XPD - Cross Product
  *   dst.x = src0.y \times src1.z - src1.y \times src0.z
  *   dst.y = src0.z \times src1.x - src1.z \times src0.x
@@ -1336,6 +1380,11 @@ transform_instr(struct tgsi_transform_context *tctx,
          goto skip;
       transform_dst(tctx, inst);
       break;
+   case TGSI_OPCODE_FLR:
+       if (!ctx->config->lower_FLR)
+           goto skip;
+       transform_flr(tctx, inst);
+       break;
    case TGSI_OPCODE_XPD:
       if (!ctx->config->lower_XPD)
          goto skip;
@@ -1460,6 +1509,7 @@ tgsi_transform_lowering(const struct tgsi_lowering_config 
*config,
 #define OPCS(x) ((config->lower_ ## x) ? info->opcode_count[TGSI_OPCODE_ ## x] 
: 0)
    /* if there are no instructions to lower, then we are done: */
    if (!(OPCS(DST) ||
+         OPCS(FLR) ||
          OPCS(XPD) ||
          OPCS(SCS) ||
          OPCS(LRP) ||
@@ -1489,6 +1539,10 @@ tgsi_transform_lowering(const struct 
tgsi_lowering_config *config,
       newlen += DST_GROW * OPCS(DST);
       numtmp = MAX2(numtmp, DST_TMP);
    }
+   if (OPCS(FLR)) {
+      newlen += FLR_GROW * OPCS(FLR);
+      numtmp = MAX2(numtmp, FLR_TMP);
+   }
    if (OPCS(XPD)) {
       newlen += XPD_GROW * OPCS(XPD);
       numtmp = MAX2(numtmp, XPD_TMP);
diff --git a/src/gallium/auxiliary/tgsi/tgsi_lowering.h 
b/src/gallium/auxiliary/tgsi/tgsi_lowering.h
index 52c204f..803f84e 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_lowering.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_lowering.h
@@ -55,6 +55,7 @@ struct tgsi_lowering_config
     * enable lowering of TGSI_OPCODE_<opc>
     */
    unsigned lower_DST:1;
+   unsigned lower_FLR:1;
    unsigned lower_XPD:1;
    unsigned lower_SCS:1;
    unsigned lower_LRP:1;
-- 
2.5.5

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to