[1/5] WineD3D/DDraw: Forward DDSCL_MULTITHREADED to WineD3D

Stefan Dösinger stefan at codeweavers.com
Sun Mar 18 13:13:33 CDT 2007


Resend of the infrastructure patches for opengl context selection

2 and 3 do not depend on this patch, but 4 and 5 do.
-------------- next part --------------
From 94e1ba3c11937404ab22f6a07676590e5b3d6200 Mon Sep 17 00:00:00 2001
From: Stefan Doesinger <stefan at codeweavers.com>
Date: Sun, 4 Mar 2007 17:03:03 +0100
Subject: [PATCH] WineD3D/DDraw: Forward DDSCL_MULTITHREADED to WineD3D

In DDraw thread safety is requested after ddraw creation using
SetCooperativeLevel. WineD3D needs an interface for ddraw to call to do
the same. SetMultithreaded will initialize the critical sections, etc,
thus it is called by d3d8 and d3d9 too. For now it only stores the
behavior flag.

The WINED3DCREATE_MULTITHREADED flag is moved from the public headers
into the private headers to signal that IWineD3D::CreateDevice ignores
this flag.
---
 dlls/d3d8/directx.c                  |    4 ++++
 dlls/d3d9/directx.c                  |    5 +++++
 dlls/ddraw/ddraw.c                   |   16 +++++++++++-----
 dlls/wined3d/device.c                |   17 +++++++++++++++++
 dlls/wined3d/wined3d_private_types.h |    5 ++++-
 include/wine/wined3d_interface.h     |    2 ++
 include/wine/wined3d_types.h         |    1 -
 7 files changed, 43 insertions(+), 7 deletions(-)

