wined3d: Add code to cleanup device multistate_funcs.
This commit is contained in:
parent
538cf8b847
commit
29dd286d79
|
@ -164,6 +164,13 @@ static ULONG WINAPI IWineD3DDeviceImpl_Release(IWineD3DDevice *iface) {
|
|||
TRACE("(%p) : Releasing from %d\n", This, refCount + 1);
|
||||
|
||||
if (!refCount) {
|
||||
UINT i;
|
||||
|
||||
for (i = 0; i < sizeof(This->multistate_funcs)/sizeof(This->multistate_funcs[0]); ++i) {
|
||||
HeapFree(GetProcessHeap(), 0, This->multistate_funcs[i]);
|
||||
This->multistate_funcs[i] = NULL;
|
||||
}
|
||||
|
||||
/* TODO: Clean up all the surfaces and textures! */
|
||||
/* NOTE: You must release the parent if the object was created via a callback
|
||||
** ***************************/
|
||||
|
|
|
@ -3631,6 +3631,7 @@ static HRESULT WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter,
|
|||
const struct fragment_pipeline *frag_pipeline = NULL;
|
||||
int i;
|
||||
struct fragment_caps ffp_caps;
|
||||
HRESULT hr;
|
||||
|
||||
/* Validate the adapter number. If no adapters are available(no GL), ignore the adapter
|
||||
* number and create a device without a 3D adapter for 2D only operation.
|
||||
|
@ -3689,9 +3690,16 @@ static HRESULT WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter,
|
|||
frag_pipeline->get_caps(DeviceType, &GLINFO_LOCATION, &ffp_caps);
|
||||
object->max_ffp_textures = ffp_caps.MaxSimultaneousTextures;
|
||||
object->max_ffp_texture_stages = ffp_caps.MaxTextureBlendStages;
|
||||
compile_state_table(object->StateTable, object->multistate_funcs, &GLINFO_LOCATION,
|
||||
hr = compile_state_table(object->StateTable, object->multistate_funcs, &GLINFO_LOCATION,
|
||||
ffp_vertexstate_template, frag_pipeline, misc_state_template);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
IWineD3D_Release(object->wineD3D);
|
||||
HeapFree(GetProcessHeap(), 0, object);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
object->blitter = select_blit_implementation(Adapter, DeviceType);
|
||||
|
||||
/* set the state of the device to valid */
|
||||
|
|
|
@ -5488,7 +5488,7 @@ static void multistate_apply_3(DWORD state, IWineD3DStateBlockImpl *stateblock,
|
|||
stateblock->wineD3DDevice->multistate_funcs[state][2](state, stateblock, context);
|
||||
}
|
||||
|
||||
void compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_multistate_funcs,
|
||||
HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_multistate_funcs,
|
||||
const WineD3D_GL_Info *gl_info, const struct StateEntryTemplate *vertex,
|
||||
const struct fragment_pipeline *fragment, const struct StateEntryTemplate *misc)
|
||||
{
|
||||
|
@ -5520,6 +5520,7 @@ void compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_mul
|
|||
memset(set, 0, sizeof(set));
|
||||
|
||||
for(i = 0; cur[i].state; i++) {
|
||||
APPLYSTATEFUNC *funcs_array;
|
||||
|
||||
/* Only use the first matching state with the available extension from one template.
|
||||
* e.g.
|
||||
|
@ -5552,17 +5553,24 @@ void compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_mul
|
|||
dev_multistate_funcs[cur[i].state] = HeapAlloc(GetProcessHeap(),
|
||||
0,
|
||||
sizeof(**dev_multistate_funcs) * 2);
|
||||
if (!dev_multistate_funcs[cur[i].state]) {
|
||||
goto out_of_mem;
|
||||
}
|
||||
|
||||
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];
|
||||
funcs_array = HeapReAlloc(GetProcessHeap(),
|
||||
0,
|
||||
dev_multistate_funcs[cur[i].state],
|
||||
sizeof(**dev_multistate_funcs) * 3);
|
||||
if (!funcs_array) {
|
||||
goto out_of_mem;
|
||||
}
|
||||
|
||||
dev_multistate_funcs[cur[i].state] = funcs_array;
|
||||
dev_multistate_funcs[cur[i].state][2] = multistate_funcs[cur[i].state][2];
|
||||
break;
|
||||
default:
|
||||
|
@ -5578,5 +5586,16 @@ void compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_mul
|
|||
StateTable[cur[i].state].representative = cur[i].content.representative;
|
||||
}
|
||||
}
|
||||
|
||||
return WINED3D_OK;
|
||||
|
||||
out_of_mem:
|
||||
for (i = 0; i <= STATE_HIGHEST; ++i) {
|
||||
HeapFree(GetProcessHeap(), 0, dev_multistate_funcs[i]);
|
||||
}
|
||||
|
||||
memset(dev_multistate_funcs, 0, (STATE_HIGHEST + 1)*sizeof(*dev_multistate_funcs));
|
||||
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
#undef GLINFO_LOCATION
|
||||
|
|
|
@ -760,7 +760,7 @@ extern const struct fragment_pipeline nvts_fragment_pipeline;
|
|||
extern const struct fragment_pipeline nvrc_fragment_pipeline;
|
||||
|
||||
/* "Base" state table */
|
||||
void compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_multistate_funcs,
|
||||
HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_multistate_funcs,
|
||||
const WineD3D_GL_Info *gl_info, const struct StateEntryTemplate *vertex,
|
||||
const struct fragment_pipeline *fragment, const struct StateEntryTemplate *misc);
|
||||
|
||||
|
|
Loading…
Reference in New Issue