WineD3D: WineD3D: Use the shader backend to enable / disable atifs and nvts

Stefan Dösinger stefan at
Sat Apr 12 06:34:12 CDT 2008

Am Samstag, 12. April 2008 04:27:07 schrieb H. Verbeet:

> Anything that gets ignored when a vertex shader is active gets put in
> the vertex states, anything that gets ignored when a fragment shader
> is active should be part of the fragment states. Resource loading
> would be part of the "other" states.
GL named arrays get ignored when a vertex shader is in use, unless the shader 
explicitly uses them...

> Most of the connections you 
> mention appear to be connections on the D3D side, these would have no
> consequences for a separation on the GL side of things. Iow, it's
> perfectly valid for a state in the vertex block and a state in the
> fragment block to read from the same D3D state.
So if e.g. the vertex declaration is changed you would dirtify many states:
-> misc stream sources
-> vertex shader(use it or not?)
-> Fog
-> Fixed function vertex processing matrices(rhw vertices or not)
-> texture transforms
-> (a few others as well)
I have no problem with doing that, changing the vdecl is an expensive business 
no matter what we do, just asking to make sure I understand what you mean. 
How do you control which gl states are dirtified by which d3d state? This 
will depend on the combination of backends you use.

There are quite a few opengl connections as well, although they work 
differently.It's more the various interactions between shader extensions. In 
quite a few cases the fragment processing implementation has to configure the 
vertex processing correctly to feed it in the right way, and also the other 
way round.

For example, to stick to the texture transform flags. Let's consider we're 
using fixed function D3D vertex processing in whatever GL extension. Now 
enter fragment processing and D3DTTFF_PROJECTED:

-> With fixed function GL or a NVTS fixed function replacement we have to make 
sure that the 4th coordinate is 1.0 to disabe the GL division if 
TTFF_PROJECTED is not set, and if it is set with TTFF_COUNT3 make sure that 
the 3rd coord is copied to the 4th
-> With GLSL or ARB fixed function replacement we can handle the lack of 
TTFF_PROJECTED properly, but not COUNT3
-> With ATIFS we can handle everything properly in the replacement shader
-> With an ARB, GLSL or ATIFS D3D shader we don't need any special texture 
transform fixups
-> With an NVTS D3D shader we have to take care about disabling projected 
textures in vertex processing again

That means different fragment processing implementations have different vertex 
processing requirements. Now you could make that a flag in the fragment 
processing and pixel shader implementation. You'd need 4 
flags(nonshader_unprojected, shader_unprojected, nonshader_count3, 
shader_count3). Are you sure the flags won't grow out of control?

Another example is fogging. Fog is overwritten by ARB and GLSL, but not ATIFS 
and NVTS(as far as I can see). Is fog a vertex or fragment state? How do you 
share the quite complex fog applying code between the ATIFS, NVTS and GL 
fixed function implementation if you make it a fragment state?

> >  Also note that the GLSL pixel shaders depend on the type of vertex
> >  processing(non-GLSL or GLSL) to load the 3.0 varyings correctly. We
> > could get rid of that by requiring GLSL vp, but that would break
> > requirement 4, using the GL fixed function pipeline.
> From the shader's point of view a pipeline replacement should be
> indistinguishable from real fixed function processing, other than that
> in case of GLSL you have to link it together into a single program.
PS 3.0 shaders read texcoords and colors from custom varyings, and D3DCOLOR0, 
1, TEXCOORD0-7 are linked to their predecessors. That way a 3.0 pshader can 
interact with fixed function vertex processing and rhw drawing.(fixed 
function vertex processing is broken on ATI on Windows, but I don't want to 
justify the design with an ATI driver bug. RHW+3.0 is used by e.g. Age of 
Empires 3).

Where would you write the TEXCOORD0-7 and D3DCOLOR0 and 1 varyings from a GLSL 
vertex shader, and where do you read them from in the pixel shader? Keep 
indirect varying addressing in the pshader in mind.

> It's a concern when mixing different shader backends, but I'm not sure
> there's a lot we can do about it there. For fixed function
> replacements it shouldn't matter though, because you always write to
> the predefined fixed function outputs. In that case linking is only an
> issue for GLSL FFP + GLSL shader, which is trivial to implement.
When you're not able to link ARBVP+ATIFS pixel shaders or ATIVP+NVTS then that 
defeats the point of implementing pixel shaders with them, so we have to do 
something about them.

From the mail from yesterday:
> The private data between the FFP replacement and the shader backend
> can be shared. That means our general GLSL management stuff can see
> you've got eg. a FFP vertex shader and a pixel shader and link them
> together.
I am using GLSL for pixel shaders. Can I share my private data with a GLSL 
fragment replacement, or do I have to bother that the fixed function fragment 
processing might be done using ATIFS? Not using GLSL pshaders + ATIFS was one 
of the symtoms for you that "the shader backend isn't the right place to 
implement this".


> I'm currently not too bothered about Intel cards, although that might
> change in the future. Either way, it's certainly possible to create an
> ARB implementation, it's more a matter of priority.
They are pretty widespread and are even used in the EEEPC, so I think dealing 
with these cards will become a priority soon, at least for me. Unfortunately 
the driver sucks in terms of stability and performance.

More information about the wine-devel mailing list