[D3D 18] Some texturing work...

Lionel Ulmer lionel.ulmer at free.fr
Sat Dec 14 14:19:11 CST 2002


Hi all,

Basically, this removes the D3DTexture object and has the D3D code always
use internally DDrawSurfaces for textures (thus preparing the work for D3D7
where the Texture interface disappeared). It should also provide support for
texture locking / unlocking and direct uploading without going through the
Load method.

This patch is still a little bit rough at the edges (ie it should work but
it does not give me the results I expected : I get some more textures
displayed correctly but it's still not perfect).

Changelog:
 - rework how texturing is done in the D3D driver
 - added the generic path for DrawPrimitive API in D3D 3 / 7

                Lionel

-- 
		 Lionel Ulmer - http://www.bbrox.org/
-------------- next part --------------
Index: dlls/ddraw/d3d_private.h
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/d3d_private.h,v
retrieving revision 1.13
diff -u -r1.13 d3d_private.h
--- dlls/ddraw/d3d_private.h	2 Dec 2002 18:59:11 -0000	1.13
+++ dlls/ddraw/d3d_private.h	14 Dec 2002 20:14:50 -0000
@@ -32,7 +32,6 @@
 typedef struct IDirect3DImpl IDirect3DImpl;
 typedef struct IDirect3DLightImpl IDirect3DLightImpl;
 typedef struct IDirect3DMaterialImpl IDirect3DMaterialImpl;
-typedef struct IDirect3DTextureImpl IDirect3DTextureImpl;
 typedef struct IDirect3DViewportImpl IDirect3DViewportImpl;
 typedef struct IDirect3DExecuteBufferImpl IDirect3DExecuteBufferImpl;
 typedef struct IDirect3DDeviceImpl IDirect3DDeviceImpl;
@@ -53,6 +52,9 @@
     DWORD                   ref;
     /* IDirect3D fields */
     IDirectDrawImpl*	ddraw;
+
+    /* Used as a callback function to create a texture */
+    HRESULT (*create_texture)(IDirect3DImpl *d3d, IDirectDrawSurfaceImpl *tex, BOOLEAN at_creation, IDirectDrawSurfaceImpl *main, DWORD mipmap_level);
 };
 
 /*****************************************************************************
@@ -95,21 +97,6 @@
 };
 
 /*****************************************************************************
- * IDirect3DTexture implementation structure
- */
-struct IDirect3DTextureImpl
-{
-    ICOM_VFIELD_MULTI(IDirect3DTexture2);
-    ICOM_VFIELD_MULTI(IDirect3DTexture);
-    DWORD ref;
-    /* IDirect3DTexture fields */
-    IDirect3DImpl *d3d;
-    IDirect3DDeviceImpl *d3ddevice;
-    IDirectDrawSurfaceImpl *surface;
-    BOOL loaded;
-};
-
-/*****************************************************************************
  * IDirect3DViewport implementation structure
  */
 struct IDirect3DViewportImpl
@@ -183,7 +170,7 @@
 
     IDirect3DViewportImpl *viewport_list;
     IDirect3DViewportImpl *current_viewport;
-    IDirect3DTextureImpl *current_texture[MAX_TEXTURES];
+    IDirectDrawSurfaceImpl *current_texture[MAX_TEXTURES];
 
     void (*set_context)(IDirect3DDeviceImpl*);
 };
Index: dlls/ddraw/d3dtexture.c
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/d3dtexture.c,v
retrieving revision 1.21
diff -u -r1.21 d3dtexture.c
--- dlls/ddraw/d3dtexture.c	5 Dec 2002 20:33:09 -0000	1.21
+++ dlls/ddraw/d3dtexture.c	14 Dec 2002 20:14:50 -0000
@@ -130,27 +130,21 @@
 /*******************************************************************************
  *			   IDirectSurface callback methods
  */
-HRESULT WINAPI SetColorKey_cb(IDirect3DTextureImpl *texture, DWORD dwFlags, LPDDCOLORKEY ckey )
+HRESULT WINAPI gltex_setcolorkey_cb(IDirectDrawSurfaceImpl *texture, DWORD dwFlags, LPDDCOLORKEY ckey )
 {
     DDSURFACEDESC *tex_d;
     GLuint current_texture;
-    IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) texture;
+    IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) texture->tex_private;
     
     TRACE("(%p) : colorkey callback\n", texture);
 
     /* Get the texture description */
-    tex_d = (DDSURFACEDESC *)&(texture->surface->surface_desc);
+    tex_d = (DDSURFACEDESC *)&(texture->surface_desc);
 
     /* Now, save the current texture */
     ENTER_GL();
     glGetIntegerv(GL_TEXTURE_BINDING_2D, &current_texture);
-
-    /* If the GetHandle was not done yet, it's an error */
-    if (glThis->tex_name == 0) {
-        ERR("Unloaded texture !\n");
-	LEAVE_GL();
-	return DD_OK;
-    }
+    if (glThis->tex_name == 0) ERR("Unbound GL texture !!!\n");
     glBindTexture(GL_TEXTURE_2D, glThis->tex_name);
 
     if (tex_d->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
@@ -180,14 +174,13 @@
 		    }
 		}
 
-		glTexImage2D(GL_TEXTURE_2D,
-			     0,
-			     GL_RGBA,
-			     tex_d->dwWidth, tex_d->dwHeight,
-			     0,
-			     GL_RGBA,
-			     GL_UNSIGNED_SHORT_5_5_5_1,
-			     dest);
+		glTexSubImage2D(GL_TEXTURE_2D,
+				glThis->mipmap_level,
+				0, 0,
+				tex_d->dwWidth, tex_d->dwHeight,
+				GL_RGBA,
+				GL_UNSIGNED_SHORT_5_5_5_1,
+				dest);
 		
 		/* Frees the temporary surface */
 		HeapFree(GetProcessHeap(),0,dest);
@@ -208,66 +201,280 @@
     } else {
         ERR("Unhandled texture format (neither RGB nor INDEX)\n");
     }
+    glBindTexture(GL_TEXTURE_2D, current_texture);
     LEAVE_GL();
 
     return DD_OK;
 }
 
