On 11/14/2011 09:48 PM, Christoph Bumiller wrote: > On 11/14/2011 09:24 PM, Jose Fonseca wrote: >> >> >> ----- Original Message ----- >>> On 11/14/2011 08:23 PM, Jose Fonseca wrote: >>>> >>>> >>>> ----- Original Message ----- >>>>> The next open question I have is whether this warrants additions >>>>> to >>>>> the tgsi_opcode_info struct, mainly whether the return value is >>>>> uint/int/float, >>>>> and whether then src regs are uint/int/float, I'm not 100% that >>>>> all >>>>> opcodes always take all int/uint/float srcs, but my memory is a >>>>> bit >>>>> hazy on what the outliers might be. >>>> >>>> I agree that adding this sort of info to tgsi_opcode_info would be >>>> a code typing saver for all drivers. >>>> >>>> However I never looked at the integer/double opcode set, but from >>>> quickly skimming d3d10/11 headers, there are three buckets: >>>> - arithmetic: (u)ints -> (u)int >>>> - comparison: (u)ints -> mask (and I don't know what's the semantic >>>> of these masks: 0/~0, 1.0f/0.0f, 0/1, or what) >>>> - conversion: float <-> (u)int >>>> >>>> >>>> And likewise to double, minus the unsigned vs signed split. >>>> >>>> So, probably we need tgsi_opcode_info to distuinguish the source >>>> type vs dest type, but we likely don't need per-source types. >>>> >>>> >>>> >>>> A much more intricate question, is how to represent boolean mask in >>>> a mixed type world. My guess is one of two: >>>> >>>> a) is that there are two we should not mandate the bit >>>> representation of a boolean (drivers are free to implement >>>> booleans as 1.0f/0.0f, 0/~0, etc). The only constrainsts is that >>>> the state tracker never tries to write a boolean directly to an >>>> output. >>>> >>> >>> >>> Booleans can be set by the user (CONST) and thus the state tracker >>> has >>> know what drivers want. >> >> I forgot about those. >> >> One thing that's common to all representations is that 0x00000000 is false >> on all of them. So we could establish that as false. >> >> Another approach, make cleaner, would be to disallow CONST booleans: i.e., >> the state tracker would use floats (0.0f/1.0f) or ints, and then explicitely >> emit a comparison against the null element to determine the boolean value: >> >> CONST[0] // boolean as float >> CONST[1] // boolean as integer >> CONST[2] // boolean as double >> IMM[0] = {0, 1.0f} >> >> // TEMP[0] == (bool)CONST[0] >> EQ TEMP[0], CONST[0], IMM[0].xxxx >> >> // TEMP[1] == (bool)CONST[1] >> IEQ TEMP[1], CONST[1], IMM[0].xxxx >> >> // TEMP[2] == (bool)CONST[2] >> DEQ TEMP[2], CONST[2], IMM[0].xxxx >> >> And the inverse for outputs. >> >> // OUT[0] = TEMP[0] ? 1.0f : 0.0f >> SELECT OUT[0], TEMP[0], IMM[1], IMM[0] >> >> We need some way to encode integer/double immediates though. >> >>>> b) if by some miracle, all hardware implements boolean vectors in >>>> the same way, then we could stick to that. (For sse/avx/llvm-2.9, >>>> the natural way to represent a boolean vector is a bitmask (0/~0). >>>> llvm 3.0 finally added support for bit vectors.) >>>> >>>> >>> >>> Currently, classic mesa uses 1/0, gallium uses 1.0f or ~0 depending >>> on >>> whether the driver supports integers. >>> >>> Also, the float SET opcodes return 1.0f/0.0f so there has to be >>> conversion if the driver supports integers, and the integer SET >>> opcodes >>> are supposed to return ~0. >> >> This is confusing -- so the semantics of e.g., IF's argument, depends on >> whether the pipe driver supports integers or not? >> > > No, TGSI_OPCODE_IF only checks for zero/nonzero (thus NaN counts as
I mean to say float -0. Anyway, the example was confusing, I just meant we do an u32 comparison for drivers that support integers. (This is where TGSI_OPCODE_IF may yield different results for float-only cards, but in practice it's never actually used with anything other than the result of a SET operation.) > true, there is no conversion required, IF may act on any kind of value - > at least that's how all drivers implement it), the representation of > TRUE doesn't matter here. > > The only case I can think of where the actual representation of booleans > matters is when casting/converting them to int or float. > >>> In SM4, all comparison operations return ~0/0. >> >> The way I was envisioning this was that the float SET opcodes would have to >> be redefined as returning these abstract booleans, and one would need to >> combine the SET opcode with a SELECT (i.e, foo ? 1.0f : 0.0f) to match the >> old behavior. Drivers that represent booleans as 0.0f/1.0f floats, would >> simply no-op on the (foo ? 1.0f : 0.0f) SELECT instruction. >> >>> (<= nv40 only support 1.0f, nv50 supports only ~0, nvc0 can do both; >>> conversion is a single instruction (convert to s32 with negation)). >> >> The advantage of not mandating as bit-representation of booleans is that we >> could accommodate all these cases, always the most efficient code without >> requiring peephole optimizers to remove redundant conversions between 1.0f / >> 0xffffffff / 1 representations. >> >> >> On the other hand, if this seems too confusing, then one could just assume >> the pipe driver will eventually optimize these conversions away anyway, and >> establish all booleans are suppose to be 0.0f/1.0f (or 0/~0) >> >> >> I think that allowing multiple and slightly incompatible concepts of >> booleans in TGSI is a recipe for disaster. Note that 0x8000000 is zero for >> floats, and comparison semantics for NaNs are also special. >> >> >> Jose > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev