wined3d: Select onscreen contexts based on the thread id.
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index 5b2ab01..0f2529a 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -312,6 +312,7 @@
}
ret->surface = (IWineD3DSurface *) target;
ret->isPBuffer = win == 0;
+ ret->tid = GetCurrentThreadId();
TRACE("Successfully created new context %p\n", ret);
@@ -641,7 +642,7 @@
*
*****************************************************************************/
void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextUsage usage) {
- DWORD tid = This->createParms.BehaviorFlags & WINED3DCREATE_MULTITHREADED ? GetCurrentThreadId() : 0;
+ DWORD tid = GetCurrentThreadId();
int i;
DWORD dirtyState, idx;
BYTE shift;
@@ -650,7 +651,7 @@
TRACE("(%p): Selecting context for render target %p, thread %d\n", This, target, tid);
- if(This->lastActiveRenderTarget != target) {
+ if(This->lastActiveRenderTarget != target || tid != This->lastThread) {
IWineD3DSwapChain *swapchain = NULL;
HRESULT hr;
BOOL readTexture = wined3d_settings.offscreen_rendering_mode != ORM_FBO && This->render_offscreen;
@@ -658,7 +659,18 @@
hr = IWineD3DSurface_GetContainer(target, &IID_IWineD3DSwapChain, (void **) &swapchain);
if(hr == WINED3D_OK && swapchain) {
TRACE("Rendering onscreen\n");
- context = ((IWineD3DSwapChainImpl *) swapchain)->context[0];
+
+ context = NULL;
+ for(i = 0; i < ((IWineD3DSwapChainImpl *) swapchain)->num_contexts; i++) {
+ if(((IWineD3DSwapChainImpl *) swapchain)->context[i]->tid == tid) {
+ context = ((IWineD3DSwapChainImpl *) swapchain)->context[i];
+ }
+ }
+
+ if(!context) {
+ /* TODO: Create a new context for the thread */
+ FIXME("Context creation for a new thread not implemented yet\n");
+ }
This->render_offscreen = FALSE;
/* The context != This->activeContext will catch a NOP context change. This can occur
* if we are switching back to swapchain rendering in case of FBO or Back Buffer offscreen
@@ -682,10 +694,16 @@
Context_MarkStateDirty(context, STATE_VDECL);
Context_MarkStateDirty(context, STATE_VIEWPORT);
}
+
} else {
TRACE("Rendering offscreen\n");
This->render_offscreen = TRUE;
+ if(tid != This->lastThread) {
+ FIXME("Offscreen rendering is only supported from the creation thread yet\n");
+ FIXME("Expect a crash now ...\n");
+ }
+
switch(wined3d_settings.offscreen_rendering_mode) {
case ORM_FBO:
/* FBOs do not need a different context. Stay with whatever context is active at the moment */
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 4a15b33..4749113 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -1851,6 +1851,7 @@
}
IWineD3DSurface_AddRef(This->render_targets[0]);
This->activeContext = swapchain->context[0];
+ This->lastThread = GetCurrentThreadId();
/* Depth Stencil support */
This->stencilBufferTarget = This->depthStencilBuffer;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index dbfe40c..89f207e 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -736,8 +736,9 @@
/* Context management */
WineD3DContext **contexts; /* Dynamic array containing pointers to context structures */
- WineD3DContext *activeContext; /* Only 0 for now */
- UINT numContexts; /* Always 1 for now */
+ WineD3DContext *activeContext;
+ DWORD lastThread;
+ UINT numContexts;
WineD3DContext *pbufferContext; /* The context that has a pbuffer as drawable */
DWORD pbufferWidth, pbufferHeight; /* Size of the buffer drawable */
};