-HRESULT WINAPI
-Main_IDirect3DTextureImpl_2_1T_QueryInterface(LPDIRECT3DTEXTURE2 iface,
-                                              REFIID riid,
-                                              LPVOID* obp)
-{
-    ICOM_THIS_FROM(IDirect3DTextureImpl, IDirect3DTexture2, iface);
-    TRACE("(%p/%p)->(%s,%p): stub!\n", This, iface, debugstr_guid(riid), obp);
-
-    *obp = NULL;
-
-    if ( IsEqualGUID( &IID_IUnknown,  riid ) ) {
-        IDirect3DTexture2_AddRef(ICOM_INTERFACE(This, IDirect3DTexture2));
-	*obp = iface;
-	TRACE("  Creating IUnknown interface at %p.\n", *obp);
-	return S_OK;
-    }
-    if ( IsEqualGUID( &IID_IDirect3DTexture, riid ) ) {
-        IDirect3DTexture2_AddRef(ICOM_INTERFACE(This, IDirect3DTexture2));
-        *obp = ICOM_INTERFACE(This, IDirect3DTexture);
-	TRACE("  Creating IDirect3DTexture interface %p\n", *obp);
-	return S_OK;
-    }
-    if ( IsEqualGUID( &IID_IDirect3DTexture2, riid ) ) {
-        IDirect3DTexture2_AddRef(ICOM_INTERFACE(This, IDirect3DTexture2));
-        *obp = ICOM_INTERFACE(This, IDirect3DTexture2);
-	TRACE("  Creating IDirect3DTexture2 interface %p\n", *obp);
-	return S_OK;
-    }
-    FIXME("(%p): interface for IID %s NOT found!\n", This, debugstr_guid(riid));
-    return OLE_E_ENUM_NOMORE;
-}
+static void
+gltex_upload_texture(IDirectDrawSurfaceImpl *This, BOOLEAN init_upload) {
+    IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private;
+    GLuint current_texture;
+#if 0
+    static BOOL color_table_queried = FALSE;
+#endif
+    void (*ptr_ColorTableEXT) (GLenum target, GLenum internalformat,
+			       GLsizei width, GLenum format, GLenum type, const GLvoid *table) = NULL;
 
-ULONG WINAPI
-Main_IDirect3DTextureImpl_2_1T_AddRef(LPDIRECT3DTEXTURE2 iface)
-{
-    ICOM_THIS_FROM(IDirect3DTextureImpl, IDirect3DTexture2, iface);
-    TRACE("(%p/%p)->() incrementing from %lu.\n", This, iface, This->ref);
-    return ++(This->ref);
-}
+    DDSURFACEDESC *src_d = (DDSURFACEDESC *)&(This->surface_desc);;
 
-ULONG WINAPI
-Main_IDirect3DTextureImpl_2_1T_Release(LPDIRECT3DTEXTURE2 iface)
-{
-    ICOM_THIS_FROM(IDirect3DTextureImpl, IDirect3DTexture2, iface);
-    FIXME("(%p/%p)->() decrementing from %lu.\n", This, iface, This->ref);
-    
-    if (!--(This->ref)) {
-        /* Release surface */
-        IDirectDrawSurface3_Release(ICOM_INTERFACE(This->surface, IDirectDrawSurface3));
+    TRACE(" uploading texture to GL id %d (initial = %d).\n", glThis->tex_name, init_upload);
 
-	HeapFree(GetProcessHeap(),0,This);
-	return 0;
-    }
+    glGetIntegerv(GL_TEXTURE_BINDING_2D, &current_texture);
+    glBindTexture(GL_TEXTURE_2D, glThis->tex_name);
+
+    if (src_d->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
+	  /* ****************
+	     Paletted Texture
+	     **************** */
+        IDirectDrawPaletteImpl* pal = This->palette;
+	BYTE table[256][4];
+	int i;
+
+#if 0
+	if (color_table_queried == FALSE) {
+	    ptr_ColorTableEXT =
+	        ((Mesa_DeviceCapabilities *) ((x11_dd_private *) This->surface->s.ddraw->d->private)->device_capabilities)->ptr_ColorTableEXT;
+	}
+#endif
+	
+	if (pal == NULL) {
+	    ERR("Palettized texture Loading with a NULL palette !\n");
+	    LEAVE_GL();
+	    return;
+	}
+	/* Get the surface's palette */
+	for (i = 0; i < 256; i++) {
+	    table[i][0] = pal->palents[i].peRed;
+	    table[i][1] = pal->palents[i].peGreen;
+	    table[i][2] = pal->palents[i].peBlue;
+	    if ((src_d->dwFlags & DDSD_CKSRCBLT) &&
+		(i >= src_d->ddckCKSrcBlt.dwColorSpaceLowValue) &&
+		(i <= src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
+	        table[i][3] = 0x00;
+	    else
+	        table[i][3] = 0xFF;
+	}
+
+	/* Texture snooping */
+	SNOOP_PALETTED();
+
+	if (ptr_ColorTableEXT != NULL) {
+	    /* use Paletted Texture Extension */
+	    ptr_ColorTableEXT(GL_TEXTURE_2D,    /* target */
+			      GL_RGBA,          /* internal format */
+			      256,              /* table size */
+			      GL_RGBA,          /* table format */
+			      GL_UNSIGNED_BYTE, /* table type */
+			      table);           /* the color table */
+	    
+	    glTexImage2D(GL_TEXTURE_2D,       /* target */
+			 glThis->mipmap_level,                   /* level */
+			 GL_COLOR_INDEX8_EXT, /* internal format */
+			 src_d->dwWidth, src_d->dwHeight, /* width, height */
+			 0,                   /* border */
+			 GL_COLOR_INDEX,      /* texture format */
+			 GL_UNSIGNED_BYTE,    /* texture type */
+			 src_d->lpSurface); /* the texture */
+	} else {
+	    DWORD *surface = (DWORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(DWORD));
+	    DWORD i;
+	    BYTE *src = (BYTE *) src_d->lpSurface, *dst = (BYTE *) surface;
+	    
+	    for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
+	        BYTE color = *src++;
+		*dst++ = table[color][0];
+		*dst++ = table[color][1];
+		*dst++ = table[color][2];
+		*dst++ = table[color][3];
+	    }
+	    
+	    if (init_upload)
+	        glTexImage2D(GL_TEXTURE_2D,
+			     glThis->mipmap_level,
+			     GL_RGBA,
+			     src_d->dwWidth, src_d->dwHeight,
+			     0,
+			     GL_RGBA,
+			     GL_UNSIGNED_BYTE,
+			     surface);
+	    else
+	        glTexSubImage2D(GL_TEXTURE_2D,
+				glThis->mipmap_level,
+				0, 0,
+				src_d->dwWidth, src_d->dwHeight,
+				GL_RGBA,
+				GL_UNSIGNED_BYTE,
+				surface);
+	    
+	    HeapFree(GetProcessHeap(), 0, surface);
+	}
+    } else if (src_d->ddpfPixelFormat.dwFlags & DDPF_RGB) {
+	    /* ************
+	       RGB Textures
+	       ************ */
+        if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 8) {
+	        /* **********************
+		   GL_UNSIGNED_BYTE_3_3_2
+		   ********************** */
+	    if (init_upload)
+	        glTexImage2D(GL_TEXTURE_2D,
+			     glThis->mipmap_level,
+			     GL_RGB,
+			     src_d->dwWidth, src_d->dwHeight,
+			     0,
+			     GL_RGB,
+			     GL_UNSIGNED_BYTE_3_3_2,
+			     src_d->lpSurface);
+	    else
+	        glTexSubImage2D(GL_TEXTURE_2D,
+				glThis->mipmap_level,
+				0, 0,
+				src_d->dwWidth, src_d->dwHeight,
+				GL_RGB,
+				GL_UNSIGNED_BYTE_3_3_2,
+				src_d->lpSurface);
+	} else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 16) {
+  	    if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000000) {
+	        /* Texture snooping */
+	        SNOOP_5650();
+		    
+		if (init_upload)
+		    glTexImage2D(GL_TEXTURE_2D,
+				 glThis->mipmap_level,
+				 GL_RGB,
+				 src_d->dwWidth, src_d->dwHeight,
+				 0,
+				 GL_RGB,
+				 GL_UNSIGNED_SHORT_5_6_5,
+				 src_d->lpSurface);
+		else
+		    glTexSubImage2D(GL_TEXTURE_2D,
+				    glThis->mipmap_level,
+				    0, 0,
+				    src_d->dwWidth, src_d->dwHeight,
+				    GL_RGB,
+				    GL_UNSIGNED_SHORT_5_6_5,
+				    src_d->lpSurface);
+
+	    } else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000001) {
+	        /* Texture snooping */
+  	        SNOOP_5551();
+		    
+		if (init_upload)
+		    glTexImage2D(GL_TEXTURE_2D,
+				 glThis->mipmap_level,
+				 GL_RGBA,
+				 src_d->dwWidth, src_d->dwHeight,
+				 0,
+				 GL_RGBA,
+				 GL_UNSIGNED_SHORT_5_5_5_1,
+				 src_d->lpSurface);
+		else
+		    glTexSubImage2D(GL_TEXTURE_2D,
+				    glThis->mipmap_level,
+				    0, 0,
+				    src_d->dwWidth, src_d->dwHeight,
+				    GL_RGBA,
+				    GL_UNSIGNED_SHORT_5_5_5_1,
+				    src_d->lpSurface);
+	    } else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x0000000F) {
+	        if (init_upload)
+		    glTexImage2D(GL_TEXTURE_2D,
+				 glThis->mipmap_level,
+				 GL_RGBA,
+				 src_d->dwWidth, src_d->dwHeight,
+				 0,
+				 GL_RGBA,
+				 GL_UNSIGNED_SHORT_4_4_4_4,
+				 src_d->lpSurface);
+		else
+		    glTexSubImage2D(GL_TEXTURE_2D,
+				    glThis->mipmap_level,
+				    0, 0,
+				    src_d->dwWidth, src_d->dwHeight,
+				    GL_RGBA,
+				    GL_UNSIGNED_SHORT_4_4_4_4,
+				    src_d->lpSurface);
+	    } else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00008000) {
+	        /* Converting the 1555 format in 5551 packed */
+	        WORD *surface = (WORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(WORD));
+		DWORD i;
+		WORD *src = (WORD *) src_d->lpSurface, *dst = surface;
+		
+		for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
+		    *dst++ = (((*src & 0x8000) >> 15) |
+			      ((*src & 0x7FFF) <<  1));
+		    src++;
+		}
+		SNOOP_1555();
+		
+		if (init_upload)
+		    glTexImage2D(GL_TEXTURE_2D,
+				 glThis->mipmap_level,
+				 GL_RGBA,
+				 src_d->dwWidth, src_d->dwHeight,
+				 0,
+				 GL_RGBA,
+				 GL_UNSIGNED_SHORT_5_5_5_1,
+				 surface);
+		else
+		    glTexSubImage2D(GL_TEXTURE_2D,
+				    glThis->mipmap_level,
+				    0, 0,
+				    src_d->dwWidth, src_d->dwHeight,
+				    GL_RGBA,
+				    GL_UNSIGNED_SHORT_5_5_5_1,
+				    surface);
 
-    return This->ref;
+		HeapFree(GetProcessHeap(), 0, surface);
+	    } else {
+	        ERR("Unhandled texture format (bad Aplha channel for a 16 bit texture)\n");
+	    }
+	} else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 24) {
+	    if (init_upload)
+	        glTexImage2D(GL_TEXTURE_2D,
+			     glThis->mipmap_level,
+			     GL_RGB,
+			     src_d->dwWidth, src_d->dwHeight,
+			     0,
+			     GL_RGB,
+			     GL_UNSIGNED_BYTE,
+			     src_d->lpSurface);
+	    else
+	        glTexSubImage2D(GL_TEXTURE_2D,
+				glThis->mipmap_level,
+				0, 0,
+				src_d->dwWidth, src_d->dwHeight,
+				GL_RGB,
+				GL_UNSIGNED_BYTE,
+				src_d->lpSurface);
+	} else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 32) {
+	    if (init_upload)
+	        glTexImage2D(GL_TEXTURE_2D,
+			     glThis->mipmap_level,
+			     GL_RGBA,
+			     src_d->dwWidth, src_d->dwHeight,
+			     0,
+			     GL_RGBA,
+			     GL_UNSIGNED_BYTE,
+			     src_d->lpSurface);
+	    else
+	        glTexSubImage2D(GL_TEXTURE_2D,
+				glThis->mipmap_level,
+				0, 0,
+				src_d->dwWidth, src_d->dwHeight,
+				GL_RGBA,
+				GL_UNSIGNED_BYTE,
+				src_d->lpSurface);
+	} else {
+	    ERR("Unhandled texture format (bad RGB count)\n");
+	}
+    } else {
+        ERR("Unhandled texture format (neither RGB nor INDEX)\n");
+    }    
+    glBindTexture(GL_TEXTURE_2D, current_texture);
 }
 
 HRESULT WINAPI
