[D3D] Handle more properly versions for Direct3D and Direct3DDevice objects.

Christian Costa titan.costa at wanadoo.fr
Fri Feb 11 16:51:17 CST 2005


Hi,

This patch fixes particularly a wrong DXT texture formats enumeration 
that caused SuperBike to hang.
Thanks to Lionel Ulmer and Carlos Lozano (testing, ideas, etc...).

Changelog:
Handle more properly versions for Direct3D and Direct3DDevice objects.

Christian Costa   titan.costa at wanadoo.fr

-------------- next part --------------
Index: dlls/ddraw/d3d_private.h
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/d3d_private.h,v
retrieving revision 1.41
diff -u -r1.41 d3d_private.h
--- dlls/ddraw/d3d_private.h	6 Aug 2004 17:30:44 -0000	1.41
+++ dlls/ddraw/d3d_private.h	11 Feb 2005 21:23:00 -0000
@@ -197,6 +197,9 @@
     ICOM_VFIELD_MULTI(IDirect3DDevice);
     DWORD  ref;
 
+    /* Version of the Direct3D object from which the device has been created */
+    DWORD version;
+
     /* IDirect3DDevice fields */
     IDirectDrawImpl *d3d;
     IDirectDrawSurfaceImpl *surface;
Index: dlls/ddraw/mesa.c
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/mesa.c,v
retrieving revision 1.65
diff -u -r1.65 mesa.c
--- dlls/ddraw/mesa.c	9 Jan 2005 16:42:53 -0000	1.65
+++ dlls/ddraw/mesa.c	11 Feb 2005 21:23:05 -0000
@@ -361,7 +361,7 @@
 	        glThis->blending = dwRenderState;
 
 	        /* Hack for some old games ... */
-	        if (glThis->version == 1) {
+	        if (glThis->parent.version == 1) {
 		    lpStateBlock->render_state[D3DRENDERSTATE_COLORKEYENABLE - 1] = dwRenderState;
 		}
 	        break;
Index: dlls/ddraw/mesa_private.h
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/mesa_private.h,v
retrieving revision 1.62
diff -u -r1.62 mesa_private.h
--- dlls/ddraw/mesa_private.h	30 Jul 2004 18:54:32 -0000	1.62
+++ dlls/ddraw/mesa_private.h	11 Feb 2005 21:23:05 -0000
@@ -117,9 +117,6 @@
     /* The last type of vertex drawn */
     GL_TRANSFORM_STATE transform_state;
 
-    /* Maybe a hack, but it works */
-    DWORD version;
-    
     /* Used to handle fogging faster... */
     BYTE fog_table[3 * 0x10000]; /* 3 is for R, G and B
 				    0x10000 is 0xFF for the vertex color and
@@ -192,7 +189,7 @@
 extern HRESULT d3dmaterial_create(IDirect3DMaterialImpl **obj, IDirectDrawImpl *d3d);
 extern HRESULT d3dviewport_create(IDirect3DViewportImpl **obj, IDirectDrawImpl *d3d);
 extern HRESULT d3dvertexbuffer_create(IDirect3DVertexBufferImpl **obj, IDirectDrawImpl *d3d, LPD3DVERTEXBUFFERDESC lpD3DVertBufDesc, DWORD dwFlags);
-extern HRESULT d3ddevice_create(IDirect3DDeviceImpl **obj, IDirectDrawImpl *d3d, IDirectDrawSurfaceImpl *surface, BOOLEAN from_surface);
+extern HRESULT d3ddevice_create(IDirect3DDeviceImpl **obj, IDirectDrawImpl *d3d, IDirectDrawSurfaceImpl *surface, int version);
 
 /* Used for Direct3D to request the device to enumerate itself */
 extern HRESULT d3ddevice_enumerate(LPD3DENUMDEVICESCALLBACK cb, LPVOID context, DWORD version) ;
Index: dlls/ddraw/d3ddevice/main.c
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/d3ddevice/main.c,v
retrieving revision 1.54
diff -u -r1.54 main.c
--- dlls/ddraw/d3ddevice/main.c	9 Jan 2005 17:35:44 -0000	1.54
+++ dlls/ddraw/d3ddevice/main.c	11 Feb 2005 21:23:11 -0000
@@ -207,6 +207,9 @@
 
     *obp = NULL;
 
+    /* Note: We cannot get an interface whose version is higher than the
+     *       Direct3D object that created the device */
+
     if ( IsEqualGUID( &IID_IUnknown,  riid ) ) {
         IDirect3DDevice7_AddRef(ICOM_INTERFACE(This, IDirect3DDevice7));
 	*obp = iface;
@@ -219,19 +222,19 @@
 	TRACE("  Creating IDirect3DDevice interface %p\n", *obp);
 	return S_OK;
     }
-    if ( IsEqualGUID( &IID_IDirect3DDevice2, riid ) ) {
+    if ( IsEqualGUID( &IID_IDirect3DDevice2, riid ) && (This->version >= 2)) {
         IDirect3DDevice7_AddRef(ICOM_INTERFACE(This, IDirect3DDevice7));
         *obp = ICOM_INTERFACE(This, IDirect3DDevice2);
 	TRACE("  Creating IDirect3DDevice2 interface %p\n", *obp);
 	return S_OK;
     }
-    if ( IsEqualGUID( &IID_IDirect3DDevice3, riid ) ) {
+    if ( IsEqualGUID( &IID_IDirect3DDevice3, riid ) && (This->version >= 3)) {
         IDirect3DDevice7_AddRef(ICOM_INTERFACE(This, IDirect3DDevice7));
         *obp = ICOM_INTERFACE(This, IDirect3DDevice3);
 	TRACE("  Creating IDirect3DDevice3 interface %p\n", *obp);
 	return S_OK;
     }
-    if ( IsEqualGUID( &IID_IDirect3DDevice7, riid ) ) {
+    if ( IsEqualGUID( &IID_IDirect3DDevice7, riid ) && (This->version >= 7)) {
         IDirect3DDevice7_AddRef(ICOM_INTERFACE(This, IDirect3DDevice7));
         *obp = ICOM_INTERFACE(This, IDirect3DDevice7);
 	TRACE("  Creating IDirect3DDevice7 interface %p\n", *obp);
Index: dlls/ddraw/d3ddevice/mesa.c
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/d3ddevice/mesa.c,v
retrieving revision 1.167
diff -u -r1.167 mesa.c
--- dlls/ddraw/d3ddevice/mesa.c	10 Jan 2005 13:29:25 -0000	1.167
+++ dlls/ddraw/d3ddevice/mesa.c	11 Feb 2005 21:23:22 -0000
@@ -474,7 +474,7 @@
 
 static HRESULT enum_texture_format_OpenGL(LPD3DENUMTEXTUREFORMATSCALLBACK cb_1,
 					  LPD3DENUMPIXELFORMATSCALLBACK cb_2,
-					  LPVOID context)
+					  LPVOID context, int version)
 {
     DDSURFACEDESC sdesc;
     LPDDPIXELFORMAT pformat;
@@ -617,7 +617,8 @@
     if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
     if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
 
-    if (GL_extensions.s3tc_compressed_texture) {
+    /* DXT textures only exist for devices created from IDirect3D3 and above */
+    if ((version >= 3) && GL_extensions.s3tc_compressed_texture) {
 	TRACE("Enumerating DXT1\n");
 	pformat->dwFlags = DDPF_FOURCC;
         pformat->dwFourCC = MAKE_FOURCC('D','X','T','1');
@@ -682,7 +683,7 @@
 {
     ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
     TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DEnumTextureProc, lpArg);
-    return enum_texture_format_OpenGL(lpD3DEnumTextureProc, NULL, lpArg);
+    return enum_texture_format_OpenGL(lpD3DEnumTextureProc, NULL, lpArg, This->version);
 }
 
 HRESULT WINAPI
@@ -692,7 +693,7 @@
 {
     ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
     TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DEnumPixelProc, lpArg);
-    return enum_texture_format_OpenGL(NULL, lpD3DEnumPixelProc, lpArg);
+    return enum_texture_format_OpenGL(NULL, lpD3DEnumPixelProc, lpArg, This->version);
 }
 
 HRESULT WINAPI
@@ -2312,7 +2313,7 @@
 
     /* Apparently, whatever the state of BLEND, color keying is always activated for 'old' D3D versions */
     if (((This->state_block.render_state[D3DRENDERSTATE_COLORKEYENABLE - 1]) ||
-	 (glThis->version == 1)) &&
+	 (glThis->parent.version == 1)) &&
 	(enable_colorkey)) {
 	TRACE(" colorkey activated.\n");
 	
@@ -3877,7 +3878,7 @@
 }     
 
 HRESULT
-d3ddevice_create(IDirect3DDeviceImpl **obj, IDirectDrawImpl *d3d, IDirectDrawSurfaceImpl *surface, BOOLEAN from_surface)
+d3ddevice_create(IDirect3DDeviceImpl **obj, IDirectDrawImpl *d3d, IDirectDrawSurfaceImpl *surface, int version)
 {
     IDirect3DDeviceImpl *object;
     IDirect3DDeviceGLImpl *gl_object;
@@ -3903,6 +3904,7 @@
     object->set_matrices = d3ddevice_set_matrices;
     object->matrices_updated = d3ddevice_matrices_updated;
     object->flush_to_framebuffer = d3ddevice_flush_to_frame_buffer;
+    object->version = version;
     
     TRACE(" creating OpenGL device for surface = %p, d3d = %p\n", surface, d3d);
 
@@ -3910,13 +3912,6 @@
 
     TRACE(" device critical section : %p\n", &(object->crit));
 
-    /* This is just a hack for some badly done games :-/ */
-    if (from_surface) {
-	gl_object->version = 1;
-	TRACE(" using D3D1 special hacks.\n");
-    } else
-	gl_object->version = 7;
-
     device_context = GetDC(surface->ddraw_owner->window);
     gl_object->display = get_display(device_context);
     gl_object->drawable = get_drawable(device_context);
@@ -4067,8 +4062,7 @@
     /* And finally warn D3D that this device is now present */
     object->d3d->d3d_added_device(object->d3d, object);
 
-    /* FIXME: Should handle other versions than just 7 */
-    InitDefaultStateBlock(&object->state_block, 7);
+    InitDefaultStateBlock(&object->state_block, object->version);
     /* Apply default render state and texture stage state values */
     apply_render_state(object, &object->state_block);
     apply_texture_state(object);
Index: dlls/ddraw/direct3d/mesa.c
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/direct3d/mesa.c,v
retrieving revision 1.35
diff -u -r1.35 mesa.c
--- dlls/ddraw/direct3d/mesa.c	20 Dec 2004 17:08:41 -0000	1.35
+++ dlls/ddraw/direct3d/mesa.c	11 Feb 2005 21:23:27 -0000
@@ -62,7 +62,22 @@
 }
 
 HRESULT WINAPI
-GL_IDirect3DImpl_3_2T_EnumDevices(LPDIRECT3D3 iface,
+GL_IDirect3DImpl_2_EnumDevices(LPDIRECT3D2 iface,
+				  LPD3DENUMDEVICESCALLBACK lpEnumDevicesCallback,
+				  LPVOID lpUserArg)
+{
+    ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D2, iface);
+    TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpEnumDevicesCallback, lpUserArg);
+
+    /* Call functions defined in d3ddevices.c */
+    if (d3ddevice_enumerate(lpEnumDevicesCallback, lpUserArg, 2) != D3DENUMRET_OK)
+	return D3D_OK;
+
+    return D3D_OK;
+}
+
+HRESULT WINAPI
+GL_IDirect3DImpl_3_EnumDevices(LPDIRECT3D3 iface,
 				  LPD3DENUMDEVICESCALLBACK lpEnumDevicesCallback,
 				  LPVOID lpUserArg)
 {
@@ -146,7 +161,7 @@
     IDirect3DDeviceImpl *lpd3ddev;
     HRESULT ret_value;
 
-    ret_value = d3ddevice_create(&lpd3ddev, This, lpDDS, FALSE);
+    ret_value = d3ddevice_create(&lpd3ddev, This, lpDDS, version);
     if (FAILED(ret_value)) return ret_value;
     
     if ((iid == NULL) ||
@@ -331,7 +346,7 @@
     XCAST(QueryInterface) Thunk_IDirect3DImpl_3_QueryInterface,
     XCAST(AddRef) Thunk_IDirect3DImpl_3_AddRef,
     XCAST(Release) Thunk_IDirect3DImpl_3_Release,
-    XCAST(EnumDevices) GL_IDirect3DImpl_3_2T_EnumDevices,
+    XCAST(EnumDevices) GL_IDirect3DImpl_3_EnumDevices,
     XCAST(CreateLight) GL_IDirect3DImpl_3_2T_1T_CreateLight,
     XCAST(CreateMaterial) GL_IDirect3DImpl_3_2T_1T_CreateMaterial,
     XCAST(CreateViewport) GL_IDirect3DImpl_3_2T_1T_CreateViewport,
@@ -358,7 +373,7 @@
     XCAST(QueryInterface) Thunk_IDirect3DImpl_2_QueryInterface,
     XCAST(AddRef) Thunk_IDirect3DImpl_2_AddRef,
     XCAST(Release) Thunk_IDirect3DImpl_2_Release,
-    XCAST(EnumDevices) Thunk_IDirect3DImpl_2_EnumDevices,
+    XCAST(EnumDevices) GL_IDirect3DImpl_2_EnumDevices,
     XCAST(CreateLight) Thunk_IDirect3DImpl_2_CreateLight,
     XCAST(CreateMaterial) Thunk_IDirect3DImpl_2_CreateMaterial,
     XCAST(CreateViewport) Thunk_IDirect3DImpl_2_CreateViewport,
Index: dlls/ddraw/dsurface/main.c
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/dsurface/main.c,v
retrieving revision 1.62
diff -u -r1.62 main.c
--- dlls/ddraw/dsurface/main.c	9 Jan 2005 17:35:44 -0000	1.62
+++ dlls/ddraw/dsurface/main.c	11 Feb 2005 21:23:30 -0000
@@ -195,7 +195,7 @@
         IDirect3DDeviceImpl *d3ddevimpl;
 	HRESULT ret_value;
 
-	ret_value = d3ddevice_create(&d3ddevimpl, This->ddraw_owner, This, TRUE);
+	ret_value = d3ddevice_create(&d3ddevimpl, This->ddraw_owner, This, 1);
 	if (FAILED(ret_value)) return ret_value;
 
 	*ppObj = ICOM_INTERFACE(d3ddevimpl, IDirect3DDevice);


More information about the wine-patches mailing list