[D3D 22] Some small optimisations

Lionel Ulmer lionel.ulmer at free.fr
Sun Dec 15 12:14:31 CST 2002


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/
-------------- next part --------------
--- ../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;


More information about the wine-patches mailing list