@@ -275,7 +482,7 @@
                                        LPDIRECT3DDEVICE lpDirect3DDevice,
                                        LPDIRECTDRAWSURFACE lpDDSurface)
 {
-    ICOM_THIS_FROM(IDirect3DTextureImpl, IDirect3DTexture, iface);
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture, iface);
     FIXME("(%p/%p)->(%p,%p) no-op...\n", This, iface, lpDirect3DDevice, lpDDSurface);
     return DD_OK;
 }
@@ -285,7 +492,7 @@
                                               DWORD dwStart,
                                               DWORD dwCount)
 {
-    ICOM_THIS_FROM(IDirect3DTextureImpl, IDirect3DTexture2, iface);
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface);
     FIXME("(%p/%p)->(%08lx,%08lx): stub!\n", This, iface, dwStart, dwCount);
     return DD_OK;
 }
@@ -293,7 +500,7 @@
 HRESULT WINAPI
 Main_IDirect3DTextureImpl_1_Unload(LPDIRECT3DTEXTURE iface)
 {
-    ICOM_THIS_FROM(IDirect3DTextureImpl, IDirect3DTexture, iface);
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture, iface);
     FIXME("(%p/%p)->(): stub!\n", This, iface);
     return DD_OK;
 }
@@ -303,7 +510,7 @@
 					 LPDIRECT3DDEVICE2 lpDirect3DDevice2,
 					 LPD3DTEXTUREHANDLE lpHandle)
 {
-    ICOM_THIS_FROM(IDirect3DTextureImpl, IDirect3DTexture2, iface);
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface);
     FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lpDirect3DDevice2, lpHandle);
     return DD_OK;
 }
@@ -312,45 +519,60 @@
 Main_IDirect3DTextureImpl_2_1T_Load(LPDIRECT3DTEXTURE2 iface,
 				    LPDIRECT3DTEXTURE2 lpD3DTexture2)
 {
-    ICOM_THIS_FROM(IDirect3DTextureImpl, IDirect3DTexture2, iface);
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface);
     FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpD3DTexture2);
     return DD_OK;
 }
 
-ULONG WINAPI
-GL_IDirect3DTextureImpl_2_1T_Release(LPDIRECT3DTEXTURE2 iface)
+static void
+gltex_final_release(IDirectDrawSurfaceImpl *This)
 {
-    ICOM_THIS_FROM(IDirect3DTextureImpl, IDirect3DTexture2, iface);
-    IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This;
-    FIXME("(%p/%p)->() decrementing from %lu.\n", This, iface, This->ref);
-    
-    if (!--(This->ref)) {
-        DWORD mem_used;
+    IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private;
+    DWORD mem_used;
+
+    TRACE(" deleting texture with GL id %d.\n", glThis->tex_name);
       
-        /* Release surface */
-        IDirectDrawSurface3_Release(ICOM_INTERFACE(This->surface, IDirectDrawSurface3));
+    /* And delete texture handle */
+    ENTER_GL();
+    if (glThis->tex_name != 0)
+        glDeleteTextures(1, &(glThis->tex_name));
+    LEAVE_GL();	
+
+    /* And if this texture was the current one, remove it at the device level */
+    if (This->d3ddevice != NULL)
+        if (This->d3ddevice->current_texture[0] == This)
+	    This->d3ddevice->current_texture[0] = NULL;
+
+    /* All this should be part of main surface management not just a hack for texture.. */
+    if (glThis->loaded) {
+        mem_used = This->surface_desc.dwHeight *
+	           This->surface_desc.dwHeight *
+		   This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount;
+	This->ddraw_owner->free_memory(This->ddraw_owner, mem_used);
+    }
 
-	/* And delete texture handle */
-	ENTER_GL();
-	glDeleteTextures(1, &(glThis->tex_name));
-	LEAVE_GL();	
+    glThis->final_release(This);
+}
 
-	/* And if this texture was the current one, remove it at the device level */
-	if (This->d3ddevice != NULL)
-	    if (This->d3ddevice->current_texture[0] == This)
-	        This->d3ddevice->current_texture[0] = NULL;
-
-	if (This->loaded) {
-	    mem_used = This->surface->surface_desc.dwHeight *
-	               This->surface->surface_desc.dwHeight *
-		       This->surface->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount;
-	    This->surface->ddraw_owner->free_memory(This->surface->ddraw_owner, mem_used);
-	}
-	HeapFree(GetProcessHeap(),0,This);
-	return 0;
-    }
+static void
+gltex_lock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect, DWORD dwFlags)
+{
+    IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private;
+    
+    glThis->lock_update(This, pRect, dwFlags);
+}
+
+static void
+gltex_unlock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect)
+{
+    IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private;
 
-    return This->ref;
+    ENTER_GL();
+    gltex_upload_texture(This, glThis->first_unlock);
+    LEAVE_GL();
+    glThis->first_unlock = FALSE;
+
+    glThis->unlock_update(This, pRect);
 }
 
 HRESULT WINAPI
@@ -358,8 +580,8 @@
 				       LPDIRECT3DDEVICE2 lpDirect3DDevice2,
 				       LPD3DTEXTUREHANDLE lpHandle)
 {
-    ICOM_THIS_FROM(IDirect3DTextureImpl, IDirect3DTexture2, iface);
-    IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This;
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface);
+    IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private;
     IDirect3DDeviceImpl *lpDeviceImpl = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice2, lpDirect3DDevice2);
     
     TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpDirect3DDevice2, lpHandle);
@@ -371,16 +593,12 @@
     
     /* Now, bind a new texture */
     This->d3ddevice = lpDeviceImpl;
-    ENTER_GL();
-    if (glThis->tex_name == 0)
-	glGenTextures(1, &(glThis->tex_name));
-    LEAVE_GL();
 
     /* Associate the texture with the device and perform the appropriate AddRef/Release */
     /* FIXME: Is there only one or several textures associated with the device ? */
     if (lpDeviceImpl->current_texture[0] != NULL)
-        IDirect3DTexture2_Release(ICOM_INTERFACE(lpDeviceImpl->current_texture[0], IDirect3DTexture2));           
-    IDirect3DTexture2_AddRef(ICOM_INTERFACE(This, IDirect3DTexture2));
+        IDirectDrawSurface7_Release(ICOM_INTERFACE(lpDeviceImpl->current_texture[0], IDirectDrawSurface7));
+    IDirectDrawSurface7_AddRef(ICOM_INTERFACE(This, IDirectDrawSurface7));
     lpDeviceImpl->current_texture[0] = This;
 
     TRACE("OpenGL texture handle is : %d\n", glThis->tex_name);
@@ -394,49 +612,43 @@
 GL_IDirect3DTextureImpl_2_1T_Load(LPDIRECT3DTEXTURE2 iface,
 				  LPDIRECT3DTEXTURE2 lpD3DTexture2)
 {
-    ICOM_THIS_FROM(IDirect3DTextureImpl, IDirect3DTexture2, iface);
-    IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This;
-    IDirect3DTextureImpl *lpD3DTextureImpl = ICOM_OBJECT(IDirect3DTextureImpl, IDirect3DTexture2, lpD3DTexture2);
+    ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface);
+    IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private;
+    IDirectDrawSurfaceImpl *lpD3DTextureImpl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture2, lpD3DTexture2);
     DWORD mem_used;
-    DDSURFACEDESC	*src_d, *dst_d;
-    static void (*ptr_ColorTableEXT) (GLenum target, GLenum internalformat,
-				      GLsizei width, GLenum format, GLenum type, const GLvoid *table) = NULL;
-#if 0
-    static BOOL color_table_queried = FALSE;
-#endif
+    DDSURFACEDESC *src_d, *dst_d;
     
     TRACE("(%p/%p)->(%p)\n", This, iface, lpD3DTexture2);
 
