Stefan Dösinger napsal(a):
This patch finishes the opengl side of multithreaded direct3d, which was started with the state management rewrite(well, almost, no offscreen rendering yet) It does not make Direct3D thread safe, because there is no protection against race conditions.

This patch improves multithreaded games a bit. They do not crash any more in a gl call, but running them is kinda like a lottery, especially on smp systems.

Vitaly and Andras have reported success with Prince of Persia 3D: Sands of Time and some other games, and on my laptop Empire Earth is running. Empire Earth deadlocks regularly on my dual core system at ddraw creation.

I can even run Tom Clancy's Rainbow Six Vegas, but there are still problems with offscreen rendering.

Mirek



------------------------------------------------------------------------

From 49cc9a0aa6e06f559540758d5b0ed2252208a0ad Mon Sep 17 00:00:00 2001
From: Stefan Doesinger <[EMAIL PROTECTED]>
Date: Sun, 25 Feb 2007 00:18:25 +0100
Subject: [PATCH] WineD3D: Create multithreading contexts for swapchains

This patch adds a routine to clone the main context of a swapchain to use it 
with a different thread on the
same drawable. This will enable multithreaded direct3d rendering, or better 
enable an attempt to do that.
From the opengl point of view it will work, but because concurrency control is 
not implemented yet(appart
of ENTER_GL() / LEAVE_GL() ) games may crash randomly, show strange behavior, 
...

The other problem is that this code was only tested with the open source radeon 
driver yet. While what
wined3d is doing here should be allowed by the spec, some drivers may have some 
bugs when using multiple
contexts on one drawable.
---
 dlls/wined3d/context.c         |    4 ++--
 dlls/wined3d/swapchain.c       |   30 ++++++++++++++++++++++++++++++
 dlls/wined3d/wined3d_private.h |    2 ++
 3 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index 3a815b3..8545568 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -626,8 +626,8 @@ void ActivateContext(IWineD3DDeviceImpl *This, 
IWineD3DSurface *target, ContextU
                 }
if(!context) {
-                    /* TODO: Create a new context for the thread */
-                    FIXME("Context creation for a new thread not implemented 
yet\n");
+                    /* Create a new context for the thread */
+                    context = 
IWineD3DSwapChainImpl_CreateContextForThread(swapchain);
                 }
             } else {
                 context = ((IWineD3DSwapChainImpl *) swapchain)->context[0];
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
index 2977a05..3b8e3e8 100644
--- a/dlls/wined3d/swapchain.c
+++ b/dlls/wined3d/swapchain.c
@@ -510,3 +510,33 @@ const IWineD3DSwapChainVtbl IWineD3DSwapChain_Vtbl =
     IWineD3DSwapChainImpl_SetGammaRamp,
     IWineD3DSwapChainImpl_GetGammaRamp
 };
+
+WineD3DContext *IWineD3DSwapChainImpl_CreateContextForThread(IWineD3DSwapChain 
*iface) {
+    WineD3DContext *ctx;
+    IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *) iface;
+    WineD3DContext **newArray;
+
+    TRACE("Creating a new context for swapchain %p, thread %d\n", This, 
GetCurrentThreadId());
+
+    ctx = CreateContext(This->wineD3DDevice, (IWineD3DSurfaceImpl *) 
This->frontBuffer,
+                        This->context[0]->display, This->win);
+    if(!ctx) {
+        ERR("Failed to create a new context for the swapchain\n");
+        return NULL;
+    }
+
+    newArray = HeapAlloc(GetProcessHeap(), 0, sizeof(*newArray) * 
This->num_contexts + 1);
+    if(!newArray) {
+        ERR("Out of memory when trying to allocate a new context array\n");
+        DestroyContext(This->wineD3DDevice, ctx);
+        return NULL;
+    }
+    memcpy(newArray, This->context, sizeof(*newArray) * This->num_contexts);
+    HeapFree(GetProcessHeap(), 0, This->context);
+    newArray[This->num_contexts] = ctx;
+    This->context = newArray;
+    This->num_contexts++;
+
+    TRACE("Returning context %p\n", ctx);
+    return ctx;
+}
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 45e69bf..fa4232c 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1341,6 +1341,8 @@ typedef struct IWineD3DSwapChainImpl
extern const IWineD3DSwapChainVtbl IWineD3DSwapChain_Vtbl; +WineD3DContext *IWineD3DSwapChainImpl_CreateContextForThread(IWineD3DSwapChain *iface);
+
 /*****************************************************************************
* Utility function prototypes */


------------------------------------------------------------------------




Reply via email to