Stefan Dösinger : wined3d: Blitting to offscreen target.

Alexandre Julliard julliard at wine.codeweavers.com
Thu Mar 15 08:19:22 CDT 2007


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

Author: Stefan Dösinger <stefan at codeweavers.com>
Date:   Wed Mar 14 22:00:31 2007 +0100

wined3d: Blitting to offscreen target.

Fix the NULL deref that occured when blitting to offscreen targets and
select the proper gl drawing buffer instead.

---

 dlls/wined3d/device.c  |    2 +-
 dlls/wined3d/surface.c |   20 ++++++++++++++------
 2 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 460a255..9223b55 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -690,7 +690,7 @@ static HRESULT  WINAPI IWineD3DDeviceImpl_CreateSurface(IWineD3DDevice *iface, U
     object->pow2Height = pow2Height;
 
     /* Flags */
-    object->Flags      = 0; /* We start without flags set */
+    object->Flags      = SFLAG_DYNLOCK;
     object->Flags     |= (pow2Width != Width || pow2Height != Height) ? SFLAG_NONPOW2 : 0;
     object->Flags     |= Discard ? SFLAG_DISCARD : 0;
     object->Flags     |= (WINED3DFMT_D16_LOCKABLE == Format) ? SFLAG_LOCKABLE : 0;
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 30ae169..a295bc7 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -2637,7 +2637,6 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, RECT *
         DWORD oldCKeyFlags = Src->CKeyFlags;
         DDCOLORKEY oldBltCKey = This->SrcBltCKey;
         RECT SourceRectangle;
-        GLint oldDraw;
 
         TRACE("Blt from surface %p to rendertarget %p\n", Src, This);
 
@@ -2687,11 +2686,17 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, RECT *
         /* Activate the destination context, set it up for blitting */
         ActivateContext(myDevice, (IWineD3DSurface *) This, CTXUSAGE_BLIT);
 
-        glGetIntegerv(GL_DRAW_BUFFER, &oldDraw);
-        if(This == (IWineD3DSurfaceImpl *) dstSwapchain->frontBuffer) {
+        if(!dstSwapchain) {
+            TRACE("Drawing to offscreen buffer\n");
+            glDrawBuffer(myDevice->offscreenBuffer);
+        } else if(This == (IWineD3DSurfaceImpl *) dstSwapchain->frontBuffer) {
             TRACE("Drawing to front buffer\n");
             glDrawBuffer(GL_FRONT);
             checkGLcall("glDrawBuffer GL_FRONT");
+        } else {
+            TRACE("Drawing to back buffer\n");
+            glDrawBuffer(GL_BACK);
+            checkGLcall("glDrawBuffer GL_BACK");
         }
 
         /* Bind the texture */
@@ -2722,7 +2727,7 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, RECT *
         }
 
         /* Draw a textured quad
-            */
+         */
         glBegin(GL_QUADS);
 
         glColor3d(1.0f, 1.0f, 1.0f);
@@ -2755,8 +2760,11 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, RECT *
         glBindTexture(GL_TEXTURE_2D, 0);
         checkGLcall("glEnable glBindTexture");
 
-        if(This == (IWineD3DSurfaceImpl *) dstSwapchain->frontBuffer && oldDraw == GL_BACK) {
-            glDrawBuffer(oldDraw);
+        /* The draw buffer should only need to be restored if we were drawing to the front buffer, and there is a back buffer.
+         * otherwise the context manager should choose between GL_BACK / offscreenDrawBuffer
+         */
+        if(dstSwapchain && This == (IWineD3DSurfaceImpl *) dstSwapchain->frontBuffer && dstSwapchain->backBuffer) {
+            glDrawBuffer(GL_BACK);
         }
         /* Restore the color key parameters */
         Src->CKeyFlags = oldCKeyFlags;




More information about the wine-cvs mailing list