[Mesa-dev] [PATCH 1/2] WIP gallivm: add support for PK2H/UP2H

Ilia Mirkin imirkin at alum.mit.edu
Sun Jan 3 13:29:37 PST 2016


This hits assertion failures on LLVM 3.5

Signed-off-by: Ilia Mirkin <imirkin at alum.mitedu>
---

It definitely worked at one point or another, but it might have been with
a later LLVM version and/or on a different CPU. On my i7-920 with LLVM 3.5
I definitely get assertion errors from inside LLVM. Any interested party
can take this patch over and fix it as they see fit. Or ignore it.

 src/gallium/auxiliary/gallivm/lp_bld_tgsi.c        |  1 -
 src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c | 87 ++++++++++++++++++++++
 src/gallium/drivers/llvmpipe/lp_screen.c           |  2 +-
 3 files changed, 88 insertions(+), 2 deletions(-)

diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.c
index c88dfbf..1cbe47c 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.c
@@ -248,7 +248,6 @@ lp_build_tgsi_inst_llvm(
    /* Ignore deprecated instructions */
    switch (inst->Instruction.Opcode) {
 
-   case TGSI_OPCODE_UP2H:
    case TGSI_OPCODE_UP2US:
    case TGSI_OPCODE_UP4B:
    case TGSI_OPCODE_UP4UB:
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c
index 3d5e2cb..ac3298d 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c
@@ -1020,6 +1020,88 @@ static void dfrac_emit(
                                                        emit_data->args[0], tmp, "");
 }
 
+static void
+pk2h_fetch_args(
+   struct lp_build_tgsi_context * bld_base,
+   struct lp_build_emit_data * emit_data)
+{
+   /* src0.x */
+   emit_data->args[0] = lp_build_emit_fetch(bld_base, emit_data->inst,
+                                            0, TGSI_CHAN_X);
+   /* src0.y */
+   emit_data->args[1] = lp_build_emit_fetch(bld_base, emit_data->inst,
+                                            0, TGSI_CHAN_Y);
+}
+
+static void
+emit_pk2h(const struct lp_build_tgsi_action *action,
+          struct lp_build_tgsi_context *bld_base,
+          struct lp_build_emit_data *emit_data)
+{
+   LLVMBuilderRef builder = bld_base->base.gallivm->builder;
+   LLVMContextRef context = bld_base->base.gallivm->context;
+   struct lp_build_context *uint_bld = &bld_base->uint_bld;
+   LLVMTypeRef fp16 = LLVMVectorType(LLVMHalfTypeInContext(context),
+                                     bld_base->base.type.length);
+   LLVMTypeRef i16 = LLVMVectorType(LLVMInt16TypeInContext(context),
+                                    bld_base->base.type.length);
+   LLVMValueRef const16 = lp_build_const_vec(uint_bld->gallivm, uint_bld->type,
+                                             16);
+
+   LLVMValueRef low = LLVMBuildFPTrunc(
+      builder, emit_data->args[0], fp16, "");
+   LLVMValueRef high = LLVMBuildFPTrunc(
+      builder, emit_data->args[1], fp16, "");
+
+   low = LLVMBuildZExt(builder, LLVMBuildBitCast(builder, low, i16, ""),
+                       uint_bld->vec_type, "");
+   high = LLVMBuildZExt(builder, LLVMBuildBitCast(builder, high, i16, ""),
+                        uint_bld->vec_type, "");
+
+   emit_data->output[emit_data->chan] =
+      LLVMBuildOr(builder, low, LLVMBuildShl(builder, high, const16, ""), "");
+}
+
+static void
+up2h_fetch_args(
+   struct lp_build_tgsi_context * bld_base,
+   struct lp_build_emit_data * emit_data)
+{
+   /* src0.x */
+   emit_data->args[0] = lp_build_emit_fetch(bld_base, emit_data->inst,
+                                            0, TGSI_CHAN_X);
+}
+
+static void
+emit_up2h(const struct lp_build_tgsi_action *action,
+          struct lp_build_tgsi_context *bld_base,
+          struct lp_build_emit_data *emit_data)
+{
+   LLVMBuilderRef builder = bld_base->base.gallivm->builder;
+   LLVMContextRef context = bld_base->base.gallivm->context;
+   struct lp_build_context *uint_bld = &bld_base->uint_bld;
+   LLVMTypeRef fp16 = LLVMVectorType(LLVMHalfTypeInContext(context),
+                                     bld_base->base.type.length);
+   LLVMTypeRef i16 = LLVMVectorType(LLVMInt16TypeInContext(context),
+                                    bld_base->base.type.length);
+   LLVMValueRef const16 = lp_build_const_vec(uint_bld->gallivm, uint_bld->type,
+                                             16);
+
+   LLVMValueRef input = LLVMBuildBitCast(
+      builder, emit_data->args[0], bld_base->base.int_vec_type, "");
+   int i;
+
+   for (i = 0; i < 2; i++) {
+      LLVMValueRef val = input;
+      if (i == 1)
+         val = LLVMBuildLShr(builder, val, const16, "");
+      val = LLVMBuildTrunc(builder, val, i16, "");
+      val = LLVMBuildBitCast(builder, val, fp16, "");
+      emit_data->output[i] =
+         LLVMBuildFPExt(builder, val, bld_base->base.vec_type, "");
+   }
+}
+
 void
 lp_set_default_actions(struct lp_build_tgsi_context * bld_base)
 {
@@ -1093,6 +1175,11 @@ lp_set_default_actions(struct lp_build_tgsi_context * bld_base)
    bld_base->op_actions[TGSI_OPCODE_DRCP].emit = drcp_emit;
    bld_base->op_actions[TGSI_OPCODE_DFRAC].emit = dfrac_emit;
 
+   bld_base->op_actions[TGSI_OPCODE_PK2H].fetch_args = pk2h_fetch_args;
+   bld_base->op_actions[TGSI_OPCODE_PK2H].emit = emit_pk2h;
+
+   bld_base->op_actions[TGSI_OPCODE_UP2H].fetch_args = up2h_fetch_args;
+   bld_base->op_actions[TGSI_OPCODE_UP2H].emit = emit_up2h;
 }
 
 /* CPU Only default actions */
diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c
index 0898cff..e2fa73f 100644
--- a/src/gallium/drivers/llvmpipe/lp_screen.c
+++ b/src/gallium/drivers/llvmpipe/lp_screen.c
@@ -290,6 +290,7 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
    case PIPE_CAP_POLYGON_OFFSET_CLAMP:
    case PIPE_CAP_TEXTURE_FLOAT_LINEAR:
    case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:
+   case PIPE_CAP_TGSI_PACK_HALF_FLOAT:
       return 1;
    case PIPE_CAP_MULTISAMPLE_Z_RESOLVE:
    case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:
@@ -302,7 +303,6 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
    case PIPE_CAP_COPY_BETWEEN_COMPRESSED_AND_PLAIN_FORMATS:
    case PIPE_CAP_CLEAR_TEXTURE:
    case PIPE_CAP_DRAW_PARAMETERS:
-   case PIPE_CAP_TGSI_PACK_HALF_FLOAT:
    case PIPE_CAP_MULTI_DRAW_INDIRECT:
    case PIPE_CAP_MULTI_DRAW_INDIRECT_PARAMS:
       return 0;
-- 
2.4.10



More information about the mesa-dev mailing list