[Mesa-dev] [PATCH] nvc0/lowering: Handle conversions to U64/S64 manually

Ilia Mirkin imirkin at alum.mit.edu
Sun Apr 17 20:38:26 UTC 2016


On Sun, Apr 17, 2016 at 4:27 PM, Pierre Moreau <pierre.morrow at free.fr> wrote:
> On 04:17 PM - Apr 17 2016, Ilia Mirkin wrote:
>> On Sun, Apr 17, 2016 at 4:07 PM, Pierre Moreau <pierre.morrow at free.fr> wrote:
>> > Ping :-)
>> >
>> > On 10:56 PM - Mar 19 2016, Pierre Moreau wrote:
>> >> Generating a `cvt u32 $r0 u64 $r1d` or a `cvt u64 $r0d u32 $r2` makes the GPU
>> >> unhappy. Instead, manually handle the conversion between 64-bit and 32-bit
>> >> values, and use `cvt` to convert between the original target (resp. source)
>> >> and 32-bit value. This happens to be the behaviour of NVIDIA's driver.
>> >>
>> >> Signed-off-by: Pierre Moreau <pierre.morrow at free.fr>
>> >> ---
>> >>  .../nouveau/codegen/nv50_ir_lowering_nvc0.cpp      | 59 ++++++++++++++++++++++
>> >>  .../nouveau/codegen/nv50_ir_lowering_nvc0.h        |  1 +
>> >>  2 files changed, 60 insertions(+)
>> >>
>> >> diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp
>> >> index 2719f2c..c419a68 100644
>> >> --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp
>> >> +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp
>> >> @@ -1859,6 +1859,63 @@ NVC0LoweringPass::handleOUT(Instruction *i)
>> >>     return true;
>> >>  }
>> >>
>> >> +bool
>> >> +NVC0LoweringPass::handleCVT(Instruction *i)
>> >> +{
>> >> +   if (isFloatType(i->dType) || isFloatType(i->sType) ||
>> >> +         isSignedIntType(i->dType) xor isSignedIntType(i->sType))
>>
>> I know pre-C89 features are cool, but let's avoid using them. I know
>> characters like ^ were uncommon on the 1960's and 1970's teletypes,
>> but I think we're past those days now.
>
> Yeah… Will fix that.
>
>>
>> >> +      return false;
>> >> +
>> >> +   if (typeSizeof(i->sType) == 8) {
>> >> +      Value *toSplit = i->getSrc(0);
>> >> +      if (i->saturate) {
>> >> +         Value *minValue = bld.loadImm(bld.getSSA(8), 0ul);
>> >> +         Value *maxValue = bld.loadImm(bld.getSSA(8), UINT32_MAX);
>> >> +         if (isSignedType(i->sType)) {
>> >> +            minValue = bld.loadImm(bld.getSSA(8), INT32_MIN);
>> >> +            maxValue = bld.loadImm(bld.getSSA(8), INT32_MAX);
>> >> +         }
>> >> +         Value *minRes = bld.mkOp2v(OP_MAX, i->sType, bld.getSSA(8), toSplit,
>> >> +                                    minValue);
>> >> +         toSplit = bld.mkOp2v(OP_MIN, i->sType, bld.getSSA(8), minRes,
>> >> +                              maxValue);
>>
>> Aren't you assuming that i->dType == 4 here? It could be an unsigned
>> <-> signed conversion, at 64-bit. So the clamp values would be
>
> I am assuming `i->dType <= 4`: remember the ^ from before! ;-) But, it
> could be a U64 <=> U64 or S64 <=> S64 conversion, which would then fail…

Oh I see. And the == 4 out is to avoid the extra cvt... which we don't
optimize out? I thought we should, but maybe not.

Some asserts could be in order, like

assert(typeSizeof(i->sType) != typeSizeof(i->dType))

or something like that above, to clarify what you mean.

  -ilia

>
>> different. Handling ALL the cases is quite annoying... can you figure
>> out what the hw doesn't support and just handle that? I doubt it'll be
>> any slower, and definitely simpler.
>
> I don’t remember if I checked U64 <=> S64 conversions… Will need to refresh my
> memory and log which combinations fail.
>
> Thanks!
> Pierre
>
>>
>>   -ilia
>>
>> >> +      }
>> >> +
>> >> +      Value *value32[2] = { bld.getSSA(), bld.getSSA() };
>> >> +      bld.mkSplit(value32, 4, toSplit);
>> >> +      if (typeSizeof(i->dType) == 4) {
>> >> +         bld.mkMov(i->getDef(0), value32[0], i->dType);
>> >> +         delete_Instruction(prog, i);
>> >> +         return true;
>> >> +      }
>> >> +
>> >> +      i->setSrc(0, bld.getSSA());
>> >> +      i->sType = isSignedIntType(i->dType) ? TYPE_S32 : TYPE_U32;
>> >> +      bld.mkMov(i->getSrc(0), value32[0], i->sType);
>> >> +   } else if (typeSizeof(i->dType) == 8) {
>> >> +      bld.setPosition(i, true);
>> >> +      Value *res = i->getDef(0);
>> >> +      Value *high32 = bld.loadImm(bld.getSSA(),
>> >> +                                  isSignedType(i->sType) ? UINT32_MAX : 0u);
>> >> +      Value *low32 = i->getSrc(0);
>> >> +      DataType resType = i->dType;
>> >> +
>> >> +      if (typeSizeof(i->sType) <= 2) {
>> >> +         i->dType = isSignedIntType(i->dType) ? TYPE_S32 : TYPE_U32;
>> >> +         low32 = bld.getSSA();
>> >> +         i->setDef(0, low32);
>> >> +      } else if (typeSizeof(i->sType) == 4) {
>> >> +         delete_Instruction(prog, i);
>> >> +      }
>> >> +
>> >> +      Value *merged64 = bld.mkOp2v(OP_MERGE, resType, bld.getSSA(8), low32,
>> >> +                                   high32);
>> >> +      bld.mkMov(res, merged64, resType);
>> >> +   }
>> >> +
>> >> +   return true;
>> >> +}
>> >> +
>> >>  // Generate a binary predicate if an instruction is predicated by
>> >>  // e.g. an f32 value.
>> >>  void
>> >> @@ -1894,6 +1951,8 @@ NVC0LoweringPass::visit(Instruction *i)
>> >>        checkPredicate(i);
>> >>
>> >>     switch (i->op) {
>> >> +   case OP_CVT:
>> >> +      return handleCVT(i);
>> >>     case OP_TEX:
>> >>     case OP_TXB:
>> >>     case OP_TXL:
>> >> diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.h b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.h
>> >> index 6eb8aff..9fc24d9 100644
>> >> --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.h
>> >> +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.h
>> >> @@ -96,6 +96,7 @@ protected:
>> >>     bool handleMOD(Instruction *);
>> >>     bool handleSQRT(Instruction *);
>> >>     bool handlePOW(Instruction *);
>> >> +   bool handleCVT(Instruction *);
>> >>     bool handleTEX(TexInstruction *);
>> >>     bool handleTXD(TexInstruction *);
>> >>     bool handleTXQ(TexInstruction *);
>> >> --
>> >> 2.7.4
>> >>
>> >> _______________________________________________
>> >> mesa-dev mailing list
>> >> mesa-dev at lists.freedesktop.org
>> >> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
>> >
>> > _______________________________________________
>> > mesa-dev mailing list
>> > mesa-dev at lists.freedesktop.org
>> > https://lists.freedesktop.org/mailman/listinfo/mesa-dev
>> >
>> _______________________________________________
>> mesa-dev mailing list
>> mesa-dev at lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list