[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