diff --git a/dlls/d3d8/directx.c b/dlls/d3d8/directx.c
index 1349f57..e05d647 100644
--- a/dlls/d3d8/directx.c
+++ b/dlls/d3d8/directx.c
@@ -377,6 +377,10 @@ static HRESULT WINAPI IDirect3D8Impl_CreateDevice(LPDIRECT3D8 iface, UINT Adapte
     localParameters.FullScreen_RefreshRateInHz                  = pPresentationParameters->FullScreen_RefreshRateInHz;
     localParameters.PresentationInterval                        = pPresentationParameters->FullScreen_PresentationInterval;
 
+    if(BehaviourFlags & D3DCREATE_MULTITHREADED) {
+        IWineD3DDevice_SetMultithreaded(object->WineD3DDevice);
+    }
+
     hr = IWineD3DDevice_Init3D(object->WineD3DDevice, &localParameters, D3D8CB_CreateAdditionalSwapChain);
 
     pPresentationParameters->BackBufferWidth                    = localParameters.BackBufferWidth;
diff --git a/dlls/d3d9/directx.c b/dlls/d3d9/directx.c
index 1c34637..f15aa4d 100644
--- a/dlls/d3d9/directx.c
+++ b/dlls/d3d9/directx.c
@@ -367,6 +367,10 @@ static HRESULT WINAPI IDirect3D9Impl_CreateDevice(LPDIRECT3D9 iface, UINT Adapte
     localParameters.FullScreen_RefreshRateInHz          = pPresentationParameters->FullScreen_RefreshRateInHz;
     localParameters.PresentationInterval                = pPresentationParameters->PresentationInterval;
 
+    if(BehaviourFlags & D3DCREATE_MULTITHREADED) {
+        IWineD3DDevice_SetMultithreaded(object->WineD3DDevice);
+    }
+
     hr = IWineD3DDevice_Init3D(object->WineD3DDevice, &localParameters, D3D9CB_CreateAdditionalSwapChain);
 
     pPresentationParameters->BackBufferWidth            = localParameters.BackBufferWidth;
@@ -389,6 +393,7 @@ static HRESULT WINAPI IDirect3D9Impl_CreateDevice(LPDIRECT3D9 iface, UINT Adapte
         HeapFree(GetProcessHeap(), 0, object);
         *ppReturnedDeviceInterface = NULL;
     }
+
     return hr;
 }
 
diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
index 3270e41..ac95ddf 100644
--- a/dlls/ddraw/ddraw.c
+++ b/dlls/ddraw/ddraw.c
@@ -323,7 +323,8 @@ IDirectDrawImpl_Release(IDirectDraw7 *iface)
  * DDSCL_SETFOCUSWINDOW may only be used with DDSCL_NOWINDOWCHANGES
  *
  * Handled flags: DDSCL_NORMAL, DDSCL_FULLSCREEN, DDSCL_EXCLUSIVE,
- *                DDSCL_SETFOCUSWINDOW (partially)
+ *                DDSCL_SETFOCUSWINDOW (partially),
+ *                DDSCL_MULTITHREADED (work in progress)
  *
  * Unhandled flags, which should be implemented
  *  DDSCL_SETDEVICEWINDOW: Sets a window specially used for rendering (I don't
@@ -334,8 +335,7 @@ IDirectDrawImpl_Release(IDirectDraw7 *iface)
  * Unsure about these: DDSCL_FPUSETUP DDSCL_FPURESERVE
  *
  * These seem not really imporant for wine
- *  DDSCL_ALLOWREBOOT, DDSCL_NOWINDOWCHANGES, DDSCL_ALLOWMODEX,
- *  DDSCL_MULTITHREDED
+ *  DDSCL_ALLOWREBOOT, DDSCL_NOWINDOWCHANGES, DDSCL_ALLOWMODEX
  *
  * Returns:
  *  DD_OK if the cooperative level was set successfully
@@ -501,13 +501,19 @@ IDirectDrawImpl_SetCooperativeLevel(IDirectDraw7 *iface,
         }
     }
 
+    if(cooplevel & DDSCL_MULTITHREADED && !(This->cooperative_level & DDSCL_MULTITHREADED))
+    {
+        FIXME("DirectDraw is not thread safe yet\n");
+
+        /* Enable thread safety in wined3d */
+        IWineD3DDevice_SetMultithreaded(This->wineD3DDevice);
+    }
+
     /* Unhandled flags */
     if(cooplevel & DDSCL_ALLOWREBOOT)
         WARN("(%p) Unhandled flag DDSCL_ALLOWREBOOT, harmless\n", This);
     if(cooplevel & DDSCL_ALLOWMODEX)
         WARN("(%p) Unhandled flag DDSCL_ALLOWMODEX, harmless\n", This);
-    if(cooplevel & DDSCL_MULTITHREADED)
-        FIXME("(%p) Unhandled flag DDSCL_MULTITHREADED, Uh Oh...\n", This);
     if(cooplevel & DDSCL_FPUSETUP)
         WARN("(%p) Unhandled flag DDSCL_FPUSETUP, harmless\n", This);
     if(cooplevel & DDSCL_FPUPRESERVE)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 0d4cdd0..4c6a1db 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -1830,6 +1830,22 @@ static void WINAPI IWineD3DDeviceImpl_SetFullscreen(IWineD3DDevice *iface, BOOL
     This->ddraw_fullscreen = fullscreen;
 }
 
+/* Enables thead safety in the wined3d device and its resources. Called by DirectDraw
+ * from SetCooperativeLeven if DDSCL_MULTITHREADED is specified, and by d3d8/9 from
+ * CreateDevice if D3DCREATE_MULTITHREADED is passed.
+ *
+ * There is no way to deactivate thread safety once it is enabled
+ */
+static void WINAPI IWineD3DDeviceImpl_SetMultithreaded(IWineD3DDevice *iface) {
+    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
+    FIXME("No thread safety in wined3d yet\n");
+
+    /*For now just store the flag(needed in case of ddraw) */
+    This->createParms.BehaviorFlags |= WINED3DCREATE_MULTITHREADED;
+
+    return;
+}
+
 static HRESULT WINAPI IWineD3DDeviceImpl_SetDisplayMode(IWineD3DDevice *iface, UINT iSwapChain, WINED3DDISPLAYMODE* pMode) {
     DEVMODEW devmode;
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
@@ -5779,6 +5795,7 @@ const IWineD3DDeviceVtbl IWineD3DDevice_Vtbl =
     IWineD3DDeviceImpl_Init3D,
     IWineD3DDeviceImpl_Uninit3D,
     IWineD3DDeviceImpl_SetFullscreen,
+    IWineD3DDeviceImpl_SetMultithreaded,
     IWineD3DDeviceImpl_EvictManagedResources,
     IWineD3DDeviceImpl_GetAvailableTextureMem,
     IWineD3DDeviceImpl_GetBackBuffer,
diff --git a/dlls/wined3d/wined3d_private_types.h b/dlls/wined3d/wined3d_private_types.h
index 5531a80..01f5d26 100644
--- a/dlls/wined3d/wined3d_private_types.h
+++ b/dlls/wined3d/wined3d_private_types.h
@@ -299,5 +299,8 @@ typedef enum _WINED3DSHADER_INSTRUCTION_OPCODE_TYPE {
 #define WINED3DSHADER_VERSION_MINOR(version) (((version) >> 0) & 0xFF)
 #define WINED3DPS_END() 0x0000FFFF
 #define WINED3DVS_END() 0x0000FFFF
-  
+
+/* Multithreaded flag. Removed from the public header to signal that IWineD3D::CreateDevice ignores it */
+#define WINED3DCREATE_MULTITHREADED                 0x00000004
+
 #endif
diff --git a/include/wine/wined3d_interface.h b/include/wine/wined3d_interface.h
index aaee89e..7842076 100644
--- a/include/wine/wined3d_interface.h
+++ b/include/wine/wined3d_interface.h
@@ -356,6 +356,7 @@ DECLARE_INTERFACE_(IWineD3DDevice,IWineD3DBase)
     STDMETHOD(Init3D)(THIS_ WINED3DPRESENT_PARAMETERS* pPresentationParameters, D3DCB_CREATEADDITIONALSWAPCHAIN D3DCB_CreateAdditionalSwapChain);
     STDMETHOD(Uninit3D)(THIS, D3DCB_DESTROYSURFACEFN pFn, D3DCB_DESTROYSWAPCHAINFN pFn2);
     STDMETHOD_(void, SetFullscreen)(THIS_ BOOL fullscreen);
+    STDMETHOD_(void, SetMultithreaded)(THIS);
     STDMETHOD(EvictManagedResources)(THIS) PURE;
     STDMETHOD_(UINT, GetAvailableTextureMem)(THIS) PURE;
     STDMETHOD(GetBackBuffer)(THIS_ UINT iSwapChain, UINT BackBuffer, WINED3DBACKBUFFER_TYPE, struct IWineD3DSurface** ppBackBuffer) PURE;
@@ -492,6 +493,7 @@ DECLARE_INTERFACE_(IWineD3DDevice,IWineD3DBase)
 #define IWineD3DDevice_Init3D(p, a, b)                          (p)->lpVtbl->Init3D(p, a, b)
 #define IWineD3DDevice_Uninit3D(p, a, b)                        (p)->lpVtbl->Uninit3D(p, a, b)
 #define IWineD3DDevice_SetFullscreen(p, a)                      (p)->lpVtbl->SetFullscreen(p, a)
+#define IWineD3DDevice_SetMultithreaded(p)                      (p)->lpVtbl->SetMultithreaded(p)
 #define IWineD3DDevice_EvictManagedResources(p)                 (p)->lpVtbl->EvictManagedResources(p)
 #define IWineD3DDevice_GetAvailableTextureMem(p)                (p)->lpVtbl->GetAvailableTextureMem(p)
 #define IWineD3DDevice_GetBackBuffer(p,a,b,c,d)                 (p)->lpVtbl->GetBackBuffer(p,a,b,c,d)
diff --git a/include/wine/wined3d_types.h b/include/wine/wined3d_types.h
index 6f0a28d..bd63f71 100644
--- a/include/wine/wined3d_types.h
+++ b/include/wine/wined3d_types.h
@@ -1569,7 +1569,6 @@ typedef enum _WINED3DSURFTYPE {
 
 /* IWineD3D::CreateDevice behaviour flags */
 #define WINED3DCREATE_FPU_PRESERVE                  0x00000002
-#define WINED3DCREATE_MULTITHREADED                 0x00000004
 #define WINED3DCREATE_PUREDEVICE                    0x00000010
 #define WINED3DCREATE_SOFTWARE_VERTEXPROCESSING     0x00000020
 #define WINED3DCREATE_HARDWARE_VERTEXPROCESSING     0x00000040
-- 
1.4.4.3



More information about the wine-patches mailing list