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

> 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

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to