Index: /trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxDispD3D.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxDispD3D.cpp	(revision 32544)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxDispD3D.cpp	(revision 32545)
@@ -1917,4 +1917,5 @@
     IDirect3DDevice9 *pDevice9If = NULL;
     HWND hOldWnd = pSwapchain->hWnd;
+//#define VBOXDISP_NEWWND_ON_SWAPCHAINUPDATE
 #ifndef VBOXDISP_NEWWND_ON_SWAPCHAINUPDATE
     if (!hOldWnd)
@@ -4759,5 +4760,15 @@
                             Assert(hr == S_OK);
                             if (hr == S_OK)
+                            {
+                                if(pResource->Flags.Primary)
+                                {
+                                    for (UINT i = 0; i < pResource->SurfCount; ++i)
+                                    {
+                                        vboxWddmSwapchainFindCreate(pDevice, &pRc->aAllocations[i]);
+                                    }
+                                    Assert(bIssueCreateResource);
+                                }
                                 continue;
+                            }
 
                             /* fail branch */
@@ -5632,5 +5643,7 @@
         {
 #ifndef VBOXWDDM_WITH_VISIBLE_FB
-            if (pSrcSwapchain && vboxWddmSwapchainGetFb(pSrcSwapchain)->pAlloc != pSrcAlloc
+            if (pSrcSwapchain
+                    && pSrcSwapchain->pRenderTargetFbCopy
+                    && vboxWddmSwapchainGetFb(pSrcSwapchain)->pAlloc != pSrcAlloc
                     && vboxWddmSwapchainNumRTs(pSrcSwapchain) > 1) /* work-around wine backbuffer */
             {
@@ -5671,5 +5684,5 @@
                     pSrcSurfIf = pSrcSwapchain->pRenderTargetFbCopy;
                     Assert(pSrcSurfIf);
-                    hr = pDevice9If->GetFrontBufferData(0, pSrcSurfIf);
+                    hr = pSrcSwapchain->pSwapChainIf->GetFrontBufferData(pSrcSurfIf);
                     Assert(hr == S_OK);
                     if (hr == S_OK)
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Wine/include/wine/wined3d.h
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Wine/include/wine/wined3d.h	(revision 32544)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Wine/include/wine/wined3d.h	(revision 32545)
@@ -7308,4 +7308,7 @@
     virtual HRESULT STDMETHODCALLTYPE AddSwapChain(
         IWineD3DSwapChain *swapchain) = 0;
+
+    virtual HRESULT STDMETHODCALLTYPE RemoveSwapChain(
+        IWineD3DSwapChain *swapchain) = 0;
 #endif
 };
@@ -8074,4 +8077,8 @@
 
     HRESULT (STDMETHODCALLTYPE *AddSwapChain)(
+        IWineD3DDevice* This,
+        IWineD3DSwapChain *swapchain);
+
+    HRESULT (STDMETHODCALLTYPE *RemoveSwapChain)(
         IWineD3DDevice* This,
         IWineD3DSwapChain *swapchain);
@@ -8236,4 +8243,5 @@
 #define IWineD3DDevice_Flush(This) (This)->lpVtbl->Flush(This)
 #define IWineD3DDevice_AddSwapChain(This,swapchain) (This)->lpVtbl->AddSwapChain(This,swapchain)
+#define IWineD3DDevice_RemoveSwapChain(This,swapchain) (This)->lpVtbl->RemoveSwapChain(This,swapchain)
 #endif
 #endif
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/arb_program_shader.c
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/arb_program_shader.c	(revision 32544)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/arb_program_shader.c	(revision 32545)
@@ -6969,5 +6969,10 @@
     if (wined3d_settings.strict_draw_ordering || (dst_swapchain
             && ((IWineD3DSurface *)dst_surface == dst_swapchain->frontBuffer
-            || dst_swapchain->num_contexts > 1)))
+#ifdef VBOXWDDM
+            || dst_swapchain->device->numContexts > 1
+#else
+            || dst_swapchain->num_contexts > 1
+#endif
+            )))
         wglFlush(); /* Flush to ensure ordering across contexts. */
 
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/context.c
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/context.c	(revision 32544)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/context.c	(revision 32545)
@@ -757,4 +757,7 @@
 {
 #ifdef VBOXWDDM
+# ifdef DEBUG_misha
+    Assert(0);
+# endif
     TRACE("Updating context %p window from %p to %p.\n",
             context, context->win_handle, swapchain->win_handle);
@@ -776,9 +779,8 @@
 #ifdef VBOXWDDM
     context->win_handle = swapchain->win_handle;
-    context->hdc = GetDC(context->win_handle);
     context->currentSwapchain = swapchain;
 #else
     context->win_handle = context->swapchain->win_handle;
-
+#endif
     if (!(context->hdc = GetDC(context->win_handle)))
     {
@@ -786,5 +788,4 @@
         goto err;
     }
-#endif
 
     if (!context_set_pixel_format(context->gl_info, context->hdc, context->pixel_format))
@@ -1595,38 +1596,21 @@
         const struct wined3d_format_desc *ds_format_desc)
 {
-    int i, j;
-    int swapchains = IWineD3DDevice_GetNumberOfSwapChains(device);
+    int i;
     DWORD tid = GetCurrentThreadId();
     struct wined3d_context *context = NULL;
 
-//    Assert(0);
-
-    for(i = 0 ; i < swapchains ; i ++)
-    {
-        IWineD3DSwapChainImpl *curSwapChain;
-        IWineD3DDevice_GetSwapChain(device, i, &curSwapChain);
-        if (curSwapChain->ds_format == ds_format_desc)
-        {
-            for(j = 0; j < curSwapChain->num_contexts; j++) {
-                if(curSwapChain->context[j]->tid == tid) {
-                    context = curSwapChain->context[j];
-                    break;
-                }
-            }
-        }
-        else
-        {
-            Assert(0);
-        }
-
-        IWineD3DSwapChain_Release(curSwapChain);
-
-        if (context)
+    Assert(0);
+
+    for(i = 0 ; i < device->numContexts ; i ++)
+    {
+        if(device->contexts[i]->tid == tid) {
+            context = device->contexts[i];
             break;
+        }
     }
 
     if (!context)
     {
-        Assert(!swapchains);
+        Assert(!device->NumberOfSwapChains);
         context = context_create(swapchain, target, ds_format_desc);
     }
@@ -1915,5 +1899,12 @@
 {
     unsigned int i;
-
+#ifdef VBOXWDDM
+    IWineD3DDeviceImpl *device = ((IWineD3DSwapChainImpl*)swapchain)->device;
+    for (i = 0; i < device->numContexts; ++i)
+    {
+        if (device->contexts[i]->tid == tid)
+            return device->contexts[i];
+    }
+#else
     for(i = 0; i < ((IWineD3DSwapChainImpl *) swapchain)->num_contexts; i++) {
         if(((IWineD3DSwapChainImpl *) swapchain)->context[i]->tid == tid) {
@@ -1921,7 +1912,4 @@
         }
     }
-
-#ifdef VBOXWDDM
-    Assert(0);
 #endif
 
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/device.c
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/device.c	(revision 32544)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/device.c	(revision 32545)
@@ -6296,5 +6296,9 @@
 }
 
-static void delete_opengl_contexts(IWineD3DDevice *iface, IWineD3DSwapChainImpl *swapchain)
+static void delete_opengl_contexts(IWineD3DDevice *iface
+#ifndef VBOXWDDM
+        , IWineD3DSwapChainImpl *swapchain
+#endif
+        )
 {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
@@ -6335,7 +6339,9 @@
         context_destroy(This, This->contexts[0]);
     }
+#ifndef VBOXWDDM
     HeapFree(GetProcessHeap(), 0, swapchain->context);
     swapchain->context = NULL;
     swapchain->num_contexts = 0;
+#endif
 }
 
@@ -6347,4 +6353,5 @@
     IWineD3DSurfaceImpl *target;
 
+#ifndef VBOXWDDM
     /* Recreate the primary swapchain's context */
     swapchain->context = HeapAlloc(GetProcessHeap(), 0, sizeof(*swapchain->context));
@@ -6354,4 +6361,5 @@
         return E_OUTOFMEMORY;
     }
