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(a)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
> */
>
>
> ------------------------------------------------------------------------
>
>