[3/12 WineD3D/DDraw: Forward DDSCL_MULTITHREADED to WineD3D

Stefan Dösinger stefan at codeweavers.com
Mon Feb 26 07:39:26 CST 2007


This patch seemed not to arrive on the list, I'm resending

Note: that this patch conflicts with the ddraw thread safety patch. After this 
patch here is applied, I will send an updated thread safety patch for the 
ddraw implementation
-------------- next part --------------
From 7ef8b70f2928908fd4569ac9a7a93ea828712a26 Mon Sep 17 00:00:00 2001
From: Stefan Doesinger <stefan at codeweavers.com>
Date: Sun, 25 Feb 2007 00:28:00 +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.
---
 dlls/d3d8/directx.c              |    4 ++++
 dlls/d3d9/directx.c              |    5 +++++
 dlls/ddraw/ddraw.c               |   16 +++++++++++-----
 dlls/wined3d/device.c            |   17 +++++++++++++++++
 include/wine/wined3d_interface.h |    2 ++
 5 files changed, 39 insertions(+), 5 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 500a857..119a929 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -1872,6 +1872,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;
@@ -5723,6 +5739,7 @@ const IWineD3DDeviceVtbl IWineD3DDevice_Vtbl =
     IWineD3DDeviceImpl_Init3D,
     IWineD3DDeviceImpl_Uninit3D,
     IWineD3DDeviceImpl_SetFullscreen,
+    IWineD3DDeviceImpl_SetMultithreaded,
     IWineD3DDeviceImpl_EvictManagedResources,
     IWineD3DDeviceImpl_GetAvailableTextureMem,
     IWineD3DDeviceImpl_GetBackBuffer,
diff --git a/include/wine/wined3d_interface.h b/include/wine/wined3d_interface.h
index 3783ebc..2d206a7 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)
-- 
1.4.4.3



More information about the wine-patches mailing list