WineD3D State management - going live(TM)
Stefan Dösinger
stefandoesinger at gmx.at
Thu Oct 19 15:17:32 CDT 2006
Am Donnerstag 19 Oktober 2006 12:08 schrieb Stefan Dösinger:
> Hi,
> I considererd that it would be finally time to get started with the state
> management rewrite :-) Just a mail with the final plan, if anyone has
> comments.
Well, I started with the thing, and I want to show the first results so others
can better see where we are headed :-)
I named the file state.c, no idea why. At the moment it only contains a state
management table which is basically empty. The state management table
contains a representative for each state(e.g. ALPHAFUNC is the representative
for ALPHAFUNC and ALPHAREF, because both states affect the same gl state.
Most states are their own representative for now, this will change when the
stuff is implemented. Those will be used to group render states depending on
each other
For each state there is a pointer to a function for applying the state. At the
moment those pointers are NULL, but later this file will contain static
functions for applying a specific state, referenced by the table. So a state
can be applied by calling
States[STATE_RENDER(RenderState)]->func(IWineD3DStateBlockImpl *);
STATE_RENDER is defined as
#define STATE_RENDER(a) (a)
for sampler states, ..., I will add a
#define STATE_SAMPLER(b, a) STATE_RENDER(WINEHIGHEST_RENDER_STATE +
WINEHIGHEST_SAMPLER_STATE * b + a)
and so on. Simmilar, if needed a STATE_IS_SAMPLER, but I don't think we'll
need that.
For the function that applies all the states in drawprim I was thinking about
2 ways: Using a pointer to the apply function in the table, or inline
functions, aka
LIST_FOR_EACH(dirty_states_list)
{
switch(current_state_number)
{
case STATE_RENDER(D3DRS_LIGHTING)
call_some_inline_function; break;
}
}
This would have avoided a full call+ret for each state that is applied, but
this switch block would grow terribly long, ~500 entries with all states in
one list, or the equivalent number in seperate switch blocks. I think a call
is faster than checking against 500 constants, and it allows us to apply a
single state with ease.
A
for(i = 0; i < HIGHEST_STATE_ENTRY; i++)
{
if(States[i]->func) States[i]->func(Stateblock);
}
will allow us to record a full stateblock into an opengl display list :-)
Concernes:
The state table will get pretty big, with some gaps. I want to allow finding a
state by just going into the array with the state number without having to
search for the state(yes, binary search is easilly possible, but still). We
can stuff the gaps with other states if we really, really want to, and code
for searching might take more memory than the gaps in the list.
The list can get hard to maintain, one missing entry and all pointers go
wrong... But we have to write it only once, d3d10 is unlikely to add more
stuff as the fixed function pipeline was kicked.
Grouping the states: Should work nice basically, but once concern about the
vertex type, lighting, fog, vertex shaders: Fog and Lighting depends on the
vertex type, and fog depends on wether a vertex shader is used. So
D3DRS_LIGHTING, D3DRS_FOGSTART, D3DRS_FOGEND, D3DRS_FOGENABLE,
D3DRS_FOGTABLEMODE, D3DRS_FOGVERTEXMODE, The vertex type, the bound vertex
shader will be linked together. Pretty huge block... Any suggestions about
breaking it up nicely?
More?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: state.c
Type: text/x-csrc
Size: 28636 bytes
Desc: not available
Url : http://www.winehq.org/pipermail/wine-devel/attachments/20061019/8a73739e/state-0001.c
More information about the wine-devel
mailing list