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

Igor Oliveira igor.oliveira at openbossa.org
Mon Oct 4 09:48:48 PDT 2010


Hi,

I do not have commit permissions, so I created a personal repository:
ssh://people.freedesktop.org/~igor.oliveira/gallium-double-opcodes.git

There you can find dmul-tri.py and the patch.
I hope that it can help you to test the patch.

Igor

On Mon, Oct 4, 2010 at 9:31 AM, José Fonseca <jfonseca at vmware.com> wrote:
> Igor,
>
> How can I test your patches? They don't apply against
> gallium-double-opcode branch. They apply cleanly against master but
> master doesn't have the double opcodes.
>
> Could you please make it easy for me can test what you're suggesting
> without wasting too much time? In detail:
> - update gallium-double-opcode branch
> - apply your suggested llvmpipe change
> - commit your modified try.py with another name, e.g., tri-dmul.py
>
> Jose
>
> On Wed, 2010-09-29 at 08:08 -0700, Igor Oliveira wrote:
>> Yep,
>>
>> See bellow. Basically the output is not smooth because the OUT[0].x is
>> the msb from double enad the OUT[0].y is the lsb.
>>
>> Igor
>>
>> diff --git a/src/gallium/tests/python/samples/tri.py
>> b/src/gallium/tests/python/samples/tri.py
>> index 6d17c88..5b74c16 100644
>> --- a/src/gallium/tests/python/samples/tri.py
>> +++ b/src/gallium/tests/python/samples/tri.py
>> @@ -154,8 +154,8 @@ def test(dev):
>>      rgba = FloatArray(4);
>>      rgba[0] = 0.0
>>      rgba[1] = 0.0
>> -    rgba[2] = 0.0
>> -    rgba[3] = 0.0
>> +    rgba[2] = 1.0
>> +    rgba[3] = 1.0
>>      ctx.clear(PIPE_CLEAR_COLOR | PIPE_CLEAR_DEPTHSTENCIL, rgba, 1.0, 0xff)
>>
>>      # vertex shader
>> @@ -176,8 +176,10 @@ def test(dev):
>>          FRAG
>>          DCL IN[0], COLOR, LINEAR
>>          DCL OUT[0], COLOR, CONSTANT
>> -        0:MOV OUT[0], IN[0]
>> -        1:END
>> +        DCL TEMP[0]
>> +        0:DMUL TEMP[0].xy, IN[0], IN[0]
>> +        1:MOV OUT[0], TEMP[0]
>> +        2:END
>>      ''')
>>      ctx.set_fragment_shader(fs)
>>
>> @@ -189,25 +191,30 @@ def test(dev):
>>      verts[ 1] =   0.8 # y1
>>      verts[ 2] =   0.2 # z1
>>      verts[ 3] =   1.0 # w1
>> +
>>      verts[ 4] =   1.0 # r1
>> -    verts[ 5] =   0.0 # g1
>> -    verts[ 6] =   0.0 # b1
>> -    verts[ 7] =   1.0 # a1
>> +    verts[ 5] =   1.0 # g1
>> +    verts[ 6] =   0.6 # b1
>> +    verts[ 7] =   0.6 # a1
>> +
>>      verts[ 8] =  -0.8 # x2
>>      verts[ 9] =  -0.8 # y2
>>      verts[10] =   0.5 # z2
>>      verts[11] =   1.0 # w2
>> -    verts[12] =   0.0 # r2
>> -    verts[13] =   1.0 # g2
>> -    verts[14] =   0.0 # b2
>> -    verts[15] =   1.0 # a2
>> +
>> +    verts[12] =   0.6 # r2
>> +    verts[13] =   0.6 # g2
>> +    verts[14] =   0.6 # b2
>> +    verts[15] =   0.6 # a2
>> +
>>      verts[16] =   0.8 # x3
>>      verts[17] =  -0.8 # y3
>>      verts[18] =   0.8 # z3
>>      verts[19] =   1.0 # w3
>> -    verts[20] =   0.0 # r3
>> -    verts[21] =   0.0 # g3
>> -    verts[22] =   1.0 # b3
>> +
>> +    verts[20] =   1.0 # r3
>> +    verts[21] =   1.0 # g3
>> +    verts[22] =   0.6 # b3
>>      verts[23] =   1.0 # a3
>>
>>      ctx.draw_vertices(PIPE_PRIM_TRIANGLES,
>>
>> On Wed, Sep 29, 2010 at 10:57 AM, José Fonseca <jfonseca at vmware.com> wrote:
>> > 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