diff --git a/dlls/wined3d/baseshader.c b/dlls/wined3d/baseshader.c index 858bf7f31c1..870d92e5e4b 100644 --- a/dlls/wined3d/baseshader.c +++ b/dlls/wined3d/baseshader.c @@ -181,6 +181,20 @@ unsigned int shader_get_float_offset(const DWORD reg) { } } +static void shader_delete_constant_list(struct list* clist) { + + struct list *ptr; + struct local_constant* constant; + + ptr = list_head(clist); + while (ptr) { + constant = LIST_ENTRY(ptr, struct local_constant, entry); + ptr = list_next(clist, ptr); + HeapFree(GetProcessHeap(), 0, constant); + } + list_init(clist); +} + /* Note that this does not count the loop register * as an address register. */ @@ -204,6 +218,13 @@ HRESULT shader_get_registers_used( if (pToken == NULL) return WINED3D_OK; + /* get_registers_used is called on every compile on some 1.x shaders, which can result + * in stacking up a collection of local constants. Delete the old constants if existing + */ + shader_delete_constant_list(&This->baseShader.constantsF); + shader_delete_constant_list(&This->baseShader.constantsB); + shader_delete_constant_list(&This->baseShader.constantsI); + while (WINED3DVS_END() != *pToken) { CONST SHADER_OPCODE* curOpcode; DWORD opcode_token; @@ -1075,20 +1096,6 @@ void shader_trace_init( } } -static void shader_delete_constant_list( - struct list* clist) { - - struct list *ptr; - struct local_constant* constant; - - ptr = list_head(clist); - while (ptr) { - constant = LIST_ENTRY(ptr, struct local_constant, entry); - ptr = list_next(clist, ptr); - HeapFree(GetProcessHeap(), 0, constant); - } -} - static void shader_none_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) {} static void shader_none_select_depth_blt(IWineD3DDevice *iface) {} static void shader_none_load_constants(IWineD3DDevice *iface, char usePS, char useVS) {}