Henri Verbeet : wined3d: Keep track of a context's current render target.

Alexandre Julliard julliard at winehq.org
Tue Jul 21 09:34:37 CDT 2009


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

Author: Henri Verbeet <hverbeet at codeweavers.com>
Date:   Tue Jul 21 11:51:08 2009 +0200

wined3d: Keep track of a context's current render target.

---

 dlls/wined3d/context.c         |   36 ++++++++++++++++++++----------------
 dlls/wined3d/wined3d_private.h |    1 +
 2 files changed, 21 insertions(+), 16 deletions(-)

diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index 48b8e09..78ef374 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -470,7 +470,7 @@ void context_resource_released(IWineD3DDevice *iface, IWineD3DResource *resource
     {
         case WINED3DRTYPE_SURFACE:
         {
-            if ((IWineD3DSurface *)resource == This->lastActiveRenderTarget)
+            if (This->activeContext && (IWineD3DSurface *)resource == This->activeContext->current_rt)
             {
                 IWineD3DSwapChainImpl *swapchain;
 
@@ -506,6 +506,7 @@ void context_resource_released(IWineD3DDevice *iface, IWineD3DResource *resource
                         TRACE("Device is being destroyed, setting lastActiveRenderTarget to 0xdeadbabe.\n");
 
                         This->lastActiveRenderTarget = (IWineD3DSurface *) 0xdeadbabe;
+                        This->activeContext->current_rt = This->lastActiveRenderTarget;
                     }
                 }
                 else
@@ -514,6 +515,7 @@ void context_resource_released(IWineD3DDevice *iface, IWineD3DResource *resource
 
                     /* May happen during ddraw uninitialization. */
                     This->lastActiveRenderTarget = (IWineD3DSurface *)0xdeadcafe;
+                    This->activeContext->current_rt = This->lastActiveRenderTarget;
                 }
             }
             else if (This->d3d_initialized)
@@ -1019,6 +1021,7 @@ WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *tar
     }
     ret->gl_info = &This->adapter->gl_info;
     ret->surface = (IWineD3DSurface *) target;
+    ret->current_rt = (IWineD3DSurface *)target;
     ret->isPBuffer = create_pbuffer;
     ret->tid = GetCurrentThreadId();
     if(This->shader_backend->shader_dirtifyable_constants((IWineD3DDevice *) This)) {
@@ -1515,22 +1518,8 @@ static inline WineD3DContext *FindContext(IWineD3DDeviceImpl *This, IWineD3DSurf
     BOOL readTexture = wined3d_settings.offscreen_rendering_mode != ORM_FBO && This->render_offscreen;
     WineD3DContext *context = This->activeContext;
     BOOL oldRenderOffscreen = This->render_offscreen;
-    const struct GlPixelFormatDesc *old = ((IWineD3DSurfaceImpl *)This->lastActiveRenderTarget)->resource.format_desc;
-    const struct GlPixelFormatDesc *new = ((IWineD3DSurfaceImpl *)target)->resource.format_desc;
     const struct StateEntry *StateTable = This->StateTable;
-
-    /* To compensate the lack of format switching with some offscreen rendering methods and on onscreen buffers
-     * the alpha blend state changes with different render target formats
-     */
-    if (old->format != new->format)
-    {
-        /* Disable blending when the alpha mask has changed and when a format doesn't support blending */
-        if ((old->alpha_mask && !new->alpha_mask) || (!old->alpha_mask && new->alpha_mask)
-                || !(new->Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING))
-        {
-            Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), StateTable);
-        }
-    }
+    const struct GlPixelFormatDesc *old, *new;
 
     if (SUCCEEDED(IWineD3DSurface_GetContainer(target, &IID_IWineD3DSwapChain, (void **)&swapchain))) {
         TRACE("Rendering onscreen\n");
@@ -1638,6 +1627,20 @@ static inline WineD3DContext *FindContext(IWineD3DDeviceImpl *This, IWineD3DSurf
         }
     }
 
+    /* To compensate the lack of format switching with some offscreen rendering methods and on onscreen buffers
+     * the alpha blend state changes with different render target formats. */
+    old = ((IWineD3DSurfaceImpl *)context->current_rt)->resource.format_desc;
+    new = ((IWineD3DSurfaceImpl *)target)->resource.format_desc;
+    if (old->format != new->format)
+    {
+        /* Disable blending when the alpha mask has changed and when a format doesn't support blending. */
+        if ((old->alpha_mask && !new->alpha_mask) || (!old->alpha_mask && new->alpha_mask)
+                || !(new->Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING))
+        {
+            Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), StateTable);
+        }
+    }
+
     /* When switching away from an offscreen render target, and we're not using FBOs,
      * we have to read the drawable into the texture. This is done via PreLoad(and
      * SFLAG_INDRAWABLE set on the surface). There are some things that need care though.
@@ -1765,6 +1768,7 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU
     if(This->lastActiveRenderTarget != target || tid != This->lastThread) {
         context = FindContext(This, target, tid);
         context->draw_buffer_dirty = TRUE;
+        context->current_rt = target;
         This->lastActiveRenderTarget = target;
         This->lastThread = tid;
     } else {
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 59b91b3..c76db79 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1203,6 +1203,7 @@ struct WineD3DContext
     DWORD                   isStateDirty[STATE_HIGHEST/32 + 1]; /* Bitmap to find out quickly if a state is dirty */
 
     IWineD3DSurface         *surface;
+    IWineD3DSurface *current_rt;
     DWORD                   tid;    /* Thread ID which owns this context at the moment */
 
     /* Stores some information about the context state for optimization */




More information about the wine-cvs mailing list