On 11/14/2011 10:13 PM, Jose Fonseca wrote: > > > ----- Original Message ----- >> 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.) > > My other reply was about this particular case. > > But I'm not convinced we can ignore this case at all. I'm fine with drivers > cutting corners. By I can't accept an interface that's broken by design for > all drivers. > > The argument from TGSI_OPCODE_IF may very well come from the > application/state tracker as CONSTs. This means that state tracker would need > to sanitize every const -0.0f => 0.0f, or emit code that did that before > passing the TGSI_OPCODE_IF. >
If it comes from CONST, it will be either a uniform of type boolean, and thus not a degenerate case, or for if ((float)), the compiler / TGSI converter will emit a cast too bool first (i.e. an (F/I/U)SET). It's not as messy as it sounds, we just need to define the exact behaviour of IF, and making its source a float (the *only* other choice to zero/non-zero) seems awkward (since I'm strongly against representing booleans as 1.0f/0.0f if integers are supported.) The only way where we differ from SM4 is that our float comparison ops return floats, and with NativeIntegers, these are always followed by a conversion to our current boolean representation (~0/0). We already have to make a distinction, if integers are not supported, glsl-to-tgsi has to turn all glsl-ir integer operations into float operations. > Take a pick, but please keep this consistent. > > Jose _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev