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

Igor Oliveira igor.oliveira at openbossa.org
Wed Sep 29 08:08:40 PDT 2010


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