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.

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

Reply via email to