WineD3D State management - going live(TM)

Stefan Dösinger stefandoesinger at
Thu Oct 19 05:08:57 CDT 2006

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 

I will move the functions applying the states into a new file, 
opengl_utils.c(name inspired by old ddraw). I don't want to put them into 
drawprim.c because that file is already quite long.

For the start I will manage changed states per device, and not per context 
because for per context tracking I'd like to have thread safety which will 
take a bit longer to commit. The changed states will be managed in a standard 
wine list, with pointers to the dirty elements from the stateblock(the 
state.changed field). This will allow us to work efficiently with the list:

* Add an element: Constant complexity
* Remove an element: const
* Check if an element exists: const(look at the stateblock)
* Empty the list: const
* apply the changed states from the list: linearly growing with the number of 
dirty states, max the number of existing states.

I I will chain empty elements in a 2nd list to avoid unneccessary HeapAlloc 
and HeapFree calls. Many d3d games spend 10% processing time in heap 
management already :-/

All states(render state, sampler, texture stage, bound textures, shaders, 
vertex type) will share the same list. The index of the changed state will 
identify the type of the state, e.g.

#define renderstate_entry(a) (a + 0)
#define samplerstate_entry(a) (a + 1000) /* or 
#define texturestate_entry(a) (a + 2000)
and so on

This will allow us to group different states, e.g. D3DRS_LIGHTINGENABLE with 
the vertex type.

As many d3d states affect the same opengl state(e.g. D3DRS_FOGVERTEXMODE, 
D3DRS_FOGTABLEMODE, D3DRS_FOGSTART, D3DRS_FOGEND), the states can be grouped 
together for efficient application. This also works accross different types.

When a state is marked dirty the Set*State function checked if the state 
gropup representative is already marked dirty, and if yes then the state 
isn't put on the list again. This keeps the list size <= the number of known 
states, and avoids applying the same state 2 times :-)

States will be applied in drawprim. BltOverride and UnlockRect change states 
on their own, and they can put the states the change onto the dirty list so 
drawprim will reset them to what the application wants. This avoids gratious 
setting and resetting. An extra last_was_blt field could be used to avoid 
that bltoverride sets its own states again and again.

Any comments on that?

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url :

More information about the wine-devel mailing list