Hi all, The order to apply the patches is a bit tricky : first 20, then 20 bis, then 21 or 20 bis 2 (they do not conflict) then 22. We really need to implement a semaphore with Christian to not collide in patch naming :-) Changelog: Fix a memory leak and optimize a little bit the generic path -- Lionel Ulmer - http://www.bbrox.org/
--- ../wine_base/dlls/ddraw/mesa_private.h Sun Dec 15 17:17:15 2002 +++ dlls/ddraw/mesa_private.h Sun Dec 15 19:05:28 2002 @@ -99,6 +99,12 @@ void (*unlock_update)(IDirectDrawSurfaceImpl* This, LPCRECT pRect); } IDirect3DTextureGLImpl; +typedef struct { + int offset; + int extra; + void (*handler)(char *vertex, int offset, int extra); +} D3DFVF_GENERIC; + typedef struct IDirect3DDeviceGLImpl { struct IDirect3DDeviceImpl parent; @@ -112,6 +118,12 @@ BOOLEAN last_vertices_transformed; BOOLEAN last_vertices_lit; + /* This is to optimize a little bit the 'slow generic' path for the DrawPrimitive stuff */ + D3DFVF_GENERIC *handler; + DWORD last_vertex_format; + DWORD last_vertex_format_size; + DWORD last_vertex_format_elements; + D3DMATRIX *world_mat; D3DMATRIX *view_mat; D3DMATRIX *proj_mat; --- ../wine_base/dlls/ddraw/d3ddevice/mesa.c Sun Dec 15 19:12:11 2002 +++ dlls/ddraw/d3ddevice/mesa.c Sun Dec 15 19:11:09 2002 @@ -281,7 +281,9 @@ /* Release texture associated with the device */ if (This->current_texture[0] != NULL) IDirect3DTexture2_Release(ICOM_INTERFACE(This->current_texture[0], IDirect3DTexture2)); - + + if (glThis->handler) HeapFree(GetProcessHeap(), 0, This); + ENTER_GL(); glXDestroyContext(glThis->display, glThis->gl_context); LEAVE_GL(); @@ -902,12 +904,6 @@ float tu1, tv1; } D3DFVF_TLVERTEX_1; -typedef struct { - int offset; - int extra; - void (*handler)(char *vertex, int offset, int extra); -} D3DFVF_GENERIC; - /* These are the various handler used in the generic path */ static void handle_xyz(char *vertex, int offset, int extra) { glVertex3fv((float *) (vertex + offset)); @@ -1018,59 +1014,74 @@ Note that people should write a fast path for all vertex formats out there... */ DWORD elements; - DWORD size = get_flexible_vertex_size(d3dvtVertexType, &elements); + DWORD size; char *vertices = (char *) lpvVertices; int index; int current_offset = 0; int current_position = 0; - D3DFVF_GENERIC *handler = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, elements * sizeof(D3DFVF_GENERIC)); + D3DFVF_GENERIC *handler; - WARN(" using draw_primitive generic path - for better performance, add a fast path for your vertex case !\n"); - - if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) { - handler[elements - 1].handler = handle_xyz; - handler[elements - 1].offset = current_offset; - current_offset += 3 * sizeof(D3DVALUE); - } else { - handler[elements - 1].handler = handle_xyzrhw; - handler[elements - 1].offset = current_offset; - current_offset += 4 * sizeof(D3DVALUE); - } - if (d3dvtVertexType & D3DFVF_NORMAL) { - handler[current_position].handler = handle_normal; - handler[current_position].offset = current_offset; - current_position += 1; - current_offset += 3 * sizeof(D3DVALUE); - } - if (d3dvtVertexType & D3DFVF_DIFFUSE) { - handler[current_position].handler = handle_diffuse; - handler[current_position].offset = current_offset; - current_position += 1; - current_offset += sizeof(DWORD); - } - if (d3dvtVertexType & D3DFVF_SPECULAR) { - handler[current_position].handler = handle_specular; - handler[current_position].offset = current_offset; - current_position += 1; - current_offset += sizeof(DWORD); - } - if (((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT) == 1) { - handler[current_position].handler = handle_texture; - handler[current_position].offset = current_offset; - handler[current_position].extra = 0xFF; - current_position += 1; - current_offset += 2 * sizeof(D3DVALUE); - } else { - int tex_index; - for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) { + if ((glThis->last_vertex_format != d3dvtVertexType) || + (glThis->handler == NULL)) { + if (glThis->handler == NULL) HeapFree(GetProcessHeap(), 0, glThis->handler); + size = get_flexible_vertex_size(d3dvtVertexType, &elements); + + glThis->handler = handler = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, elements * sizeof(D3DFVF_GENERIC)); + glThis->last_vertex_format = d3dvtVertexType; + glThis->last_vertex_format_size = size; + glThis->last_vertex_format_elements = elements; + + if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) { + handler[elements - 1].handler = handle_xyz; + handler[elements - 1].offset = current_offset; + current_offset += 3 * sizeof(D3DVALUE); + } else { + handler[elements - 1].handler = handle_xyzrhw; + handler[elements - 1].offset = current_offset; + current_offset += 4 * sizeof(D3DVALUE); + } + if (d3dvtVertexType & D3DFVF_NORMAL) { + handler[current_position].handler = handle_normal; + handler[current_position].offset = current_offset; + current_position += 1; + current_offset += 3 * sizeof(D3DVALUE); + } + if (d3dvtVertexType & D3DFVF_DIFFUSE) { + handler[current_position].handler = handle_diffuse; + handler[current_position].offset = current_offset; + current_position += 1; + current_offset += sizeof(DWORD); + } + if (d3dvtVertexType & D3DFVF_SPECULAR) { + handler[current_position].handler = handle_specular; + handler[current_position].offset = current_offset; + current_position += 1; + current_offset += sizeof(DWORD); + } + if (((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT) == 1) { handler[current_position].handler = handle_texture; handler[current_position].offset = current_offset; - handler[current_position].extra = tex_index; + handler[current_position].extra = 0xFF; current_position += 1; current_offset += 2 * sizeof(D3DVALUE); + } else { + int tex_index; + for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) { + handler[current_position].handler = handle_texture; + handler[current_position].offset = current_offset; + handler[current_position].extra = tex_index; + current_position += 1; + current_offset += 2 * sizeof(D3DVALUE); + } } + } else { + handler = glThis->handler; + size = glThis->last_vertex_format_size; + elements = glThis->last_vertex_format_elements; } - + + WARN(" using draw_primitive generic path - for better performance, add a fast path for your vertex case !\n"); + for (index = 0; index < dwIndexCount; index++) { int i = (dwIndices == NULL) ? index : dwIndices[index]; int elt;