[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