-    if (This->loaded == FALSE) {
+    if (glThis->loaded == FALSE) {
         /* Only check memory for not already loaded texture... */
-        mem_used = This->surface->surface_desc.dwHeight *
-	           This->surface->surface_desc.dwHeight *
-	           This->surface->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount;
-	if (This->surface->ddraw_owner->allocate_memory(This->surface->ddraw_owner, mem_used) < 0) {
+        mem_used = This->surface_desc.dwHeight *
+	           This->surface_desc.dwHeight *
+	           This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount;
+	if (This->ddraw_owner->allocate_memory(This->ddraw_owner, mem_used) < 0) {
 	    TRACE(" out of virtual memory... Warning application.\n");
 	    return D3DERR_TEXTURE_LOAD_FAILED;
 	}
     }
-    This->loaded = TRUE;
+    glThis->loaded = TRUE;
     
-    TRACE("Copied surface %p to surface %p\n", lpD3DTextureImpl->surface, This->surface);
+    TRACE("Copied surface %p to surface %p\n", lpD3DTextureImpl, This);
 
-    if ( This->surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_ALLOCONLOAD )
+    if ( This->surface_desc.ddsCaps.dwCaps & DDSCAPS_ALLOCONLOAD )
         /* If the surface is not allocated and its location is not yet specified,
 	   force it to video memory */ 
-        if ( !(This->surface->surface_desc.ddsCaps.dwCaps & (DDSCAPS_SYSTEMMEMORY|DDSCAPS_VIDEOMEMORY)) )
-	    This->surface->surface_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
+        if ( !(This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_SYSTEMMEMORY|DDSCAPS_VIDEOMEMORY)) ) {
+	    This->surface_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
+	    WARN("This case is not properly handled yet.. Expect errors !\n");
+	}
 
     /* Suppress the ALLOCONLOAD flag */
-    This->surface->surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_ALLOCONLOAD;
-
+    This->surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_ALLOCONLOAD;
+    This->palette = lpD3DTextureImpl->palette;
+    
     /* Copy one surface on the other */
-    dst_d = (DDSURFACEDESC *)&(This->surface->surface_desc);
-    src_d = (DDSURFACEDESC *)&(lpD3DTextureImpl->surface->surface_desc);
-
-    /* Install the callbacks to the destination surface */
-    This->surface->texture = This;
-    This->surface->SetColorKey_cb = SetColorKey_cb;
+    dst_d = (DDSURFACEDESC *)&(This->surface_desc);
+    src_d = (DDSURFACEDESC *)&(lpD3DTextureImpl->surface_desc);
 
     if ((src_d->dwWidth != dst_d->dwWidth) || (src_d->dwHeight != dst_d->dwHeight)) {
         /* Should also check for same pixel format, u1.lPitch, ... */
@@ -445,204 +657,27 @@
     } else {
         /* LPDIRECT3DDEVICE2 d3dd = (LPDIRECT3DDEVICE2) This->D3Ddevice; */
         /* I should put a macro for the calculus of bpp */
-	GLuint current_texture;
+
+        /* Copy also the ColorKeying stuff */
+        if (src_d->dwFlags & DDSD_CKSRCBLT) {
+	    dst_d->ddckCKSrcBlt.dwColorSpaceLowValue = src_d->ddckCKSrcBlt.dwColorSpaceLowValue;
+	    dst_d->ddckCKSrcBlt.dwColorSpaceHighValue = src_d->ddckCKSrcBlt.dwColorSpaceHighValue;
+	}
 
 	/* Copy the main memry texture into the surface that corresponds to the OpenGL
 	   texture object. */
 	memcpy(dst_d->lpSurface, src_d->lpSurface, src_d->u1.lPitch * src_d->dwHeight);
 
+	/* If the GetHandle was not done, it is an error... */
+	if (glThis->tex_name == 0) ERR("Unbound GL texture !!!\n");
+
 	ENTER_GL();
 
 	/* Now, load the texture */
 	/* d3dd->set_context(d3dd); We need to set the context somehow.... */
-	glGetIntegerv(GL_TEXTURE_BINDING_2D, &current_texture);
-
-	/* If the GetHandle was not done, get the texture name here */
-	if (glThis->tex_name == 0)
-	    glGenTextures(1, &(glThis->tex_name));
-	glBindTexture(GL_TEXTURE_2D, glThis->tex_name);
-
-	if (src_d->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
-	  /* ****************
-	     Paletted Texture
-	     **************** */
-	    IDirectDrawPaletteImpl* pal = lpD3DTextureImpl->surface->palette;
-	    BYTE table[256][4];
-	    int i;
-
-#if 0
-	    if (color_table_queried == FALSE) {
-	        ptr_ColorTableEXT =
-		  ((Mesa_DeviceCapabilities *) ((x11_dd_private *) This->surface->s.ddraw->d->private)->device_capabilities)->ptr_ColorTableEXT;
-	    }
-#endif
 
-	    if (pal == NULL) {
-	        ERR("Palettized texture Loading with a NULL palette !\n");
-		LEAVE_GL();
-		return D3DERR_TEXTURE_LOAD_FAILED;
-	    }
-
-	    /* Get the surface's palette */
-	    for (i = 0; i < 256; i++) {
-	        table[i][0] = pal->palents[i].peRed;
-		table[i][1] = pal->palents[i].peGreen;
-		table[i][2] = pal->palents[i].peBlue;
-		if ((This->surface->surface_desc.dwFlags & DDSD_CKSRCBLT) &&
-		    (i >= This->surface->surface_desc.ddckCKSrcBlt.dwColorSpaceLowValue) &&
-		    (i <= This->surface->surface_desc.ddckCKSrcBlt.dwColorSpaceHighValue))
-		    table[i][3] = 0x00;
-		else
-		    table[i][3] = 0xFF;
-	    }
-
-	    /* Texture snooping */
-	    SNOOP_PALETTED();
-
-	    if (ptr_ColorTableEXT != NULL) {
-	        /* use Paletted Texture Extension */
-	        ptr_ColorTableEXT(GL_TEXTURE_2D,    /* target */
-				  GL_RGBA,          /* internal format */
-				  256,              /* table size */
-				  GL_RGBA,          /* table format */
-				  GL_UNSIGNED_BYTE, /* table type */
-				  table);           /* the color table */
-		
-		glTexImage2D(GL_TEXTURE_2D,       /* target */
-			     0,                   /* level */
-			     GL_COLOR_INDEX8_EXT, /* internal format */
-			     src_d->dwWidth, src_d->dwHeight, /* width, height */
-			     0,                   /* border */
-			     GL_COLOR_INDEX,      /* texture format */
-			     GL_UNSIGNED_BYTE,    /* texture type */
-			     src_d->lpSurface); /* the texture */
-	    } else {
-	        DWORD *surface = (DWORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(DWORD));
-		DWORD i;
-		BYTE *src = (BYTE *) src_d->lpSurface, *dst = (BYTE *) surface;
-		
-		for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
-		    BYTE color = *src++;
-		    *dst++ = table[color][0];
-		    *dst++ = table[color][1];
-		    *dst++ = table[color][2];
-		    *dst++ = table[color][3];
-		}
-		
-		glTexImage2D(GL_TEXTURE_2D,
-			     0,
-			     GL_RGBA,
-			     src_d->dwWidth, src_d->dwHeight,
-			     0,
-			     GL_RGBA,
-			     GL_UNSIGNED_BYTE,
-			     surface);
-		
-		HeapFree(GetProcessHeap(), 0, surface);
-	    }
-	} else if (src_d->ddpfPixelFormat.dwFlags & DDPF_RGB) {
-	    /* ************
-	       RGB Textures
-	       ************ */
-	    if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 8) {
-	        /* **********************
-		   GL_UNSIGNED_BYTE_3_3_2
-		   ********************** */
-	        glTexImage2D(GL_TEXTURE_2D,
-			     0,
-			     GL_RGB,
-			     src_d->dwWidth, src_d->dwHeight,
-			     0,
-			     GL_RGB,
-			     GL_UNSIGNED_BYTE_3_3_2,
-			     src_d->lpSurface);
-	    } else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 16) {
-	        if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000000) {
-		  
-		    /* Texture snooping */
-		    SNOOP_5650();
-		    
-		    glTexImage2D(GL_TEXTURE_2D,
-				 0,
-				 GL_RGB,
-				 src_d->dwWidth, src_d->dwHeight,
-				 0,
-				 GL_RGB,
-				 GL_UNSIGNED_SHORT_5_6_5,
-				 src_d->lpSurface);
-		} else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000001) {
-		    /* Texture snooping */
-		    SNOOP_5551();
-		    
-		    glTexImage2D(GL_TEXTURE_2D,
-				 0,
-				 GL_RGBA,
-				 src_d->dwWidth, src_d->dwHeight,
-				 0,
-				 GL_RGBA,
-				 GL_UNSIGNED_SHORT_5_5_5_1,
-				 src_d->lpSurface);
-		} else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x0000000F) {
-		    glTexImage2D(GL_TEXTURE_2D,
-				 0,
-				 GL_RGBA,
-				 src_d->dwWidth, src_d->dwHeight,
-				 0,
-				 GL_RGBA,
-				 GL_UNSIGNED_SHORT_4_4_4_4,
-				 src_d->lpSurface);
-		} else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00008000) {
-		    /* Converting the 1555 format in 5551 packed */
-		    WORD *surface = (WORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(WORD));
-		    DWORD i;
-		    WORD *src = (WORD *) src_d->lpSurface, *dst = surface;
-		    
-		    for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
-		        *dst++ = (((*src & 0x8000) >> 15) |
-				  ((*src & 0x7FFF) <<  1));
-			src++;
-		    }
-		    SNOOP_1555();
-		    
-		    glTexImage2D(GL_TEXTURE_2D,
-				 0,
-				 GL_RGBA,
-				 src_d->dwWidth, src_d->dwHeight,
-				 0,
-				 GL_RGBA,
-				 GL_UNSIGNED_SHORT_5_5_5_1,
-				 surface);
-		    
-		    HeapFree(GetProcessHeap(), 0, surface);
-		} else {
-		    ERR("Unhandled texture format (bad Aplha channel for a 16 bit texture)\n");
-		}
-	    } else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 24) {
-	        glTexImage2D(GL_TEXTURE_2D,
-			     0,
-			     GL_RGB,
-			     src_d->dwWidth, src_d->dwHeight,
-			     0,
-			     GL_RGB,
-			     GL_UNSIGNED_BYTE,
-			     src_d->lpSurface);
-	    } else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 32) {
-	        glTexImage2D(GL_TEXTURE_2D,
-			     0,
-			     GL_RGBA,
-			     src_d->dwWidth, src_d->dwHeight,
-			     0,
-			     GL_RGBA,
-			     GL_UNSIGNED_BYTE,
-			     src_d->lpSurface);
-	    } else {
-	        ERR("Unhandled texture format (bad RGB count)\n");
-	    }
-	} else {
-	    ERR("Unhandled texture format (neither RGB nor INDEX)\n");
-	}
-	
-	glBindTexture(GL_TEXTURE_2D, current_texture);
+	gltex_upload_texture(This, glThis->first_unlock);
+	glThis->first_unlock = FALSE;
 	
 	LEAVE_GL();
     }