+#endif
 
     target = (IWineD3DSurfaceImpl *)(swapchain->backBuffer ? swapchain->backBuffer[0] : swapchain->frontBuffer);
@@ -6359,10 +6367,14 @@
     {
         WARN("Failed to create context.\n");
+#ifndef VBOXWDDM
         HeapFree(GetProcessHeap(), 0, swapchain->context);
+#endif
         return E_FAIL;
     }
 
+#ifndef VBOXWDDM
     swapchain->context[0] = context;
     swapchain->num_contexts = 1;
+#endif
     create_dummy_textures(This);
     context_release(context);
@@ -6399,6 +6411,8 @@
     context_release(context);
     context_destroy(This, context);
+#ifndef VBOXWDDM
     HeapFree(GetProcessHeap(), 0, swapchain->context);
     swapchain->num_contexts = 0;
+#endif
     return hr;
 }
@@ -6411,4 +6425,9 @@
     WINED3DDISPLAYMODE mode;
     TRACE("(%p)\n", This);
+
+#ifdef VBOXWDDM
+    /* todo: implement multi-swapchain handlling!!! */
+    Assert(0);
+#endif
 
     hr = IWineD3DDevice_GetSwapChain(iface, 0, (IWineD3DSwapChain **) &swapchain);
@@ -6499,5 +6518,9 @@
     IWineD3DStateBlock_Release((IWineD3DStateBlock *)This->stateBlock);
 
-    delete_opengl_contexts(iface, swapchain);
+    delete_opengl_contexts(iface
+#ifndef VBOXWDDM
+            , swapchain
+#endif
+            );
 
     if(pPresentationParameters->Windowed) {
@@ -6865,8 +6888,52 @@
         return E_OUTOFMEMORY;
     }
-    IUnknown_AddRef(swapchain);
     This->swapchains = (IWineD3DSwapChain *)pvNewBuf;
     This->swapchains[This->NumberOfSwapChains] = swapchain;
     ++This->NumberOfSwapChains;
+    return WINED3D_OK;
+}
+
+static HRESULT WINAPI IWineD3DDeviceImpl_RemoveSwapChain(IWineD3DDevice *iface, IWineD3DSwapChain *swapchain)
+{
+    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
+    int i;
+    for (i = 0; i < This->NumberOfSwapChains; ++i)
+    {
+        if (This->swapchains[i] == swapchain)
+        {
+            break;
+        }
+    }
+
+    if (i == This->NumberOfSwapChains)
+    {
+        WARN("swapchain 0x%p is not part of device 0x%p\n", swapchain, iface);
+        return E_INVALIDARG;
+    }
+
+    --This->NumberOfSwapChains;
+    if (This->NumberOfSwapChains)
+    {
+        IWineD3DSwapChain **pvNewBuf = (IWineD3DSwapChain **)HeapAlloc(GetProcessHeap(), 0, (This->NumberOfSwapChains) * sizeof(IWineD3DSwapChain *));
+        if(!pvNewBuf) {
+            ERR("Out of memory!\n");
+            return E_OUTOFMEMORY;
+        }
+        if (i) {
+            memcpy (pvNewBuf, This->swapchains, i*sizeof(IWineD3DSwapChain *));
+        }
+        if (i < This->NumberOfSwapChains) {
+            memcpy (pvNewBuf + i, This->swapchains +i+1, (This->NumberOfSwapChains - i)*sizeof(IWineD3DSwapChain *));
+        }
+
+        This->swapchains = (IWineD3DSwapChain *)pvNewBuf;
+    }
+    else
+    {
+        while (This->numContexts)
+        {
+            context_destroy(This, This->contexts[0]);
+        }
+    }
     return WINED3D_OK;
 }
@@ -7029,4 +7096,5 @@
     IWineD3DDeviceImpl_Flush,
     IWineD3DDeviceImpl_AddSwapChain,
+    IWineD3DDeviceImpl_RemoveSwapChain,
 #endif
 };
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/surface.c
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/surface.c	(revision 32544)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/surface.c	(revision 32545)
@@ -488,5 +488,5 @@
         Assert(shared_handle);
         VBOXSHRC_SET_INITIALIZED(surface);
