On 04.04.2013 17:01, Jose Fonseca wrote: > > ----- Original Message ----- >>> On 04.04.2013 03:45, Zack Rusin wrote: >>>> It's part of SM4 (http://goo.gl/4IpeK). It's also fairly >>>> painful to emulate without branching. Most hardware >>>> supports it natively and even llvm has a 'select' opcode >>>> which can handle it without too much hassle. >>>> >>>> diff --git a/src/gallium/docs/source/tgsi.rst >>>> b/src/gallium/docs/source/tgsi.rst >>>> index 28308cb..6c5a02b 100644 >>>> --- a/src/gallium/docs/source/tgsi.rst >>>> +++ b/src/gallium/docs/source/tgsi.rst >>>> @@ -72,6 +72,17 @@ used. >>>> >>>> dst.w = src.w >>>> >>>> +.. opcode:: MOVC - Conditional move >>>> + >>>> +.. math:: >>>> + >>>> + dst.x = src0.x ? src1.x : src2.x >>>> + >>>> + dst.y = src0.y ? src1.y : src2.y >>>> + >>>> + dst.z = src0.z ? src1.z : src2.z >>>> + >>>> + dst.w = src0.w ? src1.w : src2.w >>>> >>> I think we already have that: >>> >>> .. opcode:: UCMP - Integer Conditional Move >>> >>> .. math:: >>> >>> dst.x = src0.x ? src1.x : src2.x >>> >>> dst.y = src0.y ? src1.y : src2.y >>> >>> dst.z = src0.z ? src1.z : src2.z >>> >>> dst.w = src0.w ? src1.w : src2.w >>> >>> >>> No difference apart from the source ordering (the "integer" just implies >>> that any non-zero value counts as true, i.e. also inf, nan and -0). >> That's really broken. UCMP needs to be a an unsigned version of the CMP >> instruction which does >> dst.chan = (src0.chan < 0) ? src1.chan : src2.chan >> not a whole new instruction. It's what everyone implements anyway. So if >> st_glsl_to_tgsi needs >> a conditional move we need to add the above patch and change it to use it. > Yes, it doesn't seem that any of the TGSI_OPCODE_UCMP implementation does > that the spec says it supposedly does -- it seems everybody implements it as > an unsigned version of CMP. That is, it seems UCMP's description needs to be > fixed.
Erm, unsigned < 0 doesn't make sense. Definitely what the description says: static void micro_ucmp(union tgsi_exec_channel *dst, const union tgsi_exec_channel *src0, const union tgsi_exec_channel *src1, const union tgsi_exec_channel *src2) { dst->u[0] = src0->u[0] ? src1->u[0] : src2->u[0]; dst->u[1] = src0->u[1] ? src1->u[1] : src2->u[1]; dst->u[2] = src0->u[2] ? src1->u[2] : src2->u[2]; dst->u[3] = src0->u[3] ? src1->u[3] : src2->u[3]; } or case TGSI_OPCODE_UCMP: case TGSI_OPCODE_CMP: FOR_EACH_DST_ENABLED_CHANNEL(0, c, tgsi) { src0 = fetchSrc(0, c); src1 = fetchSrc(1, c); src2 = fetchSrc(2, c); if (src1 == src2) mkMov(dst0[c], src1); else mkCmp(OP_SLCT, (srcTy == TYPE_F32) ? CC_LT(less than 0) : CC_NE(not equal 0), srcTy, dst0[c], src1, src2, src0); } > Jose > _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev