[Mesa-dev] [PATCH] tgsi: document and fixup IF and BREAKC instrunctions
Roland Scheidegger
sroland at vmware.com
Thu Apr 11 14:53:27 PDT 2013
Am 11.04.2013 22:52, schrieb Zack Rusin:
>> ----- Original Message -----
>>> ----- Original Message -----
>>>> Ah.. This indeed rings a bell. I don't recall the details but I'm pretty
>>>> sure
>>>> I was against dual semantics. And the fact that this problem is again
>>>> showing its ugly head is the proof of it.
>>>>
>>>> We really should have two IF opcodes. And the state tracker should choose
>>>> which one it wants.
>>>
>>> What would be the difference between those two opcodes though?
>>
>>> The current IF
>>> does a bitwise comparison,
>>
>> No, according to Marek, the current IF code has two possible behaviors:
>> - a float comparison for drivers which do not support native integers (i915)
>> - a bit comparison for drivers which support native integers (others)
>>
>> This would be the different for both opcodes. We could call the former FIF or
>> just IF, and the later UIF.
>
> Yes, I understand what you're arguing for, I don't understand how you want to get there with those two opcodes. Do you want to change the current tgsi exec behavior of IF and introduce a new UIF opcode or do you want to introduce a new FIF opcode that does the float comparisons? Also, which one does the current glsl compiler depend on?
For this prog,
void main()
{
if (gl_FragCoord.x < 30.0)
gl_FragColor = vec4(1.0, 0.0, 0.0, 0.0);
else
gl_FragColor = vec4(0.0, 1.0, 0.0, 0.0);
}
the compiler will generate this (with native integers):
0: ADD TEMP[0], IN[0], IMM[0].xxyy
1: MAD TEMP[0].y, TEMP[0], CONST[0].xxxx, CONST[0].yyyy
2: SGE TEMP[1].x, IMM[0].zzzz, TEMP[0].xxxx
3: F2I TEMP[1].x, -TEMP[1]
4: IF TEMP[1].xxxx :2
5: MOV TEMP[1], IMM[0].wyyy
6: ELSE :2
7: MOV TEMP[1], IMM[0].ywyy
8: ENDIF
9: MOV_SAT OUT[0], TEMP[1]
10: END
I doubt that's optimal (really shouldn't use sge/f2i), but clearly it
thinks the argument of the IF is a boolean-as-int. In the glsl ir itself
those if conditions are always a bool.
But, if you don't have native integers, it's this instead:
0: ADD TEMP[0], IN[0], IMM[0].xxyy
1: MAD TEMP[0].y, TEMP[0], CONST[0].xxxx, CONST[0].yyyy
2: SGE TEMP[1].x, IMM[0].zzzz, TEMP[0].xxxx
3: IF TEMP[1].xxxx :2
4: MOV TEMP[1], IMM[0].wyyy
5: ELSE :2
6: MOV TEMP[1], IMM[0].ywyy
7: ENDIF
8: MOV OUT[0], TEMP[1]
9: END
So it looks like this is already dual semantics depending on native
integer support, so we can't win (I guess technically if this is the
expected behavior, we broke this with llvmpipe when we announced support
for native integers).
Well if we don't want dual semantics we could define another
instruction. I'm still not sure there's much point though, since afaik
the argument being a different type is just because booleans are either
stored as ints (with native integers) or floats (and IIRC a boolean
float is either 1.0 or 0.0, whereas it's ~0 and 0 for native ints). So
as long as we only require "bool" behavior, this should be alright, only
with the any-bit behavior this might be a bit problematic but again I
can't see why this would make sense for drivers which don't support
native integers.
Roland
More information about the mesa-dev
mailing list