-        IWineD3DSurface_LoadLocation(surface, SFLAG_INTEXTURE, NULL);
+        IWineD3DSurface_LoadLocation((IWineD3DSurface*)surface, SFLAG_INTEXTURE, NULL);
         if (!VBOXSHRC_IS_SHARED_OPENED(surface))
         {
@@ -3792,5 +3792,10 @@
         if (wined3d_settings.strict_draw_ordering || (dstSwapchain
                 && ((IWineD3DSurface *)This == dstSwapchain->frontBuffer
-                || dstSwapchain->num_contexts > 1)))
+#ifdef VBOXWDDM
+                || dstSwapchain->device->numContexts > 1
+#else
+                || dstSwapchain->num_contexts > 1
+#endif
+                )))
             wglFlush(); /* Flush to ensure ordering across contexts. */
 
@@ -4402,5 +4407,10 @@
     if (wined3d_settings.strict_draw_ordering || (swapchain
             && ((IWineD3DSurface *)This == swapchain->frontBuffer
-            || swapchain->num_contexts > 1)))
+#ifdef VBOXWDDM
+            || swapchain->device->numContexts > 1
+#else
+            || swapchain->num_contexts > 1
+#endif
+            )))
         wglFlush(); /* Flush to ensure ordering across contexts. */
 
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/surface_gdi.c
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/surface_gdi.c	(revision 32544)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/surface_gdi.c	(revision 32545)
@@ -440,5 +440,5 @@
             IWineD3DSurfaceImpl *dds_primary;
             IWineD3DSwapChainImpl *swapchain;
-            swapchain = (IWineD3DSwapChainImpl *)This->resource.device->swapchains[0];
+            swapchain = (IWineD3DSwapChainImpl *)This->resource.device->swapchains[This->resource.device->NumberOfSwapChains-1];
             dds_primary = (IWineD3DSurfaceImpl *)swapchain->frontBuffer;
             if (dds_primary && dds_primary->palette)
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/swapchain.c
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/swapchain.c	(revision 32544)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/swapchain.c	(revision 32545)
@@ -83,23 +83,34 @@
         This->backBuffer = NULL;
     }
-
+#ifndef VBOXWDDM
     for (i = 0; i < This->num_contexts; ++i)
     {
         context_destroy(This->device, This->context[i]);
     }
-    /* Restore the screen resolution if we rendered in fullscreen
-     * This will restore the screen resolution to what it was before creating the swapchain. In case of d3d8 and d3d9
-     * this will be the original desktop resolution. In case of d3d7 this will be a NOP because ddraw sets the resolution
-     * before starting up Direct3D, thus orig_width and orig_height will be equal to the modes in the presentation params
-     */
-    if(This->presentParms.Windowed == FALSE && This->presentParms.AutoRestoreDisplayMode) {
-        mode.Width = This->orig_width;
-        mode.Height = This->orig_height;
-        mode.RefreshRate = 0;
-        mode.Format = This->orig_fmt;
-        IWineD3DDevice_SetDisplayMode((IWineD3DDevice *)This->device, 0, &mode);
-    }
-
+#else
+    IWineD3DDevice_RemoveSwapChain(This->device, This);
+    if (!This->device->NumberOfSwapChains)
+#endif
+    {
+        /* Restore the screen resolution if we rendered in fullscreen
+         * This will restore the screen resolution to what it was before creating the swapchain. In case of d3d8 and d3d9
+         * this will be the original desktop resolution. In case of d3d7 this will be a NOP because ddraw sets the resolution
+         * before starting up Direct3D, thus orig_width and orig_height will be equal to the modes in the presentation params
+         */
+        if(This->presentParms.Windowed == FALSE && This->presentParms.AutoRestoreDisplayMode) {
+            mode.Width = This->orig_width;
+            mode.Height = This->orig_height;
+            mode.RefreshRate = 0;
+            mode.Format = This->orig_fmt;
+            IWineD3DDevice_SetDisplayMode((IWineD3DDevice *)This->device, 0, &mode);
+        }
+    }
+#ifdef VBOXWDDM
+    if(This->device_window) {
+        ReleaseDC(This->device_window, This->hDC);
+    }
+#else
     HeapFree(GetProcessHeap(), 0, This->context);
+#endif
     HeapFree(GetProcessHeap(), 0, This);
 }
