[virglrenderer-devel] TGSI to GLSL translator type assumptions

Gurchetan Singh gurchetansingh at chromium.org
Tue May 1 17:44:17 UTC 2018


On Mon, Apr 30, 2018 at 1:27 PM, Dave Airlie <airlied at gmail.com> wrote:
> On 28 April 2018 at 12:03, Gurchetan Singh <gurchetansingh at chromium.org> wrote:
>> I was wondering about the typing assumptions in vrend_shader.  The
>> TGSI spec says that "all TGSI instructions, known as opcodes, operate
>> on arbitrary-precision floating-point four-component vectors."
>>
>> http://gallium.readthedocs.io/en/latest/tgsi.html
>>
>> However, some instructions such as UMAD / UMUL / ATOMIMIN have integer
>> source and destination registers, so I assume these instructions are
>> exceptions to the spec.
>
> There are tgsi_opcode_infer_src_type and tgsi_opcode_infer_dst_type interfaces,
> however there may be some cases missing in those.
>
>> One assumption we make is all temporary registers
>> (TGSI_FILE_TEMPORARY) are a vector of floats.  We do a lot work making
>> this assumption hold, with many conversions.  For example, the
>> following TGSI:
>>
>> https://pastebin.com/PN8eHDvZ
>>
>> currently produces this GLSL:
>>
>> https://pastebin.com/p90gevMA
>>
>> I'm interested in the possibility of removing the
>> "float(uintBitsToFloat)" and "int(floatBitsToInt)" steps, since I've
>> found it to be a source of many bugs.  I would like to produce a GLSL
>> like this:
>>
>> https://pastebin.com/fJCqYEjj
>>
>> By inferring the type of the declarations from the opcodes.  We would
>> copy the tgsi_full_instruction(s) that are emitted in
>> iter_instruction, deduce the type of the declarations, and then emit
>> the declarations and instructions.  Is this advisable?
>
> The main reasons I just go with all register being floats is when I wrote
> this originally I left the possibility for using GL2.1 on the host which doesn't
> have GLSL which necessitates integers (though I'm not sure I ever tested
> that path much), and I didn't want to diverge too much from what TGSI expects.
>
> TGSI expects floats in all those places, and while adding the bitcast conversion
> is ugly, it is definitely the surest way to avoid bugs, as when you
> miss one things
> usually break.
>
> Do you want temps to be always ints now? or try to infer the temp type?

Yes, I would like to infer declaration types.  My desire for some sort
of deduction step is based on issues I had with SSBOs on the GLES31
branches.  For example, if we assume all SSBOs are uvec4's, how can we
implement ATOMIMAX / ATOMIMIN (I shader compilation errors when I cast
mem parameter of atomicMax / atomicMin to an int)?  Fixing the
temporary issue is a related but separable problem.

> how does that handle I2F TEMP[0], TEMP[0] type scenarios?

There's a few options:

1) The type of a conflicting register defaults to floats.
2) The type of a conflicting register is the type to which it is most
frequently assigned.
3) Add more temporary registers.  Every-time TEMP[0] changes it's type
due an opcode, there would be another variable TEMP[0]_1 that has the
proper type.  With proper book-keeping, we would place TEMP[0]_1 into
places where TEMP[0] was (TEMP[0] reference to TEMP[0]_2 if  TEMP[0]_1
changes type too).  This would produce at most 3 times more registers
than the TGSI (TEMP[0]_0 ==> floats, TEMP[0]_1 ==> integers, TEMP[0]_2
==> unsigned).  It would remove casts in the GLSL and replace them
with additional storage, so that may not be desirable since I assume
storage is more costly.  It really depends on the relative proportion
of opcodes like  I2F, U2F compared to other opcodes.

>and temp arrays with different types,

Each temp vector would be typed individually, so no more arrays like
vec4 temp0[5].  It would be more like:

ivec4 temp0;
vec4 temp1;
uvec4 temp2;
...

> I'd need a lot more info and some example shaders using floats to see
> how it would end up.

Here's an example shader:

https://pastebin.com/Pu5E0SVG


> Dave.


More information about the virglrenderer-devel mailing list