@@ -651,28 +686,53 @@
 }
 
 HRESULT WINAPI
+Thunk_IDirect3DTextureImpl_2_QueryInterface(LPDIRECT3DTEXTURE2 iface,
+                                            REFIID riid,
+                                            LPVOID* obp)
+{
+    TRACE("(%p)->(%s,%p) thunking to IDirectDrawSurface7 interface.\n", iface, debugstr_guid(riid), obp);
+    return IDirectDrawSurface7_QueryInterface(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture2, IDirectDrawSurface7, iface),
+					      riid,
+					      obp);
+}
+
+ULONG WINAPI
+Thunk_IDirect3DTextureImpl_2_AddRef(LPDIRECT3DTEXTURE2 iface)
+{
+    TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", iface);
+    return IDirectDrawSurface7_AddRef(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture2, IDirectDrawSurface7, iface));
+}
+
+ULONG WINAPI
+Thunk_IDirect3DTextureImpl_2_Release(LPDIRECT3DTEXTURE2 iface)
+{
+    TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", iface);
+    return IDirectDrawSurface7_AddRef(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture2, IDirectDrawSurface7, iface));
+}
+
+HRESULT WINAPI
 Thunk_IDirect3DTextureImpl_1_QueryInterface(LPDIRECT3DTEXTURE iface,
                                             REFIID riid,
                                             LPVOID* obp)
 {
-    TRACE("(%p)->(%s,%p) thunking to IDirect3DTexture2 interface.\n", iface, debugstr_guid(riid), obp);
-    return IDirect3DTexture2_QueryInterface(COM_INTERFACE_CAST(IDirect3DTextureImpl, IDirect3DTexture, IDirect3DTexture2, iface),
-                                            riid,
-                                            obp);
+    TRACE("(%p)->(%s,%p) thunking to IDirectDrawSurface7 interface.\n", iface, debugstr_guid(riid), obp);
+    return IDirectDrawSurface7_QueryInterface(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirectDrawSurface7, iface),
+					      riid,
+					      obp);
 }
 
 ULONG WINAPI
 Thunk_IDirect3DTextureImpl_1_AddRef(LPDIRECT3DTEXTURE iface)
 {
-    TRACE("(%p)->() thunking to IDirect3DTexture2 interface.\n", iface);
-    return IDirect3DTexture2_AddRef(COM_INTERFACE_CAST(IDirect3DTextureImpl, IDirect3DTexture, IDirect3DTexture2, iface));
+    TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", iface);
+    return IDirectDrawSurface7_AddRef(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirectDrawSurface7, iface));
 }
 
 ULONG WINAPI
 Thunk_IDirect3DTextureImpl_1_Release(LPDIRECT3DTEXTURE iface)
 {
-    TRACE("(%p)->() thunking to IDirect3DTexture2 interface.\n", iface);
-    return IDirect3DTexture2_Release(COM_INTERFACE_CAST(IDirect3DTextureImpl, IDirect3DTexture, IDirect3DTexture2, iface));
+    TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", iface);
+    return IDirectDrawSurface7_AddRef(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirectDrawSurface7, iface));
 }
 
 HRESULT WINAPI
@@ -681,7 +741,7 @@
                                             DWORD dwCount)
 {
     TRACE("(%p)->(%08lx,%08lx) thunking to IDirect3DTexture2 interface.\n", iface, dwStart, dwCount);
-    return IDirect3DTexture2_PaletteChanged(COM_INTERFACE_CAST(IDirect3DTextureImpl, IDirect3DTexture, IDirect3DTexture2, iface),
+    return IDirect3DTexture2_PaletteChanged(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirect3DTexture2, iface),
                                             dwStart,
                                             dwCount);
 }
@@ -692,7 +752,7 @@
 				       LPD3DTEXTUREHANDLE lpHandle)
 {
     TRACE("(%p)->(%p,%p) thunking to IDirect3DTexture2 interface.\n", iface, lpDirect3DDevice, lpHandle);
-    return IDirect3DTexture2_GetHandle(COM_INTERFACE_CAST(IDirect3DTextureImpl, IDirect3DTexture, IDirect3DTexture2, iface),
+    return IDirect3DTexture2_GetHandle(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirect3DTexture2, iface),
 				       COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice2, lpDirect3DDevice),
 				       lpHandle);
 }
@@ -702,8 +762,8 @@
 				  LPDIRECT3DTEXTURE lpD3DTexture)
 {
     TRACE("(%p)->(%p) thunking to IDirect3DTexture2 interface.\n", iface, lpD3DTexture);
-    return IDirect3DTexture2_Load(COM_INTERFACE_CAST(IDirect3DTextureImpl, IDirect3DTexture, IDirect3DTexture2, iface),
-				  COM_INTERFACE_CAST(IDirect3DTextureImpl, IDirect3DTexture, IDirect3DTexture2, lpD3DTexture));
+    return IDirect3DTexture2_Load(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirect3DTexture2, iface),
+				  COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirect3DTexture2, lpD3DTexture));
 }
 
 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
@@ -715,9 +775,9 @@
 ICOM_VTABLE(IDirect3DTexture2) VTABLE_IDirect3DTexture2 =
 {
     ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-    XCAST(QueryInterface) Main_IDirect3DTextureImpl_2_1T_QueryInterface,
-    XCAST(AddRef) Main_IDirect3DTextureImpl_2_1T_AddRef,
-    XCAST(Release) GL_IDirect3DTextureImpl_2_1T_Release,
+    XCAST(QueryInterface) Thunk_IDirect3DTextureImpl_2_QueryInterface,
+    XCAST(AddRef) Thunk_IDirect3DTextureImpl_2_AddRef,
+    XCAST(Release) Thunk_IDirect3DTextureImpl_2_Release,
     XCAST(GetHandle) GL_IDirect3DTextureImpl_2_1T_GetHandle,
     XCAST(PaletteChanged) Main_IDirect3DTextureImpl_2_1T_PaletteChanged,
     XCAST(Load) GL_IDirect3DTextureImpl_2_1T_Load,
@@ -751,26 +811,50 @@
 #undef XCAST
 #endif
 
-
-
-
-HRESULT d3dtexture_create(IDirect3DTextureImpl **obj, IDirect3DImpl *d3d, IDirectDrawSurfaceImpl *surf)
+HRESULT d3dtexture_create(IDirect3DImpl *d3d, IDirectDrawSurfaceImpl *surf, BOOLEAN at_creation, 
+			  IDirectDrawSurfaceImpl *main, DWORD mipmap_level)
 {
-    IDirect3DTextureImpl *object;
+    IDirect3DTextureGLImpl *private;
 
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DTextureGLImpl));
-    if (object == NULL) return DDERR_OUTOFMEMORY;
+    private = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DTextureGLImpl));
+    if (private == NULL) return DDERR_OUTOFMEMORY;
 
-    object->ref = 1;
-    object->d3d = d3d;
-    object->surface = surf;
+    private->final_release = surf->final_release;
+    private->lock_update = surf->lock_update;
+    private->unlock_update = surf->unlock_update;
+    private->mipmap_level = mipmap_level;
+    
+    /* If at creation, we can optimize stuff and wait the first 'unlock' to upload a valid stuff to OpenGL.
+       Otherwise, it will be uploaded here (and may be invalid). */
+    if (at_creation == TRUE)
+        private->first_unlock = TRUE;
+    else
+        private->first_unlock = FALSE;
+    surf->final_release = gltex_final_release;
+    surf->lock_update = gltex_lock_update;
+    surf->unlock_update = gltex_unlock_update;
+    surf->tex_private = private;
+    surf->SetColorKey_cb = gltex_setcolorkey_cb;
     
