On 2010-07-14, at 3:22 AM, Steve Baker wrote:
Sorry, no. I don't have an example of the problem easily to hand - I've
changed jobs twice since the last time this happened to me - and it
presumably hasn't happened since then because I've been using ftransform.
It's really tough to come up with examples (unless, of course your game
is going gold next week and suddenly everything breaks because someone
changed a shader constant someplace).
Yes I know. That's why I was hoping you had something on hand which had cause you problems...
But sadly, having an example that breaks under OpenGL (if you don't use
ftransform or invariant) - and then showing that this same exact example
DOESN'T break under D3D doesn't in any way demonstrate that some other
example wouldn't break. The way these compilers optimize varies from
platform to platform even for the same hardware vendor...so unless you
have a cast-iron guarantee of invariance - no amount of "Look! This
example doesn't break!" would be convincing proof of a non-problem.
That is a valid point as well.
I've gotta say though - Microsoft's "solution" (as quoted below) is just
lame! They are essentially saying "Well, you can solve the problem by
turning off shader optimization"...but that means that you have to have
the entire shader pessimally compiled just to stop a one or two line
problem! Whoever thought THAT was an adequate response totally didn't
understand the scope of the problem! When this problem strikes - it
affects every single shader the project uses - since they all need to
manage multi-pass correctly.
No that's not what they are saying. They said they are "providing selectable, well-defined optimization levels that must also be respected by the driver compiler." I believe this to mean that they have strictly defined the optimizations that the drivers are allowed to do, and the intent is to only allow optimizations which wouldn't cause invariance problems. What exactly those rules are, I don't know, but I would certainly like to! However I am quite certain that they would have examined the problem in great detail, even if the detail didn't manage to make it into that particular article.
On 07/13/2010 12:29 PM, Daniel Koch wrote:
The problem is that there is nothing like the "invariant" keyword in
D3D9 HLSL (or even D3D10 HLSL for that matter) that I am aware of.
In practise, there must be some form of invariance guaranteed by d3d9
(especially for position), since I know of many games which use
multi-pass rendering algorithms which work just fine. The difficulty
lies in figuring out exactly what is guaranteed by D3D9, since we've
been unable to find any sort of public documentation or discussion of
these issues. However, even if there is position invariance, this
does not provide a mechanism to toggle invariance on and off on a
per-variable basis as is required in GLSL.
The closest thing we've been able to find is a SIGGRAPH article on
D3D10 from Microsoft.
They briefly allude to this problem in section 5.4:
"We considered several solutions for how to specify invariance
requirements in the source code itself, for example, requiring
that subroutines be compiled in an invariant fashion even if they
are inlined. However, our search ultimately led us to the more
traditional route of providing selectable, well-defined
optimization levels that must also be respected by the driver
My assumption is that D3D9 must have had similar requirements.
The version of Cg that was open-sourced is quite archaic at this
point. The ANGLE compiler is open-sourced
(https://code.google.com/p/angleproject/) and is based off the 3DLabs
GLSL compiler. It compiles GLSL ES to HLSL9 which is then compiled
to D3D9 byte-code using D3DXCompileShader. A future extension to
ANGLE could be to generate D3D9 byte-code directly. However, even
D3D9 bytecode is still an IL and there is no guarantee that the
hardware executes those instructions exactly (and I know there are
implementations which do compile/optimize this further).
The issue raised about ftransform in CG and GLSL and position
invariance was primarily an issue when using fixed function and
shaders together, and it was indeed a very common problem. This is
also why the "position_invariant" option was added to the
ARB_vertex_program assembly extension. Examples of this occurring in
shader-only applications are much more difficult to come by.
Ideally, an example program which does exhibit invariance issues in
webgl (or GLSL or GLSL ES) would be available to demonstrate that
this is actually a real problem for webgl. If that existed, we could
verify whether or not ANGLE on D3D9 has such problems, or if it just
Steve Baker: do you have any such examples, or would you be able to
put one together which demonstrates this problem?
We are continuing to investigate the guarantees provided by D3D in
this area and a concrete test case showing such issues would be
invaluable for this.