On 12/04/2008, Stefan Dösinger stefan@codeweavers.com wrote:
- 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.
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.
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.
I'm not sure I follow your reasoning here. Just to be clear, I'm only talking about applying states, not marking them dirty. In the worst case it simply means you apply them when switching back to fixed function instead of in the current draw call, but you could potentially save some redundant state applications while the shader is active. However, what I was actually wondering about is if it might be more expensive on some drivers to do fixed function state changes while a shader is active.
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 interconnections.
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. 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.
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 constants?
In the shader backend. Splitting things up doesn't change much there. You could decide to not even expose constant loading though, and instead just mark the state dirty on the shader backend. Deciding when to load constants then becomes the responsibility of the shader backend.
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.
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.
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. I'd prefer to keep this discussion focussed on fixed function implementations though. GL3, D3D10 and splitting up the shader backend are certainly interesting, but at this point it just distract from the core issues.