BlamKiwi / angleproject

Automatically exported from code.google.com/p/angleproject
Other
0 stars 0 forks source link

Add support for emulating lower precision in shaders #787

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Bugs resulting from shaders not having been tested on lower-precision mobile 
hardware are a relatively common occurrence. To help test shaders for this kind 
of bugs without needing a wide array of hardware, lower-precision emulation 
could be built into ANGLE.

It is possible to implement an ESSL function that approximately rounds numbers 
to a lower precision float format. If ANGLE would wrap all float operations in 
lowp and mediump precision with such a function, this would in effect emulate 
how hardware with the given precision would operate and the shader would still 
be able to run on the GPU.

This functionality could be behind a flag that could be set by developer tools 
in projects using ANGLE.

Original issue reported on code.google.com by oetu...@nvidia.com on 14 Oct 2014 at 3:14

GoogleCodeExporter commented 9 years ago
See http://glslsandbox.com/e#20238.6 for a prototype for the ESSL function.

Original comment by oetu...@nvidia.com on 14 Oct 2014 at 3:28

GoogleCodeExporter commented 9 years ago
This is probably relatively straightforward. In OutputHLSL::visitBinary() we 
currently call outputTriplet() for most operations, to output the code before, 
at, and after traversing the AST node. You could replace it with e.g. an 
outputBinary() function which surrounds the binary operation with FRM() if 
lower precision emulation is enabled.

visitUnary() would need similar treatment, and 
generateVertexShaderForInputLayout and generateShaderLinkHLSL will have to call 
FRM() on the shader's input.

Original comment by nicolasc...@google.com on 14 Oct 2014 at 4:02

GoogleCodeExporter commented 9 years ago
nicolas: Sounds promising. Does ANGLE also track precision information for the 
AST nodes, so that the FRM calls can only be added where the shader source is 
actually specifying mediump precision for operations? GLSL ES spec has a bunch 
of rules on how operation precision is determined.

Original comment by oetu...@nvidia.com on 15 Oct 2014 at 12:54

GoogleCodeExporter commented 9 years ago
I've done a bit of investigation on this, and it seems like built-in math 
functions do not propagate precision of their arguments in ANGLE. ESSL spec 
4.5.2 does suggest that they should do this. Binary math operations do 
propagate precision correctly. I'll look into fixing this.

Original comment by oetu...@nvidia.com on 20 Oct 2014 at 3:40

GoogleCodeExporter commented 9 years ago
I spotted the issue concerning built-in math functions. 
src/compiler/translator/glslang.y sets the correct precision on the unary op 
node by using TIntermediate::addUnaryMath -> TIntermUnary::promote. However, 
the type of the return value is then overridden by this call: 
$$->setType(fnCandidate->getReturnType());

I'll develop a fix for this.

Original comment by oetu...@nvidia.com on 21 Oct 2014 at 2:05

GoogleCodeExporter commented 9 years ago
I now have the first complete working prototype implemented in the GLSL 
translator in ANGLE. Shader performance is expectedly low, and instruction 
count limits may be a problem with some long shaders, and some operators are 
not yet supported (particularly ++ and --, which look very hard to support). 
However, despite these limitations it seems like this would make a very useful 
tool. Many shader bugs are instantly revealed, and on a high-end GPU 
performance is still good enough for running complete games, like Unity's Angry 
Bots demo.

Original comment by oetu...@nvidia.com on 31 Oct 2014 at 2:57

GoogleCodeExporter commented 9 years ago
The support was recently added for ESSL and GLSL output. Marking as fixed.

Original comment by oetu...@nvidia.com on 2 Dec 2014 at 10:07