[Mesa-dev] [PATCH] llvmpipe: add initial support to double opcodes in llvmpipe.

Igor Oliveira igor.oliveira at openbossa.org
Wed Sep 29 07:41:14 PDT 2010


Hi Jose,

I updated the patch(see below), I am using python samples, modifying
the tri.py to use it because the regress tests are outdated.
Now we have we can get the msb and the lsb values from double operations.

diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
index 441aeba..70330dc 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
@@ -963,6 +963,68 @@ emit_kil(
       lp_build_mask_update(bld->mask, mask);
 }

+static LLVMValueRef
+lp_cast_to_double(struct lp_build_context *bld,
+                   LLVMValueRef a,
+                   LLVMValueRef b)
+{
+   struct lp_type type;
+   LLVMValueRef res;
+   LLVMTypeRef vec_type;
+   LLVMTypeRef vec_double_type;
+
+   type = lp_type_uint_vec(64);
+   vec_type = lp_build_vec_type(type);
+
+   a = LLVMBuildBitCast(bld->builder, a, vec_type, "");
+   b = LLVMBuildBitCast(bld->builder, b, vec_type, "");
+
+   res = LLVMBuildShl(bld->builder, a, lp_build_const_int_vec(type, 32),"");
+   res = LLVMBuildOr(bld->builder, res, b, "");
+
+   a = LLVMBuildBitCast(bld->builder, a, bld->vec_type, "");
+   b = LLVMBuildBitCast(bld->builder, b, bld->vec_type, "");
+
+   type = lp_type_float_vec(64);
+   bld->type = type;
+   vec_double_type = lp_build_vec_type(type);
+   res = LLVMBuildBitCast(bld->builder, res, vec_double_type, "");
+
+   return res;
+}
+
+static LLVMValueRef
+lp_cast_from_double_msb(struct lp_build_context *bld,
+                        LLVMValueRef double_value)
+{
+   LLVMTypeRef double_type;
+   LLVMValueRef res;
+   struct lp_type type = lp_type_uint_vec(64);
+
+   double_type = lp_build_vec_type(type);
+   res = LLVMBuildBitCast(bld->builder, double_value, double_type, "");
+   res = LLVMBuildLShr(bld->builder, res,
lp_build_const_int_vec(type, 32), "");
+   res = LLVMBuildBitCast(bld->builder, res, bld->vec_type, "");
+
+   return res;
+}
+
+
+static LLVMValueRef
+lp_cast_from_double_lsb(struct lp_build_context *bld,
+                        LLVMValueRef double_value)
+{
+   LLVMTypeRef double_type;
+   LLVMValueRef res;
+   struct lp_type type = lp_type_uint_vec(64);
+
+   double_type = lp_build_vec_type(type);
+   res = LLVMBuildBitCast(bld->builder, double_value, double_type, "");
+   res = LLVMBuildAnd(bld->builder, res, lp_build_const_int_vec(type,
0x00000000FFFFFFFF), "");
+   res = LLVMBuildBitCast(bld->builder, res, bld->vec_type, "");
+
+   return res;
+}

 /**
  * Predicated fragment kill.
@@ -1982,6 +2044,37 @@ emit_instruction(
    case TGSI_OPCODE_NOP:
       break;

+   case TGSI_OPCODE_DMUL:
+      if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_X) &&
IS_DST0_CHANNEL_ENABLED(inst, CHAN_Y)) {
+         tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
+         tmp1 = emit_fetch( bld, inst, 0, CHAN_Y );
+
+         tmp2 = emit_fetch( bld, inst, 1, CHAN_X );
+         tmp3 = emit_fetch( bld, inst, 1, CHAN_Y );
+
+         src0 = lp_cast_to_double(&bld->base, tmp0, tmp1);
+         src1 = lp_cast_to_double(&bld->base, tmp2, tmp3);
+         tmp4 = lp_build_mul(&bld->base, src0, src1);
+         dst0[CHAN_X] = lp_cast_from_double_msb(&bld->base, tmp4);
+         dst0[CHAN_Y] = lp_cast_from_double_lsb(&bld->base, tmp4);
+      }
+
+      if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_Z) &&
IS_DST0_CHANNEL_ENABLED(inst, CHAN_W)) {
+         tmp0 = emit_fetch( bld, inst, 0, CHAN_Z );
+         tmp1 = emit_fetch( bld, inst, 0, CHAN_W );
+
+         tmp2 = emit_fetch( bld, inst, 1, CHAN_Z );
+         tmp3 = emit_fetch( bld, inst, 1, CHAN_W );
+
+         src0 = lp_cast_to_double(&bld->base, tmp0, tmp1);
+         src1 = lp_cast_to_double(&bld->base, tmp2, tmp3);
+         tmp4 = lp_build_mul(&bld->base, src0, src1);
+         dst0[CHAN_Z] = lp_cast_from_double_msb(&bld->base, tmp4);
+         dst0[CHAN_W] = lp_cast_from_double_lsb(&bld->base, tmp4);
+
+      }
+      break;
+
    default:
       return FALSE;
    }
-- 
1.7.0.4



On Tue, Sep 28, 2010 at 5:32 PM, Jose Fonseca <jfonseca at vmware.com> wrote:
> Sorry Igor. I dropped the ball on your previous submission.
>
> I still don't understand what the code does, nor how the generated code will look like. Granted, your implementation is better than no implementation, but I'd like to go a bit further and get this nailed, and not have to redo this code.
>
> Is there a simple test case I can use to exercise and test this?
>
> Jose
>
> ________________________________________
> From: mesa-dev-bounces+jfonseca=vmware.com at lists.freedesktop.org [mesa-dev-bounces+jfonseca=vmware.com at lists.freedesktop.org] On Behalf Of Igor Oliveira [igor.oliveira at openbossa.org]
> Sent: Tuesday, September 28, 2010 20:34
> To: mesa-dev at lists.freedesktop.org
> Subject: [Mesa-dev] [PATCH] llvmpipe: add initial support to double opcodes     in llvmpipe.
>
> - create helper function
> - implement DMUL opcode
> ---
>  src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c |   78 +++++++++++++++++++++++
>  1 files changed, 78 insertions(+), 0 deletions(-)
>
> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
> b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
> index ca8db9c..c9174ce 100644
> --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
> +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
> @@ -970,6 +970,56 @@ emit_kil(
>       lp_build_mask_update(bld->mask, mask);
>  }
>
> +static LLVMValueRef
> +lp_cast_to_double(struct lp_build_context *bld,
> +                   LLVMValueRef a,
> +                   LLVMValueRef b)
> +{
> +   struct lp_type type;
> +   LLVMValueRef res;
> +   LLVMTypeRef vec_type;
> +   LLVMTypeRef vec_double_type;
> +
> +   assert(lp_check_value(bld->type, a));
> +   assert(lp_check_value(bld->type, b));
> +
> +   type = lp_type_uint_vec(64);
> +   vec_type = lp_build_vec_type(type);
> +
> +   a = LLVMBuildBitCast(bld->builder, a, vec_type, "");
> +   b = LLVMBuildBitCast(bld->builder, b, vec_type, "");
> +
> +   res = LLVMBuildShl(bld->builder, a, lp_build_const_int_vec(type, 32),"");
> +   res = LLVMBuildOr(bld->builder, res, b, "");
> +
> +   a = LLVMBuildBitCast(bld->builder, a, bld->vec_type, "");
> +   b = LLVMBuildBitCast(bld->builder, b, bld->vec_type, "");
> +
> +   type = lp_type_float_vec(64);
> +   vec_double_type = lp_build_vec_type(type);
> +   res = LLVMBuildBitCast(bld->builder, res, vec_double_type, "");
> +
> +   return res;
> +}
> +
> +static void
> +lp_cast_from_double(struct lp_build_context *bld,
> +                    LLVMValueRef double_value,
> +                    LLVMValueRef a,
> +                    LLVMValueRef b)
> +{
> +   LLVMTypeRef double_type;
> +   struct lp_type type = lp_type_uint_vec(64);
> +
> +   double_type = lp_build_vec_type(type);
> +   a = LLVMBuildBitCast(bld->builder, double_value, double_type, "");
> +
> +   b = LLVMBuildAnd(bld->builder, a, lp_build_const_int_vec(type,
> 0x00000000FFFFFFFF), "");
> +
> +   a = LLVMBuildBitCast(bld->builder, a, bld->vec_type, "");
> +   b = LLVMBuildBitCast(bld->builder, b, bld->vec_type, "");
> +}
> +
>
>  /**
>  * Predicated fragment kill.
> @@ -1988,6 +2038,34 @@ emit_instruction(
>    case TGSI_OPCODE_NOP:
>       break;
>
> +   case TGSI_OPCODE_DMUL:
> +      if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_X) &&
> IS_DST0_CHANNEL_ENABLED(inst, CHAN_Y)) {
> +         tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
> +         tmp1 = emit_fetch( bld, inst, 0, CHAN_Y );
> +
> +         tmp2 = emit_fetch( bld, inst, 1, CHAN_X );
> +         tmp3 = emit_fetch( bld, inst, 1, CHAN_Y );
> +
> +         src0 = lp_cast_to_double(&bld->base, tmp0, tmp1);
> +         src1 = lp_cast_to_double(&bld->base, tmp2, tmp3);
> +         tmp4 = lp_build_mul(&bld->base, src0, src1);
> +         lp_cast_from_double(&bld->base, tmp4, dst0[CHAN_X], dst0[CHAN_Y]);
> +      }
> +
> +      if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_Z) &&
> IS_DST0_CHANNEL_ENABLED(inst, CHAN_W)) {
> +         tmp0 = emit_fetch( bld, inst, 0, CHAN_Z );
> +         tmp1 = emit_fetch( bld, inst, 0, CHAN_W );
> +
> +         tmp2 = emit_fetch( bld, inst, 1, CHAN_Z );
> +         tmp3 = emit_fetch( bld, inst, 1, CHAN_W );
> +
> +         src0 = lp_cast_to_double(&bld->base, tmp0, tmp1);
> +         src1 = lp_cast_to_double(&bld->base, tmp2, tmp3);
> +         tmp4 = lp_build_mul(&bld->base, src0, src1);
> +         lp_cast_from_double(&bld->base, tmp4, dst0[CHAN_Z], dst0[CHAN_W]);
> +      }
> +      break;
> +
>    default:
>       return FALSE;
>    }
> --
> 1.7.0.4
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
>


More information about the mesa-dev mailing list