-    ICOM_INIT_INTERFACE(object, IDirect3DTexture,  VTABLE_IDirect3DTexture);
-    ICOM_INIT_INTERFACE(object, IDirect3DTexture2, VTABLE_IDirect3DTexture2);
+    ICOM_INIT_INTERFACE(surf, IDirect3DTexture,  VTABLE_IDirect3DTexture);
+    ICOM_INIT_INTERFACE(surf, IDirect3DTexture2, VTABLE_IDirect3DTexture2);
+
+    if (mipmap_level == 0) {
+        ENTER_GL();
+	glGenTextures(1, &(private->tex_name));
+	if (private->tex_name == 0) ERR("Error at creation of OpenGL texture ID !\n");
+	TRACE(" GL texture created (private data at %p and GL id %d).\n", private, private->tex_name);
+    } else {
+        private->tex_name = ((IDirect3DTextureGLImpl *) main->tex_private)->tex_name;
+	TRACE(" GL texture created (private data at %p and GL id reusing id %d).\n", private, private->tex_name);
+    }
 
-    *obj = object;
+    if ((at_creation == FALSE) &&
+	((surf->surface_desc.ddsCaps.dwCaps & DDSCAPS_ALLOCONLOAD) == 0))
+    {
+        gltex_upload_texture(surf, TRUE);
+    }
+    LEAVE_GL();
 
-    TRACE(" creating implementation at %p.\n", *obj);
-    
     return D3D_OK;
 }
Index: dlls/ddraw/d3dvertexbuffer.c
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/d3dvertexbuffer.c,v
retrieving revision 1.3
diff -u -r1.3 d3dvertexbuffer.c
--- dlls/ddraw/d3dvertexbuffer.c	5 Dec 2002 20:33:09 -0000	1.3
+++ dlls/ddraw/d3dvertexbuffer.c	14 Dec 2002 20:14:50 -0000
@@ -303,7 +303,7 @@
     object->ref = 1;
     object->d3d = d3d;
     object->desc = *lpD3DVertBufDesc;
-    object->vertex_buffer_size = get_flexible_vertex_size(lpD3DVertBufDesc->dwFVF) * lpD3DVertBufDesc->dwNumVertices;
+    object->vertex_buffer_size = get_flexible_vertex_size(lpD3DVertBufDesc->dwFVF, NULL) * lpD3DVertBufDesc->dwNumVertices;
     object->vertices = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->vertex_buffer_size);
     
     ICOM_INIT_INTERFACE(object, IDirect3DVertexBuffer,  VTABLE_IDirect3DVertexBuffer);
Index: dlls/ddraw/ddraw_private.h
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/ddraw_private.h,v
retrieving revision 1.31
diff -u -r1.31 ddraw_private.h
--- dlls/ddraw/ddraw_private.h	30 Nov 2002 19:06:53 -0000	1.31
+++ dlls/ddraw/ddraw_private.h	14 Dec 2002 20:14:51 -0000
@@ -26,6 +26,7 @@
 #include "wingdi.h"
 #include "winuser.h"
 #include "ddraw.h"
+#include "d3d.h"
 #include "ddcomimpl.h"
 #include "ddrawi.h"
 
@@ -220,6 +221,8 @@
     ICOM_VFIELD_MULTI(IDirectDrawSurface7);
     ICOM_VFIELD_MULTI(IDirectDrawSurface3);
     ICOM_VFIELD_MULTI(IDirectDrawGammaControl);
+    ICOM_VFIELD_MULTI(IDirect3DTexture2);
+    ICOM_VFIELD_MULTI(IDirect3DTexture);
     DWORD ref;
 
     struct IDirectDrawSurfaceImpl* attached; /* attached surfaces */
@@ -289,10 +292,10 @@
     void (*aux_release)(LPVOID ctx, LPVOID data);
     BOOL (*aux_flip)(LPVOID ctx, LPVOID data);
     void (*aux_unlock)(LPVOID ctx, LPVOID data, LPRECT lpRect);
-    struct IDirect3DTextureImpl *texture;
-    HRESULT (WINAPI *SetColorKey_cb)(struct IDirect3DTextureImpl *texture, DWORD dwFlags, LPDDCOLORKEY ckey ) ;
+    HRESULT (WINAPI *SetColorKey_cb)(struct IDirectDrawSurfaceImpl *texture, DWORD dwFlags, LPDDCOLORKEY ckey ) ;
     /* This is to get the D3DDevice object associated to this surface */
     struct IDirect3DDeviceImpl *d3ddevice;
+    LPVOID tex_private;
 };
 
 /*****************************************************************************
Index: dlls/ddraw/mesa.c
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/mesa.c,v
retrieving revision 1.11
diff -u -r1.11 mesa.c
--- dlls/ddraw/mesa.c	5 Dec 2002 20:33:09 -0000	1.11
+++ dlls/ddraw/mesa.c	14 Dec 2002 20:14:51 -0000
@@ -46,14 +46,14 @@
 	/* All others state variables */
 	switch (dwRenderStateType) {
 	    case D3DRENDERSTATE_TEXTUREHANDLE: {    /*  1 */
-	        IDirect3DTextureImpl *tex = (IDirect3DTextureImpl*) dwRenderState;
+	        IDirectDrawSurfaceImpl *tex = (IDirectDrawSurfaceImpl*) dwRenderState;
 		
 		if (tex == NULL) {
 		    glBindTexture(GL_TEXTURE_2D, 0);
 		    glDisable(GL_TEXTURE_2D);
 		    TRACE("disabling texturing\n");
 		} else {
-		    IDirect3DTextureGLImpl *gl_tex = (IDirect3DTextureGLImpl *) tex;
+		    IDirect3DTextureGLImpl *gl_tex = (IDirect3DTextureGLImpl *) tex->tex_private;
 		    
 		    glEnable(GL_TEXTURE_2D);
 		    /* Default parameters */
Index: dlls/ddraw/mesa_private.h
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/mesa_private.h,v
retrieving revision 1.21
diff -u -r1.21 mesa_private.h
--- dlls/ddraw/mesa_private.h	5 Dec 2002 19:07:59 -0000	1.21
+++ dlls/ddraw/mesa_private.h	14 Dec 2002 20:14:51 -0000
@@ -82,10 +82,17 @@
     GLenum light_num;
 } IDirect3DLightGLImpl;
 
+/* This structure is used for the 'private' field of the IDirectDrawSurfaceImpl structure */
 typedef struct IDirect3DTextureGLImpl
 {
-    struct IDirect3DTextureImpl parent;
     GLuint tex_name;
+    BOOLEAN loaded; /* For the moment, this is here.. Should be part of surface management though */
+    BOOLEAN first_unlock;
+    DWORD mipmap_level;
+    /* This is for now used to override 'standard' surface stuff to be as transparent as possible */
+    void (*final_release)(struct IDirectDrawSurfaceImpl *This);
+    void (*lock_update)(IDirectDrawSurfaceImpl* This, LPCRECT pRect, DWORD dwFlags);
+    void (*unlock_update)(IDirectDrawSurfaceImpl* This, LPCRECT pRect);
 } IDirect3DTextureGLImpl;
 
 typedef struct IDirect3DDeviceGLImpl
@@ -111,7 +118,7 @@
 
 /* All non-static functions 'exported' by various sub-objects */
 extern HRESULT direct3d_create(IDirect3DImpl **obj, IDirectDrawImpl *ddraw);
-extern HRESULT d3dtexture_create(IDirect3DTextureImpl **obj, IDirect3DImpl *d3d, IDirectDrawSurfaceImpl *surf);
+extern HRESULT d3dtexture_create(IDirect3DImpl *d3d, IDirectDrawSurfaceImpl *surf, BOOLEAN at_creation, IDirectDrawSurfaceImpl *main_surf, DWORD mipmap_level);
 extern HRESULT d3dlight_create(IDirect3DLightImpl **obj, IDirect3DImpl *d3d, GLenum light_num);
 extern HRESULT d3dexecutebuffer_create(IDirect3DExecuteBufferImpl **obj, IDirect3DImpl *d3d, IDirect3DDeviceImpl *d3ddev, LPD3DEXECUTEBUFFERDESC lpDesc);
 extern HRESULT d3dmaterial_create(IDirect3DMaterialImpl **obj, IDirect3DImpl *d3d);
@@ -126,7 +133,7 @@
 
 /* Some helper functions.. Would need to put them in a better place */
 extern void dump_flexible_vertex(DWORD d3dvtVertexType);
-extern DWORD get_flexible_vertex_size(DWORD d3dvtVertexType);
+extern DWORD get_flexible_vertex_size(DWORD d3dvtVertexType, DWORD *elements);
 
 /* Matrix copy WITH transposition */
 #define conv_mat2(mat,gl_mat)			\
Index: dlls/ddraw/d3ddevice/mesa.c
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/d3ddevice/mesa.c,v
retrieving revision 1.37
diff -u -r1.37 mesa.c
--- dlls/ddraw/d3ddevice/mesa.c	5 Dec 2002 20:33:09 -0000	1.37
+++ dlls/ddraw/d3ddevice/mesa.c	14 Dec 2002 20:14:52 -0000
@@ -160,7 +160,7 @@
     fill_opengl_primcaps(&(d1->dpcLineCaps));
     fill_opengl_primcaps(&(d1->dpcTriCaps));
     d1->dwDeviceRenderBitDepth  = DDBD_16|DDBD_24|DDBD_32;
-    d1->dwDeviceZBufferBitDepth = DDBD_16;
+    d1->dwDeviceZBufferBitDepth = DDBD_16|DDBD_24|DDBD_32;
     d1->dwMaxBufferSize = 0;
     d1->dwMaxVertexCount = 65536;
     d1->dwMinTextureWidth  = 1;
@@ -842,19 +842,23 @@
     return ret_value;
 }
 
-DWORD get_flexible_vertex_size(DWORD d3dvtVertexType)
+DWORD get_flexible_vertex_size(DWORD d3dvtVertexType, DWORD *elements)
 {
     DWORD size = 0;
+    DWORD elts = 0;
     
-    if (d3dvtVertexType & D3DFVF_NORMAL) size += 3 * sizeof(D3DVALUE);
-    if (d3dvtVertexType & D3DFVF_DIFFUSE) size += sizeof(DWORD);
-    if (d3dvtVertexType & D3DFVF_SPECULAR) size += sizeof(DWORD);
+    if (d3dvtVertexType & D3DFVF_NORMAL) { size += 3 * sizeof(D3DVALUE); elts += 1; }
+    if (d3dvtVertexType & D3DFVF_DIFFUSE) { size += sizeof(DWORD); elts += 1; }
+    if (d3dvtVertexType & D3DFVF_SPECULAR) { size += sizeof(DWORD); elts += 1; }
     switch (d3dvtVertexType & D3DFVF_POSITION_MASK) {
-        case D3DFVF_XYZ: size += 3 * sizeof(D3DVALUE); break;
-        case D3DFVF_XYZRHW: size += 4 * sizeof(D3DVALUE); break;
+        case D3DFVF_XYZ: size += 3 * sizeof(D3DVALUE); elts += 1; break;
+        case D3DFVF_XYZRHW: size += 4 * sizeof(D3DVALUE); elts += 1; break;
 	default: TRACE(" matrix weighting not handled yet...\n");
     }
     size += 2 * sizeof(D3DVALUE) * ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT);
+    elts += (d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT;
+
+    if (elements) *elements = elts;
 
     return size;
 }
@@ -908,6 +912,48 @@
     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));
