Not sure about the _utils part there, since it's pretty much core functionality, but fair enough.
well, we can use other names too :-) opengl_state.c, opengl_AllOtherStuff.c
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 renderstate_entry(max_render_state) #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.
Can't you do that without putting everything in a single list?
Basically yes, but is there a problem with a single list? I think it makes the code simpler to have a single list.
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.
I think typically that only goes for states from the same type, ie different render states that affect the same GL state or different texture stages that affect the same GL state, but not so much across state types. ie, it should be fairly uncommon for a render state to affect the same state as a texture stage state.
Yes for texture state and render state(*), but for example the vertex type affects lighting and fog, which is also affected by render states.
(*) In earlier versions texture stage states used to be render states(D3DRENDERSTATE_MINFILTER, D3DRENDERSTATE_MAGFILTER, D3DRENDERSTATE_TEXTUREMAPBLEND, ...). But those states are forwarded to texture stage states / sampler states in ddraw, so we don't see them in wined3d.
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.
Display lists could possibly help there as well, and might be easier / faster than integrating those functions into the state management. You would have to benchmark that to be sure though.
My idea is to write the state applying code to be able to record setting a number of states into a display list, for easier use in stateblocks. When creating a stateblock we could do that
glRecordList(stateblockImpl->glList); /* or whatever the function is called */ for(i = 0; i < all_known_states; i++) set_state(i) glEndList(stateblockImpl->glList);
StateBlock::Apply can use the list to set the states glCallList(This->list); clear_dirty_state_list();
I assume you won't be changing everything over in one go, so perhaps it would be best to start with the texture stage states, since those are currently reapplied every drawprim call, and should be pretty easy to group.
Yup. Although I will start with render states, because breaking up the texture stage state + sampler state + active texture compound will be a bit tricky.
One concern I've got about lumping all the state changes together right before the drawprim call is that we might lose some CPU/GPU parallelism. I guess we won't be able to see how that affects things until it's pretty much done either, but it's probably a good idea to run some proper benchmarks before sending any patches in. (It might actually be a good idea to do that in general).
Ack.
Although I think regarding parallelism it can't be worse than it is at the moment :-)