Stefan Dösinger : wined3d: Activate a different context if the active render target is destroyed.

Alexandre Julliard julliard at wine.codeweavers.com
Mon Feb 19 07:02:21 CST 2007


Module: wine
Branch: master
Commit: 5e37345b3046aa0c80a9d12044a506028ed8e65b
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=5e37345b3046aa0c80a9d12044a506028ed8e65b

Author: Stefan Dösinger <stefan at codeweavers.com>
Date:   Sat Feb 17 18:06:30 2007 +0100

wined3d: Activate a different context if the active render target is destroyed.

---

 dlls/wined3d/surface.c |   36 ++++++++++++++++++++++++++++++++----
 1 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 333712d..b090366 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -247,6 +247,38 @@ ULONG WINAPI IWineD3DSurfaceImpl_Release(IWineD3DSurface *iface) {
     if (ref == 0) {
         IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) This->resource.wineD3DDevice;
         TRACE("(%p) : cleaning up\n", This);
+
+        if(iface == device->lastActiveRenderTarget) {
+            IWineD3DSwapChainImpl *swapchain = device->swapchains ? (IWineD3DSwapChainImpl *) device->swapchains[0] : NULL;
+
+            TRACE("Last active render target destroyed\n");
+            /* Find a replacement surface for the currently active back buffer. The context manager does not do NULL
+             * checks, so switch to a valid target as long as the currently set surface is still valid. Use the
+             * surface of the implicit swpchain. If that is the same as the destroyed surface the device is destroyed
+             * and the lastActiveRenderTarget member shouldn't matter
+             */
+            if(swapchain) {
+                if(swapchain->backBuffer && swapchain->backBuffer[0] != iface) {
+                    TRACE("Activating primary back buffer\n");
+                    ActivateContext(device, swapchain->backBuffer[0], CTXUSAGE_RESOURCELOAD);
+                } else if(!swapchain->backBuffer && swapchain->frontBuffer != iface) {
+                    /* Single buffering environment */
+                    TRACE("Activating primary front buffer\n");
+                    ActivateContext(device, swapchain->frontBuffer, CTXUSAGE_RESOURCELOAD);
+                } else {
+                    TRACE("Device is beeing destroyed, setting lastActiveRenderTarget = 0xdeadbabe\n");
+                    /* Implicit render target destroyed, that means the device is beeing destroyed
+                     * whatever we set here, it shouldn't matter
+                     */
+                    device->lastActiveRenderTarget = (IWineD3DSurface *) 0xdeadbabe;
+                }
+            } else {
+                /* May happen during ddraw uninitialization */
+                TRACE("Render target set, but swapchain does not exist!\n");
+                device->lastActiveRenderTarget = (IWineD3DSurface *) 0xdeadcafe;
+            }
+        }
+
         if (This->glDescription.textureName != 0) { /* release the openGL texture.. */
             ENTER_GL();
             TRACE("Deleting texture %d\n", This->glDescription.textureName);
@@ -269,10 +301,6 @@ ULONG WINAPI IWineD3DSurfaceImpl_Release(IWineD3DSurface *iface) {
         if(iface == device->ddraw_primary)
             device->ddraw_primary = NULL;
 
-        if(iface == device->lastActiveRenderTarget) {
-            device->lastActiveRenderTarget = NULL;
-        }
-
         TRACE("(%p) Released\n", This);
         HeapFree(GetProcessHeap(), 0, This);
 




More information about the wine-cvs mailing list