wined3d: Start the state splitup.

The idea of this patchset is to split the monolithic state set into 3
parts, vertex processing, fragment processing and other states(depth,
stencil, scissor, ...). The states will be provided in templates which
can be (mostly) independently combined, and are merged into a single
state table at device creation time. This way we retain the advantages
of the single state table and having the advantage of separated
pipeline implementations which can be combined without any manually
written glue code.
This commit is contained in:
Stefan Dösinger 2008-07-01 18:23:44 -05:00 committed by Alexandre Julliard
parent 155d3ac4cc
commit 98faed8ff5
6 changed files with 21 additions and 10 deletions

View File

@ -859,7 +859,7 @@ struct StateEntry ATIFSStateTable[STATE_HIGHEST + 1];
static void init_state_table() {
unsigned int i;
const DWORD rep = STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP);
memcpy(ATIFSStateTable, arb_program_shader_backend.StateTable, sizeof(ATIFSStateTable));
memcpy(ATIFSStateTable, arb_program_shader_backend.StateTable_remove, sizeof(ATIFSStateTable));
for(i = 0; i < MAX_TEXTURES; i++) {
ATIFSStateTable[STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP)].apply = set_tex_op_atifs;

View File

@ -102,7 +102,7 @@ static WineD3DContext *AddContextToArray(IWineD3DDeviceImpl *This, HWND win_hand
/* Mark all states dirty to force a proper initialization of the states on the first use of the context
*/
for(state = 0; state <= STATE_HIGHEST; state++) {
Context_MarkStateDirty(This->contexts[This->numContexts], state, This->shader_backend->StateTable);
Context_MarkStateDirty(This->contexts[This->numContexts], state, This->StateTable);
}
This->numContexts++;
@ -641,7 +641,7 @@ static inline void set_blit_dimension(UINT width, UINT height) {
*****************************************************************************/
static inline void SetupForBlit(IWineD3DDeviceImpl *This, WineD3DContext *context, UINT width, UINT height) {
int i;
const struct StateEntry *StateTable = This->shader_backend->StateTable;
const struct StateEntry *StateTable = This->StateTable;
TRACE("Setting up context %p for blitting\n", context);
if(context->last_was_blit) {
@ -836,7 +836,7 @@ static inline WineD3DContext *FindContext(IWineD3DDeviceImpl *This, IWineD3DSurf
BOOL oldRenderOffscreen = This->render_offscreen;
const WINED3DFORMAT oldFmt = ((IWineD3DSurfaceImpl *) This->lastActiveRenderTarget)->resource.format;
const WINED3DFORMAT newFmt = ((IWineD3DSurfaceImpl *) target)->resource.format;
const struct StateEntry *StateTable = This->shader_backend->StateTable;
const struct StateEntry *StateTable = This->StateTable;
/* To compensate the lack of format switching with some offscreen rendering methods and on onscreen buffers
* the alpha blend state changes with different render target formats
@ -1034,7 +1034,7 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU
BYTE shift;
WineD3DContext *context;
GLint drawBuffer=0;
const struct StateEntry *StateTable = This->shader_backend->StateTable;
const struct StateEntry *StateTable = This->StateTable;
TRACE("(%p): Selecting context for render target %p, thread %d\n", This, target, tid);
if(This->lastActiveRenderTarget != target || tid != This->lastThread) {

View File

@ -4507,7 +4507,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetTextureStageState(IWineD3DDevice *if
}
if(Stage > This->stateBlock->lowest_disabled_stage &&
This->shader_backend->StateTable[STATE_TEXTURESTAGE(0, Type)].representative == STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP)) {
This->StateTable[STATE_TEXTURESTAGE(0, Type)].representative == STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP)) {
/* Colorop change above lowest disabled stage? That won't change anything in the gl setup
* Changes in other states are important on disabled stages too
*/
@ -7977,7 +7977,7 @@ const DWORD SavedVertexStates_S[NUM_SAVEDVERTEXSTATES_S] = {
};
void IWineD3DDeviceImpl_MarkStateDirty(IWineD3DDeviceImpl *This, DWORD state) {
DWORD rep = This->shader_backend->StateTable[state].representative;
DWORD rep = This->StateTable[state].representative;
DWORD idx;
BYTE shift;
UINT i;

View File

@ -3446,6 +3446,8 @@ static HRESULT WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter,
select_shader_mode(&GLINFO_LOCATION, DeviceType, &object->ps_selected_mode, &object->vs_selected_mode);
object->shader_backend = select_shader_backend(Adapter, DeviceType);
compile_state_table(object->StateTable, object->shader_backend->StateTable_remove);
/* Prefer the vtable with functions optimized for single dirtifyable objects if the shader
* model can deal with that. It is essentially the same, just with adjusted
* Set*ShaderConstantF implementations

View File

@ -446,7 +446,7 @@ static void state_blend(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D
/* colorkey fixup for stage 0 alphaop depends on WINED3DRS_ALPHABLENDENABLE state,
so it may need updating */
if (stateblock->renderState[WINED3DRS_COLORKEYENABLE]) {
const struct StateEntry *StateTable = stateblock->wineD3DDevice->shader_backend->StateTable;
const struct StateEntry *StateTable = stateblock->wineD3DDevice->StateTable;
StateTable[STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP)].apply(STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), stateblock, context);
}
}
@ -496,7 +496,7 @@ static void state_alpha(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D
}
if(enable_ckey || context->last_was_ckey) {
const struct StateEntry *StateTable = stateblock->wineD3DDevice->shader_backend->StateTable;
const struct StateEntry *StateTable = stateblock->wineD3DDevice->StateTable;
StateTable[STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP)].apply(STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), stateblock, context);
}
context->last_was_ckey = enable_ckey;
@ -4885,3 +4885,10 @@ const struct StateEntry FFPStateTable[] =
{ /* STATE_MATERIAL */ STATE_RENDER(WINED3DRS_SPECULARENABLE), state_specularenable},
{ /* STATE_FRONTFACE */ STATE_FRONTFACE, frontface },
};
/* Remove the temptable, but instead pass a fragment pipeline table, vertex pipeline and misc pipeline
* table in
*/
void compile_state_table(struct StateEntry *StateTable, const struct StateEntry *temptable) {
memcpy(StateTable, temptable, sizeof(*StateTable) * (STATE_HIGHEST + 1));
}

View File

@ -302,7 +302,7 @@ typedef struct {
void (*shader_get_caps)(WINED3DDEVTYPE devtype, WineD3D_GL_Info *gl_info, struct shader_caps *caps);
void (*shader_dll_load_init)(void);
void (*shader_fragment_enable)(IWineD3DDevice *iface, BOOL enable);
const struct StateEntry *StateTable;
const struct StateEntry *StateTable_remove; /* TODO: This has to go away */
} shader_backend_t;
extern const shader_backend_t atifs_shader_backend;
@ -588,6 +588,7 @@ struct StateEntry
/* "Base" state table */
extern const struct StateEntry FFPStateTable[];
void compile_state_table(struct StateEntry *StateTable, const struct StateEntry *temptable);
/* The new context manager that should deal with onscreen and offscreen rendering */
struct WineD3DContext {
@ -812,6 +813,7 @@ struct IWineD3DDeviceImpl
const shader_backend_t *shader_backend;
hash_table_t *glsl_program_lookup;
void *shader_priv;
struct StateEntry StateTable[STATE_HIGHEST + 1];
/* To store */
BOOL view_ident; /* true iff view matrix is identity */