[virglrenderer-devel] Thoughts about TGSI-to-GLSL and improvements and beyond
Dave Airlie
airlied at gmail.com
Mon Sep 17 00:48:46 UTC 2018
On Sat, 15 Sep 2018 at 00:22, Gert Wollny <gert.wollny at collabora.com> wrote:
>
> Dear all,
>
> Erik and me collected a few thought about the TGSI to GLSL translation
> code. Here is the result:
Thanks for the analysis!
>
> Current problems and possible solution:
> ----
> P:
> * using fixed-size buffers for some code creation
> * all concetations call realloc
>
> S:
> * Use glib strings
> + glib is a qemu dependency, so the addition is no real burden
> - except for non-qemu users? (like crosvm?)
> + glib is widely used an probabably available somewhere in chromeos
> + crosvm uses rust, so doing it in rust would make sense there
> + supports growing strings as needed,
> In order to avoid too many re-allocations a translation context
> can hold a few buffers that grow as needed and are kept around
> With gcc and clang there is even an auto-pointer like feature for
> glib types
>
> Alternative: implement a simple growing string-buffer ourselves
> It's not that hard can be coupled with some domain-specifics, like
> automatically generating the right level of indentation.
>
> In a more radical approach one could also think about using a real OO
> language for this (C++, Rust, D, ... )
The other option if the realloc overhead is too much is just to move
to chunked allocations, so we realloc + 4k everytime we need to rather
than doing it on a string basis. I think we'd just have to store a
global size or pull around a struct instead of the char *, granted
glib strings might be a bit cleaner and I've no objections to pulling
in glib as a dependency either. I'd like to have some idea of how much
this could improve translation perf, I don't think shader translation
perf is going to be that bad for us but I'm sure there are plenty of
cases where using less CPU is going to be better.
> P:
> * lots of code duplication
> S:
> * replace the in-lined strings for build-ins with constants
> * Move the duplicated code in the case chains into functions
> * use some object-oriented approach to handle the different shader
> types
> * Lots of small, composable helpers to emit things?
I think we've started moving in that direction already with
Gurchetan's work, I think looking to other projects in the area like
wine might have some value, as they do similiar translations on
shaders. Though I loosely based our translation on wine's to start
with. So I do see that this might help, but I think I'd want more
definite goals than just moving the code around, I'm not sure how
unmaintainable what we have now is, but I'm also not sure how much
code needs to be added to it to complete GL4.x support, at which point
it's pretty much a completed body of code.
>
> ----
> P:
> * VS GLSL code needs to be patched based on FS (possibly also
> TESS_EVAL and GS could need this, but so far there is no test case)
> S:
> * decouple parsing the TGSI from creating the GLSL
> - This would add another layer with an additional IR
> + Can we do this on the mesa-side? Most gallium drivers don't finish
> off compiling shaders until draw. Perhaps we could do the same,
> and then have the "full perspective"?
We delay compiling on the host side util draw anyways, I'm not sure
how often early compiling works out for us and we don't end up
recompiling on the first draw (probably never). We actually do patch
gs/tes the function is just misnamed. We always patch the last shader
gs->tes->vs.
> P:
> * TGSI might not be the best suited IR:
> - Probably not going to get *that* much more love in the future,
> due to NIR taking over
> - We already diverged from upstream
> - Untyped TGSI-registers leads to a *lot* of bitcasts.
> Can result in slow to compile shaders
> - and quite possibly slow to run, because a lot of on-line shader
> compilers don't optimize too much ... especially on mobile
> Note: NIR has the same problem ...but easier to figure out, due to
> SSA form
There's quite a lot of realworld shaders which have a lot of bitcasts,
I think compilers should be handling that case pretty well now.
(Anyone who writes shaders in HLSL will end up with GLSL that is just
as ugly as ours)
If we find any specific cases where a compiler really does worse in
practice then I think we can enter into dealing with it if the vendor
isn't or won't fix it, but I don't think we should preempt this
problem, unless we have hard figures where we can show the compiler
outputs pure garbage and removing some of the bitcasts in advance will
help.
>
> S:
> + Introduce a more reasonable IR? (see above)
> + Could we get away with sending GLSL to the guest instead of TGSI?
> - I guess one reason not to send the GLSL would be to not send
> literal strings to the host that could be used to exploit
> vulnerabilities in the host shader compiler
> + How about SPIRV?
> Has a stable, actively maintained serialization, and SPIRV-Cross can
> turn
> it back to GLSL in case the host lacks GL_ARB_spirv
> (part of OpenGL 4.6)
TGSI has many advantages, and I think from the POV of GL 4.5 and
GLES3.2 I think we might be best sticking with what we have, Vulkan
and GL_ARB_spirv opens up some new possibilities
GLSL isn't useful, we have a goal to support Windows guests (and
someone has recently started working on it). GLSL is way too unwieldy
and freeform to be handing across the boundary, we'd never cover all
the holes in parsing it, and we'd have to parse or patch it on the
host side most likely, we'd hardly ever just be passing through GLSL
from the guest apps.
SPIR-V is a more interesting proposition, it suffers from some
deficiencies in terms of what is supports (no transform feedback
supported in public yet) and I'm not sure we could use it to cover all
the GL cases, GL SPIR-V has a number of restrictions on it vs GLSL
which would make in unsuited as our transport at present.
Going forward I do think we will want to pass SPIR-V across for both
Vulkan and GL4.6 SPIR-V support, but we will want to have tools to
patch and rewrite the SPIR-V code on the host side.
The big advantage we have with TGSI is we have control over it going
forward, and we can add features without going via standards bodies,
we can enforce our own versioning on it. It however isn't great due to
it's VEC4 nature and some other areas.
I suspect we would want to start looking at how we can use SPIR-V and
where the big holes will end up, and we leave TGSI as our default
position until we figure it out.
Gurchetan, I think SPIRV-Cross has some introspection support in it
alright, (you asked in your reply I think).
Dave.
More information about the virglrenderer-devel
mailing list