+}
+static void handle_xyzrhw(char *vertex, int offset, int extra) {
+    float *coords = (float *) (vertex + offset);
+    if (coords[3] < 0.00001)
+        glVertex3f(coords[0], coords[1], coords[2]);
+    else
+        glVertex4f(coords[0] / coords[3],
+		   coords[1] / coords[3],
+		   coords[2] / coords[3],
+		   1.0 / coords[3]);
+}
+static void handle_normal(char *vertex, int offset, int extra) {
+    glNormal3fv((float *) (vertex + offset));
+}
+static void handle_specular(char *vertex, int offset, int extra) {
+    /* Specular not handled yet properly... */
+}
+static void handle_diffuse(char *vertex, int offset, int extra) {
+    DWORD color = *((DWORD *) (vertex + offset));
+    glColor4ub((color >> 24) & 0xFF,
+	       (color >> 16) & 0xFF,
+	       (color >>  8) & 0xFF,
+	       (color >>  0) & 0xFF);
+}
+static void handle_texture(char *vertex, int offset, int extra) {
+    if (extra == 0xFF) {
+        /* Special case for single texture... */
+        glTexCoord2fv((float *) (vertex + offset));
+    } else {
+        /* Multitexturing not handled yet */
+    }
+}
+
 static void draw_primitive_7(IDirect3DDeviceImpl *This,
 			     D3DPRIMITIVETYPE d3dptPrimitiveType,
 			     DWORD d3dvtVertexType,
@@ -936,9 +982,9 @@
 	for (index = 0; index < dwIndexCount; index++) {
 	    int i = (dwIndices == NULL) ? index : dwIndices[index];
 	  
-	    glNormal3f(vertices[i].nx, vertices[i].ny, vertices[i].nz);
-	    glTexCoord2f(vertices[i].tu1, vertices[i].tv1);
-	    glVertex3f(vertices[i].x, vertices[i].y, vertices[i].z);
+	    glNormal3fv(&(vertices[i].nx));
+	    glTexCoord2fv(&(vertices[i].tu1));
+	    glVertex3fv(&(vertices[i].x));
 	    TRACE(" %f %f %f / %f %f %f (%f %f)\n",
 		  vertices[i].x, vertices[i].y, vertices[i].z,
 		  vertices[i].nx, vertices[i].ny, vertices[i].nz,
@@ -956,7 +1002,7 @@
 		       (vertices[i].diffuse >>  8) & 0xFF,
 		       (vertices[i].diffuse >>  0) & 0xFF);
 	    /* Todo : handle specular... */
-	    glTexCoord2f(vertices[i].tu1, vertices[i].tv1);
+	    glTexCoord2fv(&(vertices[i].tu1));
 	    if (vertices[i].rhw < 0.00001)
 	        glVertex3f(vertices[i].x, vertices[i].y, vertices[i].z);
 	    else
@@ -976,6 +1022,76 @@
 		  (vertices[i].specular >>  0) & 0xFF,
 		  vertices[i].tu1, vertices[i].tv1);
 	} 
+    } else if (((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) ||
+	       ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW)) {
+        /* This is the 'slow path' but that should support all possible vertex formats out there...
+	   Note that people should write a fast path for all vertex formats out there...
+	*/
+        DWORD elements;
+	DWORD size = get_flexible_vertex_size(d3dvtVertexType, &elements);
+	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));
+
+	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++) {
+	        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);
+	    }
+	}
+
+	for (index = 0; index < dwIndexCount; index++) {
+	    int i = (dwIndices == NULL) ? index : dwIndices[index];
+	    int elt;
+	    char *vertex = vertices + (i * size);
+
+	    for (elt = 0; elt < elements; elt++) {
+	        handler[elt].handler(vertex, handler[elt].offset, handler[elt].extra);
+	    }
+	}
+    } else {
+        ERR(" matrix weighting not handled yet....\n");
     }
     
     glEnd();
@@ -1130,11 +1246,11 @@
 	glBindTexture(GL_TEXTURE_2D, 0);
         glDisable(GL_TEXTURE_2D);
     } else {
-        IDirect3DTextureImpl *tex_impl = ICOM_OBJECT(IDirect3DTextureImpl, IDirect3DTexture2, lpTexture2);
-	IDirect3DTextureGLImpl *tex_glimpl = (IDirect3DTextureGLImpl *) tex_impl;
+        IDirectDrawSurfaceImpl *tex_impl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture2, lpTexture2);
+	IDirect3DTextureGLImpl *tex_glimpl = (IDirect3DTextureGLImpl *) tex_impl->tex_private;
 	
 	This->current_texture[dwStage] = tex_impl;
-	IDirect3DTexture2_AddRef(lpTexture2);
+	IDirectDrawSurface7_AddRef(ICOM_INTERFACE(tex_impl, IDirectDrawSurface7));
 
 	TRACE(" activating OpenGL texture %d.\n", tex_glimpl->tex_name);
 	
@@ -1453,7 +1569,6 @@
 	    LEAVE_GL();
 	    return;
 	}
-
 	glRasterPos2f(0.0, 0.0);
 	glDrawPixels(This->surface_desc.dwWidth, This->surface_desc.dwHeight, 
 		     GL_RGB, buffer_type, This->surface_desc.lpSurface);
Index: dlls/ddraw/ddraw/main.c
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/ddraw/main.c,v
retrieving revision 1.28
diff -u -r1.28 main.c
--- dlls/ddraw/ddraw/main.c	27 Nov 2002 21:38:28 -0000	1.28
+++ dlls/ddraw/ddraw/main.c	14 Dec 2002 20:14:52 -0000
@@ -177,7 +177,10 @@
 	*obj = ICOM_INTERFACE(This, IDirectDraw4);
     }
 #ifdef HAVE_OPENGL
