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

Stefan Dösinger stefan at
Fri Apr 11 17:57:57 CDT 2008

Am Freitag, 11. April 2008 22:42:17 schrieb H. Verbeet:

I did not yet read it in depth, so I am just replying to a few concerns I 
spotted. I'll look at it more in-depth tomorrow.

> >  1) The state table should be selectable based on the available opengl
> > features and possibly registry settings. I think we all agree on that
> Up to the level of being able to use different state handlers in
> different situations. I don't necessarily agree with copying and
> swapping the entire table in one piece.
Agreed, we just want to be able to swap states, in which way is open.

> >  2) We want a fixed function vertex and fragment pipeline replacement
> > with ARB and GLSL
> Only GLSL is a requirement for me. ARB could be nice, but is probably
> redundant.
Intel cards? Also GLSL has the problem with the link times.

> >  5) A nice to have is to be able to use the replacement pipelines
> > together with shaders, but that is not a hard requirement for me. We need
> > an ARB and GLSL replacement anyway.
> I assume you mean atifs & nvrc specifically here, in which case this
> is probably a bit more important than "nice to have". The most tricky
> situation to support here will be cards that support vertex shaders,
> but not fragment shaders. If we want to support pixel shaders using
> atifs / nvrc we have to allow mixing GLSL / ARB with nvrc / atifs for
> it to be of any use.
The current implementation allows that, we're using ATIFS+ARBVP

>  Aside
> from being clearer this allows you to swap these parts out
> independently from each other and possibly skip applying them as a
> whole in case a shader is active for that part of the pipeline (I
> imagine this could have some performance advantages as well, although
> I'm not sure how much).
For the performance, it depends on the app. If we skip applying (redundant) 
fixed function settings when a shader is used, we have to reapply all of them 
the shader use might have changed when the shader is deactivated. It's a 
decision between making shader on-off switches cheap vs filtering out 
redundant state changes done by the app. Currently there is no additional 
fixed function pipeline cost involved when using shaders as long as the app 
doesn't touch the ffp states.

> struct IWineD3DDeviceImpl {
>     ...
>     struct state_management_t vertex_state_manager;
>     struct state_management_t fragment_state_manager;
>     struct state_management_t other_state_manager;
>     struct shader_backend_t shader_backend;
>     void *vertex_private_data;
>     void *fragment_private_data;
>     void *other_private_data;
>     void *shader_private_data;
>     ...
> };
One of the reasons for using a single state table was that we have 
interconnections between the vertex states, fragment states and other states. 
For example, where would you put the vertex buffer loading? Is that 
an "other" state, or a vertex state? The FVF and the vertex shader influence 
if we're entering the FF or shader vertex processing codepaths. The FVF 
affects fogging, which is a vertex state in some shader implementations(nvts, 
atifs), but implemented in pixel shaders in GLSL and ARB. The texture 
transform flags are a fixed function vertex state on paper, but we have to 
compile the D3DTTFF_PROJECTED flag into the fragment shader. (we already do 
so, that's documented on the msdn, so clearly a missdesign on Microsoft's 
side). There are many more examples of vertex-fragment-other state 

> This doesn't support mixing eg. ARB vertex shaders with NVRC pixel
> shaders, but it would "simply" be a matter of splitting up the shader
> backend in a similar way to the state table. Important to note here is
> that the private data could be shared between fixed function
> replacements and the shader backend, like in the case of GLSL. I could
> imagine using a structure more similar to state_management_t for the
> shader backend as well.
The unsplit shader backend is the current d3d shader implementation + Ivan's 
pipeline linker object. If you split them up, where do you set GLSL shader 

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.

My concern is that if you split vertex processing and fragment processing up, 
you need a linker object that deals with linking. This linker object has know 
about the vertex and fragment processing state handlers and tables, thus 
creating a special linker for each vs-ps-vff-ffp-other combination. I don't 
have any objections against that in principle, but I am afraid that due to 
the high interconnection between vertex, fragment and other states we would 
end up with implementing most things in the linker.

More information about the wine-devel mailing list