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

Stefan Dösinger stefan at
Sat Apr 12 17:28:16 CDT 2008

Am Samstag, 12. April 2008 19:55:53 schrieb H. Verbeet:
> Which is completely irrelevant for classifying the operation.
> Please read the ARB_vertex_program spec, issue 3 and the
> ARB_fragment_program spec, issue 13 to get a better idea of what
> shaders replace and what they don't.
Yes, GL says so, but I think strictly sticking to the GL classification is a 
bad idea, see below.

> If the issue is that you've got an interest in keeping the existing
> structure because you've already written code on top of it there's not
> much point in having this discussion in the first place. If that's not
> the issue, I'd like to mention that the whole point of having
> interfaces is that you can avoid ugliness like setting vertex
> processing state in the fragment processing part of the pipeline.
> There's also nothing forceful about splitting your pipeline in vertex
> and fragment processing, that's how the hardware works, it's how GL
> works, and it's how D3D works.
I agree that GL works that way(fragment-vertex split), and almost certainly 
graphics hardware as well, although we don't know unless we look at the 
drivers(how the hardware works is irrelevant since GL abstracts that). 
However, D3D does *not* work that way, otherwise there would not be any issue 
to discuss here, since then D3D states would perfectly match the GL ones. 

As I understand it, this discussion comes down to the designing the state 
setting interface and implementation in an OpenGL oriented way or a D3D 
oriented way.

@ keeping old code: That's not too much of an issue, but you attacked my 
design on the grounds of a missing implementation of a functionality, so I 
explained how that would be implemented.

> > device->fragment_state_manager->mark_state_dirty(device->fragment_private
> >_data,
> >
> >  > state);
> >
> > Where does "state" come from?
> I don't remember you asking, but I see no reason to change the basic
> way dirtification is currently done.
Where does SetRenderState(or any other state setter) know if it has to dirtify 
a fragment, vertex, misc state, or multiples of them?

> >  > if (!use_vs) {
> >  >    
> >  > device->vertex_state_manager->apply_states(device->vertex_private_data
> >  >); }
> > >
> > > ...
> >
> >  This would be done where?
> ActivateContext, CTXUSAGE_DRAWPRIM. (Yes it should probably be part of
> the context, not the device, my bad.)
That means polling the states that use_vs() and use_ps() check for changes 
instead of getting notified about changes, as well as polling the 
SetPixelShader and SetVertexShader settings(via select_shader()). Avoiding 
polling was one of the goals of the state management rewrite more than a year 
ago. I don't think there's any relevant performance penalty in doing the 
little polling you suggest, but where do we draw the line?

> The pipeline object would certainly have access to all the information
> required to create such a reordering function, but I fail to see how
> it's relevant at this point. The idea here certainly isn't to
> magically fix all state and shader related issues in wined3d, it's
> just about making fixed function replacement shaders possible in a
> maintainable way.
It is insofar relevant as it affects the issues we can later on fix with the 
pipeline replacement and which we cannot. If the GLSL vertex pipeline 
replacement shader can only write to the builtin varying because the pixel 
shader input expects it that way, we'll never be able to fix the todo_wines 
in fixed_function_varying_test() in visual.c

> ...
> There really is no distinction between "pixel shader private data" and
> "ffp replacement private data", they're both pointers to the same
> block of memory, and eg. the shader backend will always only get
> passed its own private data.
Point taken, I see now how you can sort that out the fixed function 
replacement vs shader activation in the same backend via the private data. 
You'll have to watch out though that the default initialization value is a 
valid "do not load a replacement shader" request.

> I'd also like to note that most of the issues you bring up are not new
> or specific to this design at all, and some of them wouldn't work at
> all with the current structure.
Surely they aren't specific, but I do not see any that would not work with the 
current structure. Agreed, using ATIFS fragment processing + ARBFP / GLSL 
pixel shaders needs 3 inherited ATIFS shader backends, which is ugly, I 
agree. But it does not hide the ugliness and makes the issues that mixing GL 
shader functionality causes explicit. It does not limit the fixed function 
replacement to the lowest common denoimator(GL fixed function) and allows us 
to flexibly use additional features of GL extensions or GLSL to fix bugs we'd 
otherwise have to mark as WONTFIX.

I think designing the state setting interface in a D3D oriented way is better 
because it is opengl extension independent. If the state setting API is built 
on the GL state classifications some additional layer to deal with the 
differences of the state implementations is needed(e.g. by giving vertex, 
fragment and misc state setters a full state table each). Additionally with 
the splitup there is the already discussed hidden issue of implementation 
interactions which I don't think can be consumed in the abstraction layers, 
and the mentioned issue with the lowest common denominator interface of the 
fixed function replacement shaders.

More information about the wine-devel mailing list