[Mesa-dev] TGSI declarations missing type info

Jose Fonseca jfonseca at vmware.com
Wed Nov 16 02:08:37 PST 2011



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

I'm entirely in agreement with you that IF behavior must be precisely defined .

But I strongly oppose having the semantics of IF varying with integer support. In that case, lets just add an IIF (integer IF) opcode, etc.

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

Fair enough.


I've been thinking about my proposal of leaving boolean implementation independent, and indeed is more work that I initial thought for little benefit, as the having values in an undetermined representation in TEMP registers creates all sort of issues. For this to work we would need to use a separate register namespace, e.g., PREDicates. So not that interesting.


Jose


More information about the mesa-dev mailing list