@@ -353,5 +364,9 @@
     }
 
+#ifdef VBOXWDDM
+    if (This->device->numContexts > 1) wglFinish();
+#else
     if (This->num_contexts > 1) wglFinish();
+#endif
     SwapBuffers(context->hdc); /* TODO: cycle through the swapchain buffers */
 
@@ -720,4 +735,15 @@
     swapchain->win_handle = window;
     swapchain->device_window = window;
+#ifdef VBOXWDDM
+    Assert(window);
+    swapchain->hDC = GetDC(window);
+    if (!swapchain->hDC)
+    {
+        DWORD winEr = GetLastError();
+        WARN("Failed to get a window DC, winEr %d.\n", winEr);
+        Assert(0);
+        goto err;
+    }
+#endif
 
     if (!present_parameters->Windowed && window)
@@ -812,4 +838,5 @@
     }
 
+#ifndef VBOXWDDM
     swapchain->context = HeapAlloc(GetProcessHeap(), 0, sizeof(swapchain->context));
     if (!swapchain->context)
@@ -820,7 +847,9 @@
     }
     swapchain->num_contexts = 1;
+#endif
 
     if (surface_type == SURFACE_OPENGL)
     {
+        struct wined3d_context * swapchainContext;
         const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
 
@@ -844,11 +873,12 @@
 
 #ifdef VBOXWDDM
-        swapchain->context[0] = context_find_create(device, swapchain, (IWineD3DSurfaceImpl *)swapchain->frontBuffer,
+        swapchainContext = context_find_create(device, swapchain, (IWineD3DSurfaceImpl *)swapchain->frontBuffer,
                 swapchain->ds_format);
+        if (!swapchainContext)
 #else
         swapchain->context[0] = context_create(swapchain, (IWineD3DSurfaceImpl *)swapchain->frontBuffer,
                 swapchain->ds_format);
-#endif
         if (!swapchain->context[0])
+#endif
         {
             WARN("Failed to create context.\n");
@@ -856,9 +886,15 @@
             goto err;
         }
+#ifdef VBOXWDDM
+        context_release(swapchainContext);
+#else
         context_release(swapchain->context[0]);
+#endif
     }
     else
     {
+#ifndef VBOXWDDM
         swapchain->context[0] = NULL;
+#endif
     }
 
@@ -943,4 +979,13 @@
     }
 
+#ifdef VBOXWDDM
+    if (!device->NumberOfSwapChains)
+    {
+        while (device->numContexts)
+        {
+            context_destroy(device, device->contexts[0]);
+        }
+    }
+#else
     if (swapchain->context)
     {
@@ -953,4 +998,5 @@
         HeapFree(GetProcessHeap(), 0, swapchain->context);
     }
+#endif
 
     if (swapchain->frontBuffer) IWineD3DSurface_Release(swapchain->frontBuffer);
@@ -973,5 +1019,7 @@
     }
     context_release(ctx);
-
+#ifdef VBOXWDDM
+    /* no need to do anything since context gets added to the device context list within the context_create call */
+#else
     newArray = HeapAlloc(GetProcessHeap(), 0, sizeof(*newArray) * This->num_contexts + 1);
     if(!newArray) {
@@ -985,5 +1033,5 @@
     This->context = newArray;
     This->num_contexts++;
-
+#endif
     TRACE("Returning context %p\n", ctx);
     return ctx;
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/swapchain_gdi.c
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/swapchain_gdi.c	(revision 32544)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/swapchain_gdi.c	(revision 32545)
@@ -80,5 +80,7 @@
     }
 
+#ifndef VBOXWDDM
     HeapFree(GetProcessHeap(), 0, This->context);
+#endif
     HeapFree(GetProcessHeap(), 0, This);
 }
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/wined3d_private.h
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/wined3d_private.h	(revision 32544)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/wined3d_private.h	(revision 32545)
@@ -2643,9 +2643,14 @@
     unsigned int vSyncCounter;
 
+#ifndef VBOXWDDM
     struct wined3d_context **context;
     unsigned int            num_contexts;
+#endif
 
     HWND                    win_handle;
     HWND device_window;
+#ifdef VBOXWDDM
+    HDC hDC;
+#endif
 };
 