-    else if ( IsEqualGUID( &IID_IDirect3D , refiid ) )
+    else if ( IsEqualGUID( &IID_IDirect3D  , refiid ) ||
+	      IsEqualGUID( &IID_IDirect3D2 , refiid ) ||
+	      IsEqualGUID( &IID_IDirect3D3 , refiid ) ||
+	      IsEqualGUID( &IID_IDirect3D7 , refiid ) )
     {
         IDirect3DImpl *d3d_impl;
 	HRESULT ret_value;
@@ -185,48 +188,22 @@
 	ret_value = direct3d_create(&d3d_impl, This);
 	if (FAILED(ret_value)) return ret_value;
 
-	*obj = ICOM_INTERFACE(d3d_impl, IDirect3D);
+	if ( IsEqualGUID( &IID_IDirect3D  , refiid ) ) {
+  	    *obj = ICOM_INTERFACE(d3d_impl, IDirect3D);
+	    TRACE(" returning Direct3D interface at %p.\n", *obj);	    
+	} else 	if ( IsEqualGUID( &IID_IDirect3D2  , refiid ) ) {
+  	    *obj = ICOM_INTERFACE(d3d_impl, IDirect3D2);
+	    TRACE(" returning Direct3D2 interface at %p.\n", *obj);	    
+	} else 	if ( IsEqualGUID( &IID_IDirect3D3  , refiid ) ) {
+  	    *obj = ICOM_INTERFACE(d3d_impl, IDirect3D3);
+	    TRACE(" returning Direct3D3 interface at %p.\n", *obj);	    
+	} else {
+  	    *obj = ICOM_INTERFACE(d3d_impl, IDirect3D7);
+	    TRACE(" returning Direct3D7 interface at %p.\n", *obj);	    
+	}
 
 	/* And store the D3D object */
 	This->d3d = d3d_impl;
-	
-	TRACE(" returning Direct3D interface at %p.\n", *obj);
-    }
-    else if ( IsEqualGUID( &IID_IDirect3D2 , refiid ) )
-    {
-        IDirect3DImpl *d3d_impl;
-	HRESULT ret_value;
-
-	ret_value = direct3d_create(&d3d_impl, This);
-	if (FAILED(ret_value)) return ret_value;
-
-	*obj = ICOM_INTERFACE(d3d_impl, IDirect3D2);
-
-	TRACE(" returning Direct3D2 interface at %p.\n", *obj);
-    }
-    else if ( IsEqualGUID( &IID_IDirect3D3 , refiid ) )
-    {
-        IDirect3DImpl *d3d_impl;
-	HRESULT ret_value;
-
-	ret_value = direct3d_create(&d3d_impl, This);
-	if (FAILED(ret_value)) return ret_value;
-
-	*obj = ICOM_INTERFACE(d3d_impl, IDirect3D3);
-
-	TRACE(" returning Direct3D3 interface at %p.\n", *obj);
-    }
-    else if ( IsEqualGUID( &IID_IDirect3D7 , refiid ) )
-    {
-        IDirect3DImpl *d3d_impl;
-	HRESULT ret_value;
-
-	ret_value = direct3d_create(&d3d_impl, This);
-	if (FAILED(ret_value)) return ret_value;
-
-	*obj = ICOM_INTERFACE(d3d_impl, IDirect3D7);
-
-	TRACE(" returning Direct3D7 interface at %p.\n", *obj);
     }
 #endif
     else
@@ -375,6 +352,9 @@
     hr = This->create_texture(This, &ddsd, ppSurf, pUnkOuter, mipmap_level);
     if (FAILED(hr)) return hr;
 
+    if (This->d3d) This->d3d->create_texture(This->d3d, ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, *ppSurf), TRUE, 
+					     ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, *ppSurf), mipmap_level);
+
     /* Create attached mipmaps if required. */
     if (more_mipmaps(&ddsd))
     {
@@ -411,6 +391,8 @@
 		IDirectDrawSurface7_Release(*ppSurf);
 		return hr;
 	    }
+	    if (This->d3d) This->d3d->create_texture(This->d3d, ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, *ppSurf), TRUE,
+						     ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, *ppSurf), mipmap_level);
 
 	    IDirectDrawSurface7_AddAttachedSurface(prev_mipmap, mipmap);
 	    IDirectDrawSurface7_Release(prev_mipmap);
@@ -1130,6 +1112,11 @@
 {
     ICOM_THIS(IDirectDrawImpl,iface);
     TRACE("(%p)->(%p,%p,%p)\n", This,ddscaps,total,free);
+
+    if (TRACE_ON(ddraw)) {
+        TRACE(" Asking for memory of type : \n");
+        DDRAW_dump_DDSCAPS2(ddscaps);
+    }
 
     /* We have 16 MB videomemory */
     if (total)	*total= This->total_vidmem;
Index: dlls/ddraw/direct3d/mesa.c
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/direct3d/mesa.c,v
retrieving revision 1.19
diff -u -r1.19 mesa.c
--- dlls/ddraw/direct3d/mesa.c	5 Dec 2002 19:07:59 -0000	1.19
+++ dlls/ddraw/direct3d/mesa.c	14 Dec 2002 20:14:53 -0000
@@ -387,6 +387,7 @@
 
     object->ref = 1;
     object->ddraw = ddraw;
+    object->create_texture = d3dtexture_create;
     
     ICOM_INIT_INTERFACE(object, IDirect3D,  VTABLE_IDirect3D);
     ICOM_INIT_INTERFACE(object, IDirect3D2, VTABLE_IDirect3D2);
Index: dlls/ddraw/dsurface/main.c
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/dsurface/main.c,v
retrieving revision 1.36
diff -u -r1.36 main.c
--- dlls/ddraw/dsurface/main.c	27 Nov 2002 21:38:28 -0000	1.36
+++ dlls/ddraw/dsurface/main.c	14 Dec 2002 20:14:53 -0000
@@ -81,7 +81,7 @@
 			DDRAW_IDDS3_Thunk_VTable);
     ICOM_INIT_INTERFACE(This, IDirectDrawGammaControl,
 			DDRAW_IDDGC_VTable);
-    /* There is no generic implementation of IDDS7 */
+    /* There is no generic implementation of IDDS7 or texture */
 
     Main_DirectDraw_AddSurface(pDD, This);
     return DD_OK;
@@ -101,6 +101,7 @@
 {
     This->final_release(This);
     if (This->private != This+1) HeapFree(GetProcessHeap(), 0, This->private);
+    if (This->tex_private) HeapFree(GetProcessHeap(), 0, This->tex_private);
     HeapFree(GetProcessHeap(), 0, This);
 }
 
@@ -146,6 +147,8 @@
     ICOM_THIS(IDirectDrawSurfaceImpl, iface);
     TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid), ppObj);
 
+    *ppObj = NULL;
+
     if (IsEqualGUID(&IID_IUnknown, riid)
 	|| IsEqualGUID(&IID_IDirectDrawSurface7, riid)
 	|| IsEqualGUID(&IID_IDirectDrawSurface4, riid))
@@ -184,32 +187,38 @@
 	This->ref++; /* No idea if this is correct.. Need to check using real Windows */
 	return ret_value;
     }
-    else if (IsEqualGUID( &IID_IDirect3DTexture, riid ))
+    else if (IsEqualGUID( &IID_IDirect3DTexture, riid ) ||
+	     IsEqualGUID( &IID_IDirect3DTexture2, riid ))
     {
-        IDirect3DTextureImpl *d3dteximpl;
-	HRESULT ret_value;
-
-	ret_value = d3dtexture_create(&d3dteximpl, NULL, This);
-	if (FAILED(ret_value)) return ret_value;
+	HRESULT ret_value = S_OK;
 
-	*ppObj = ICOM_INTERFACE(d3dteximpl, IDirect3DTexture);
-	TRACE(" returning Direct3DTexture interface at %p.\n", *ppObj);
-	
-	This->ref++; /* No idea if this is correct.. Need to check using real Windows */
-	return ret_value;
-    }    
-    else if (IsEqualGUID( &IID_IDirect3DTexture2, riid ))
-    {
-        IDirect3DTextureImpl *d3dteximpl;
-	HRESULT ret_value;
-
-	ret_value = d3dtexture_create(&d3dteximpl, NULL, This);
-	if (FAILED(ret_value)) return ret_value;
-
-	*ppObj = ICOM_INTERFACE(d3dteximpl, IDirect3DTexture2);
-	TRACE(" returning Direct3DTexture2 interface at %p.\n", *ppObj);
-	
-	This->ref++; /* No idea if this is correct.. Need to check using real Windows */
+	/* In case the texture surface was created before the D3D creation */
+	if ((This->surface_desc.ddsCaps.dwCaps & DDSCAPS_TEXTURE) == 0) return E_NOINTERFACE;
+	/* Create a 'delayed' private field only if it is not an offscreen texture... */
+	if ((This->tex_private == NULL) && 
+	    ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY)) == 0)) {
+   	    if (This->ddraw_owner->d3d == NULL) {
+	        ERR("Texture created with no D3D object yet.. Not supported !\n");
+		return E_NOINTERFACE;
+	    }
+
+	    if (((This->surface_desc.dwFlags & DDSD_MIPMAPCOUNT) &&
+		 (This->surface_desc.u2.dwMipMapCount > 1)) ||
+		(This->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_MIPMAPSUBLEVEL)) {
+	        ERR(" need to fix mipmaping in this case !!\n");
+	    }
+
+	    ret_value = This->ddraw_owner->d3d->create_texture(This->ddraw_owner->d3d, This, FALSE, NULL, 0);
+	    if (FAILED(ret_value)) return ret_value;
+	}
+	if (IsEqualGUID( &IID_IDirect3DTexture, riid )) {
+	    *ppObj = ICOM_INTERFACE(This, IDirect3DTexture);
+	    TRACE(" returning Direct3DTexture interface at %p.\n", *ppObj);
+	} else {
+	    *ppObj = ICOM_INTERFACE(This, IDirect3DTexture2);
+	    TRACE(" returning Direct3DTexture2 interface at %p.\n", *ppObj);
+	}
+	This->ref++;
 	return ret_value;
     }    
 #endif


More information about the wine-patches mailing list