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

José Fonseca jfonseca at vmware.com
Wed Sep 29 07:57:34 PDT 2010


Could you please send me the modified tri.py as well. Thanks

Jose

On Wed, 2010-09-29 at 07:41 -0700, Igor Oliveira wrote:
> 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