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 stefan@codeweavers.com 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
*/
Hi,
I can even run Tom Clancy's Rainbow Six Vegas, but there are still problems with offscreen rendering.
Yeah, offscreen rendering is unsupported with my multithreading patches. I have another patch to fix that, but I haven't tested it.
I have a bit of a mess in my wine tree at the moment(2 sets of patches), I will clean that up, send a few non-multithreaded patches to wine-patches and the newest multithreading thing to wine-devel for testing.