From 68dec9d16187b8346b58cf46fe2471f6632b0a1f Mon Sep 17 00:00:00 2001 From: =?utf8?q?Stefan=20D=C3=B6singer?= Date: Tue, 1 Jul 2008 19:43:52 -0500 Subject: [PATCH] wined3d: Implement the state merger and start to use it. --- dlls/wined3d/directx.c | 4 +- dlls/wined3d/state.c | 125 ++++++++++++++++++++++++++++++++++++----- dlls/wined3d/wined3d_private.h | 21 ++++++- 3 files changed, 132 insertions(+), 18 deletions(-) diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index f121cde37a0..7f776042d82 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -3446,7 +3446,9 @@ 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); + compile_state_table(object->StateTable, object->multistate_funcs, + NULL, NULL, misc_state_template, + 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 diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 94a27fae1de..4e0f5d815ea 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -3834,15 +3834,15 @@ const struct StateEntry FFPStateTable[] = { /* 16, WINED3DRS_LASTPIXEL */ STATE_RENDER(WINED3DRS_LASTPIXEL), state_lastpixel }, { /* 17, WINED3DRS_TEXTUREMAG */ 0 /* Handled in ddraw */, state_undefined }, { /* 18, WINED3DRS_TEXTUREMIN */ 0 /* Handled in ddraw */, state_undefined }, - { /* 19, WINED3DRS_SRCBLEND */ STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, - { /* 20, WINED3DRS_DESTBLEND */ STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, + { /* 19, WINED3DRS_SRCBLEND */ STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, + { /* 20, WINED3DRS_DESTBLEND */ STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, { /* 21, WINED3DRS_TEXTUREMAPBLEND */ 0 /* Handled in ddraw */, state_undefined }, { /* 22, WINED3DRS_CULLMODE */ STATE_RENDER(WINED3DRS_CULLMODE), state_cullmode }, { /* 23, WINED3DRS_ZFUNC */ STATE_RENDER(WINED3DRS_ZFUNC), state_zfunc }, { /* 24, WINED3DRS_ALPHAREF */ STATE_RENDER(WINED3DRS_ALPHATESTENABLE), state_alpha }, { /* 25, WINED3DRS_ALPHAFUNC */ STATE_RENDER(WINED3DRS_ALPHATESTENABLE), state_alpha }, { /* 26, WINED3DRS_DITHERENABLE */ STATE_RENDER(WINED3DRS_DITHERENABLE), state_ditherenable }, - { /* 27, WINED3DRS_ALPHABLENDENABLE */ STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, + { /* 27, WINED3DRS_ALPHABLENDENABLE */ STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, { /* 28, WINED3DRS_FOGENABLE */ STATE_RENDER(WINED3DRS_FOGENABLE), state_fog }, { /* 29, WINED3DRS_SPECULARENABLE */ STATE_RENDER(WINED3DRS_SPECULARENABLE), state_specularenable}, { /* 30, WINED3DRS_ZVISIBLE */ 0 /* Not supported according to the msdn */, state_nogl }, @@ -3855,7 +3855,7 @@ const struct StateEntry FFPStateTable[] = { /* 37, WINED3DRS_FOGEND */ STATE_RENDER(WINED3DRS_FOGENABLE), state_fog }, { /* 38, WINED3DRS_FOGDENSITY */ STATE_RENDER(WINED3DRS_FOGDENSITY), state_fogdensity }, { /* 39, WINED3DRS_STIPPLEENABLE */ STATE_RENDER(WINED3DRS_STIPPLEENABLE), state_stippleenable }, - { /* 40, WINED3DRS_EDGEANTIALIAS */ STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, + { /* 40, WINED3DRS_EDGEANTIALIAS */ STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, { /* 41, WINED3DRS_COLORKEYENABLE */ STATE_RENDER(WINED3DRS_ALPHATESTENABLE), state_alpha }, { /* 42, undefined */ 0, state_undefined }, { /* 43, WINED3DRS_BORDERCOLOR */ STATE_RENDER(WINED3DRS_BORDERCOLOR), state_bordercolor }, @@ -3994,7 +3994,7 @@ const struct StateEntry FFPStateTable[] = /*173, WINED3DRS_NORMALORDER */ /* Value assigned to 2 state names */ { /*174, WINED3DRS_SCISSORTESTENABLE */ STATE_RENDER(WINED3DRS_SCISSORTESTENABLE), state_scissor }, { /*175, WINED3DRS_SLOPESCALEDEPTHBIAS */ STATE_RENDER(WINED3DRS_DEPTHBIAS), state_depthbias }, - { /*176, WINED3DRS_ANTIALIASEDLINEENABLE */ STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, + { /*176, WINED3DRS_ANTIALIASEDLINEENABLE */ STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, { /*177, undefined */ 0, state_undefined }, { /*178, WINED3DRS_MINTESSELLATIONLEVEL */ STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation }, { /*179, WINED3DRS_MAXTESSELLATIONLEVEL */ STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation }, @@ -4024,10 +4024,10 @@ const struct StateEntry FFPStateTable[] = { /*203, WINED3DRS_WRAP13 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, { /*204, WINED3DRS_WRAP14 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, { /*205, WINED3DRS_WRAP15 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, - { /*206, WINED3DRS_SEPARATEALPHABLENDENABLE */ STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, - { /*207, WINED3DRS_SRCBLENDALPHA */ STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, - { /*208, WINED3DRS_DESTBLENDALPHA */ STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, - { /*209, WINED3DRS_BLENDOPALPHA */ STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blendop }, + { /*206, WINED3DRS_SEPARATEALPHABLENDENABLE */ STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, + { /*207, WINED3DRS_SRCBLENDALPHA */ STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, + { /*208, WINED3DRS_DESTBLENDALPHA */ STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, + { /*209, WINED3DRS_BLENDOPALPHA */ STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, /* Texture stage states */ { /*0, 01, WINED3DTSS_COLOROP */ STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop }, { /*0, 02, WINED3DTSS_COLORARG1 */ STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop }, @@ -4886,9 +4886,106 @@ const struct StateEntry FFPStateTable[] = { /* 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)); +const struct StateEntryTemplate misc_state_template[] = { + { STATE_RENDER(WINED3DRS_SRCBLEND), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }}, + { STATE_RENDER(WINED3DRS_DESTBLEND), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }}, + { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }}, + { STATE_RENDER(WINED3DRS_EDGEANTIALIAS), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }}, + { STATE_RENDER(WINED3DRS_ANTIALIASEDLINEENABLE), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }}, + { STATE_RENDER(WINED3DRS_SEPARATEALPHABLENDENABLE), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }}, + { STATE_RENDER(WINED3DRS_SRCBLENDALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }}, + { STATE_RENDER(WINED3DRS_DESTBLENDALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }}, + { STATE_RENDER(WINED3DRS_DESTBLENDALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }}, + { STATE_RENDER(WINED3DRS_BLENDOPALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }}, + {0 /* Terminate */, { 0, 0 }}, +}; + +static int num_handlers(APPLYSTATEFUNC *funcs) { + unsigned int i; + for(i = 0; funcs[i]; i++); + return i; +} + +static void multistate_apply_2(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) { + stateblock->wineD3DDevice->multistate_funcs[state][0](state, stateblock, context); + stateblock->wineD3DDevice->multistate_funcs[state][1](state, stateblock, context); +} + +static void multistate_apply_3(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) { + stateblock->wineD3DDevice->multistate_funcs[state][0](state, stateblock, context); + stateblock->wineD3DDevice->multistate_funcs[state][1](state, stateblock, context); + stateblock->wineD3DDevice->multistate_funcs[state][2](state, stateblock, context); +} + +void compile_state_table(struct StateEntry *StateTable, + APPLYSTATEFUNC **dev_multistate_funcs, + const struct StateEntryTemplate *vertex, + const struct StateEntryTemplate *fragment, + const struct StateEntryTemplate *misc, + const struct StateEntry *temptable /* TODO: Remove this */) { + unsigned int i, type, handlers; + APPLYSTATEFUNC multistate_funcs[STATE_HIGHEST + 1][3]; + const struct StateEntryTemplate *cur; + + /* TODO: Remove this once all states are provided by templates */ + BOOL set[STATE_HIGHEST + 1]; + memset(set, 0, sizeof(set)); + + memset(multistate_funcs, 0, sizeof(multistate_funcs)); + + for(type = 0; type < 3; type++) { + /* This switch decides the order in which the states are applied */ + switch(type) { + case 0: cur = misc; break; + case 1: cur = fragment; break; + case 2: cur = vertex; break; + default: cur = NULL; /* Stupid compiler */ + } + if(!cur) continue; + + for(i = 0; cur[i].state; i++) { + set[cur[i].state] = TRUE; /* TODO: Remove when done with the move */ + handlers = num_handlers(multistate_funcs[cur[i].state]); + multistate_funcs[cur[i].state][handlers] = cur[i].content.apply; + switch(handlers) { + case 0: + StateTable[cur[i].state].apply = cur[i].content.apply; + break; + case 1: + StateTable[cur[i].state].apply = multistate_apply_2; + dev_multistate_funcs[cur[i].state] = HeapAlloc(GetProcessHeap(), + 0, + sizeof(**dev_multistate_funcs) * 2); + dev_multistate_funcs[cur[i].state][0] = multistate_funcs[cur[i].state][0]; + dev_multistate_funcs[cur[i].state][1] = multistate_funcs[cur[i].state][1]; + break; + case 2: + StateTable[cur[i].state].apply = multistate_apply_3; + HeapFree(GetProcessHeap(), 0, multistate_funcs[cur[i].state]); + dev_multistate_funcs[cur[i].state] = HeapAlloc(GetProcessHeap(), + 0, + sizeof(**dev_multistate_funcs) * 3); + dev_multistate_funcs[cur[i].state][0] = multistate_funcs[cur[i].state][0]; + dev_multistate_funcs[cur[i].state][1] = multistate_funcs[cur[i].state][1]; + dev_multistate_funcs[cur[i].state][2] = multistate_funcs[cur[i].state][2]; + break; + default: + ERR("Unexpected amount of state handlers for state %u: %u\n", + cur[i].state, handlers + 1); + } + + if(StateTable[cur[i].state].representative && + StateTable[cur[i].state].representative != cur[i].content.representative) { + FIXME("State %u has different representatives in different pipeline parts\n", + cur[i].state); + } + StateTable[cur[i].state].representative = cur[i].content.representative; + } + } + + /* TODO Remove this after the state move is done */ + for(i = 0; i < STATE_HIGHEST + 1; i++) { + if(set[i]) continue; + StateTable[i] = temptable[i]; + } } diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 5e988df7392..90f89fe2680 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -582,13 +582,26 @@ typedef void (*APPLYSTATEFUNC)(DWORD state, IWineD3DStateBlockImpl *stateblock, struct StateEntry { - DWORD representative; - APPLYSTATEFUNC apply; + DWORD representative; + APPLYSTATEFUNC apply; }; +struct StateEntryTemplate +{ + DWORD state; + struct StateEntry content; +}; + +extern const struct StateEntryTemplate misc_state_template[]; + /* "Base" state table */ extern const struct StateEntry FFPStateTable[]; -void compile_state_table(struct StateEntry *StateTable, const struct StateEntry *temptable); +void compile_state_table(struct StateEntry *StateTable, + APPLYSTATEFUNC **dev_multistate_funcs, + const struct StateEntryTemplate *vertex, + const struct StateEntryTemplate *fragment, + const struct StateEntryTemplate *misc, + const struct StateEntry *temptable /* TODO: Remove this */); /* The new context manager that should deal with onscreen and offscreen rendering */ struct WineD3DContext { @@ -814,6 +827,8 @@ struct IWineD3DDeviceImpl hash_table_t *glsl_program_lookup; void *shader_priv; struct StateEntry StateTable[STATE_HIGHEST + 1]; + /* Array of functions for states which are handled by more than one pipeline part */ + APPLYSTATEFUNC *multistate_funcs[STATE_HIGHEST + 1]; /* To store */ BOOL view_ident; /* true iff view matrix is identity */ -- 2.11.4.GIT