[Mesa-dev] TGSI declarations missing type info

Christoph Bumiller e0425955 at student.tuwien.ac.at
Mon Nov 14 13:36:17 PST 2011


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



More information about the mesa-dev mailing list