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 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