[Mesa-dev] TGSI declarations missing type info

Jose Fonseca jfonseca at vmware.com
Mon Nov 14 13:03:28 PST 2011



----- Original Message -----
> 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.

But what about 0x8000000 (ie., -0.0f)? That's also zero in IEEE-754 representation, and can arise naturally from evaluating floating point expressions.

So, imagine the condition register contains 0x8000000, and TGSI_OPCODE_IF is implemented with a integer equality against zero. That will give the wrong results.


No, this is too much hand waving.

We need to be consistent -- either we establish that boolean representation is implementation specific and mandate the use of implicit "foo to/from boolean" operations; or we mandate a single representation to be used everywhere. 

This patchwork of different representations is an unsustainable mess -- it seems all nice and easy for simple/obvious use cases now, but will get everybody pulling their hair later when trying to understand why a complex shader doesn't work properly.

One way or the other, the driver should be able to assume/expect that booleans are consistently represented throughout.


Jose


More information about the mesa-dev mailing list