[PATCH 7/7] Move upsideDown calculation to blit implementation.

Roderick Colenbrander thunderbird2k at gmail.com
Tue Mar 30 15:19:04 CDT 2010


---
 dlls/wined3d/device.c          |   18 +++------
 dlls/wined3d/surface.c         |   79 +++++++++++++++++++++++-----------------
 dlls/wined3d/wined3d_private.h |    2 +-
 3 files changed, 53 insertions(+), 46 deletions(-)

diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index aa16118..1970481 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -5693,7 +5693,7 @@ static HRESULT  WINAPI  IWineD3DDeviceImpl_GetDepthStencilSurface(IWineD3DDevice
 }
 
 void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, const RECT *src_rect_in,
-        IWineD3DSurface *dst_surface, const RECT *dst_rect_in, const WINED3DTEXTUREFILTERTYPE filter, BOOL flip)
+        IWineD3DSurface *dst_surface, const RECT *dst_rect_in, const WINED3DTEXTUREFILTERTYPE filter)
 {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     GLbitfield mask = GL_COLOR_BUFFER_BIT; /* TODO: Support blitting depth/stencil surfaces */
@@ -5703,8 +5703,8 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, const
     POINT offset = {0, 0};
     RECT src_rect, dst_rect;
 
-    TRACE("(%p) : src_surface %p, src_rect_in %p, dst_surface %p, dst_rect_in %p, filter %s (0x%08x), flip %u\n",
-            This, src_surface, src_rect_in, dst_surface, dst_rect_in, debug_d3dtexturefiltertype(filter), filter, flip);
+    TRACE("(%p) : src_surface %p, src_rect_in %p, dst_surface %p, dst_rect_in %p, filter %s (0x%08x)\n",
+            This, src_surface, src_rect_in, dst_surface, dst_rect_in, debug_d3dtexturefiltertype(filter), filter);
     TRACE("src_rect_in %s\n", wine_dbgstr_rect(src_rect_in));
     TRACE("dst_rect_in %s\n", wine_dbgstr_rect(dst_rect_in));
 
@@ -5817,15 +5817,9 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, const
     glDisable(GL_SCISSOR_TEST);
     IWineD3DDeviceImpl_MarkStateDirty(This, STATE_RENDER(WINED3DRS_SCISSORTESTENABLE));
 
-    if (flip) {
-        gl_info->fbo_ops.glBlitFramebuffer(src_rect.left, src_rect.top, src_rect.right, src_rect.bottom,
-                dst_rect.left, dst_rect.bottom, dst_rect.right, dst_rect.top, mask, gl_filter);
-        checkGLcall("glBlitFramebuffer()");
-    } else {
-        gl_info->fbo_ops.glBlitFramebuffer(src_rect.left, src_rect.top, src_rect.right, src_rect.bottom,
-                dst_rect.left, dst_rect.top, dst_rect.right, dst_rect.bottom, mask, gl_filter);
-        checkGLcall("glBlitFramebuffer()");
-    }
+    gl_info->fbo_ops.glBlitFramebuffer(src_rect.left, src_rect.top, src_rect.right, src_rect.bottom,
+            dst_rect.left, dst_rect.top, dst_rect.right, dst_rect.bottom, mask, gl_filter);
+    checkGLcall("glBlitFramebuffer()");
 
     LEAVE_GL();
 
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 7247fe1..fd9dde1 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -3409,14 +3409,25 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_Flip(IWineD3DSurface *iface, IWineD3DS
  * with single pixel copy calls
  */
 static inline void fb_copy_to_texture_direct(IWineD3DSurfaceImpl *This, IWineD3DSurface *SrcSurface,
-        const RECT *src_rect, const RECT *dst_rect, BOOL upsidedown, WINED3DTEXTUREFILTERTYPE Filter)
+        const RECT *src_rect, const RECT *dst_rect_in, WINED3DTEXTUREFILTERTYPE Filter)
 {
     IWineD3DDeviceImpl *myDevice = This->resource.device;
     float xrel, yrel;
     UINT row;
     IWineD3DSurfaceImpl *Src = (IWineD3DSurfaceImpl *) SrcSurface;
     struct wined3d_context *context;
+    BOOL upsidedown = FALSE;
+    RECT dst_rect = *dst_rect_in;
 
+    /* Make sure that the top pixel is always above the bottom pixel, and keep a separate upside down flag
+     * glCopyTexSubImage is a bit picky about the parameters we pass to it
+     */
+    if(dst_rect.top > dst_rect.bottom) {
+        UINT tmp = dst_rect.bottom;
+        dst_rect.bottom = dst_rect.top;
+        dst_rect.top = tmp;
+        upsidedown = TRUE;
+    }
 
     context = context_acquire(myDevice, SrcSurface, CTXUSAGE_BLIT);
     surface_internal_preload((IWineD3DSurface *) This, SRGB_RGB);
@@ -3436,8 +3447,8 @@ static inline void fb_copy_to_texture_direct(IWineD3DSurfaceImpl *This, IWineD3D
     }
     checkGLcall("glReadBuffer");
 
-    xrel = (float) (src_rect->right - src_rect->left) / (float) (dst_rect->right - dst_rect->left);
-    yrel = (float) (src_rect->bottom - src_rect->top) / (float) (dst_rect->bottom - dst_rect->top);
+    xrel = (float) (src_rect->right - src_rect->left) / (float) (dst_rect.right - dst_rect.left);
+    yrel = (float) (src_rect->bottom - src_rect->top) / (float) (dst_rect.bottom - dst_rect.top);
 
     if ((xrel - 1.0f < -eps) || (xrel - 1.0f > eps))
     {
@@ -3460,18 +3471,18 @@ static inline void fb_copy_to_texture_direct(IWineD3DSurfaceImpl *This, IWineD3D
         /* Upside down copy without stretching is nice, one glCopyTexSubImage call will do */
 
         glCopyTexSubImage2D(This->texture_target, This->texture_level,
-                dst_rect->left /*xoffset */, dst_rect->top /* y offset */,
+                dst_rect.left /*xoffset */, dst_rect.top /* y offset */,
                 src_rect->left, Src->currentDesc.Height - src_rect->bottom,
-                dst_rect->right - dst_rect->left, dst_rect->bottom - dst_rect->top);
+                dst_rect.right - dst_rect.left, dst_rect.bottom - dst_rect.top);
     } else {
-        UINT yoffset = Src->currentDesc.Height - src_rect->top + dst_rect->top - 1;
+        UINT yoffset = Src->currentDesc.Height - src_rect->top + dst_rect.top - 1;
         /* I have to process this row by row to swap the image,
          * otherwise it would be upside down, so stretching in y direction
          * doesn't cost extra time
          *
          * However, stretching in x direction can be avoided if not necessary
          */
-        for(row = dst_rect->top; row < dst_rect->bottom; row++) {
+        for(row = dst_rect.top; row < dst_rect.bottom; row++) {
             if ((xrel - 1.0f < -eps) || (xrel - 1.0f > eps))
             {
                 /* Well, that stuff works, but it's very slow.
@@ -3479,15 +3490,15 @@ static inline void fb_copy_to_texture_direct(IWineD3DSurfaceImpl *This, IWineD3D
                  */
                 UINT col;
 
-                for(col = dst_rect->left; col < dst_rect->right; col++) {
+                for(col = dst_rect.left; col < dst_rect.right; col++) {
                     glCopyTexSubImage2D(This->texture_target, This->texture_level,
-                            dst_rect->left + col /* x offset */, row /* y offset */,
+                            dst_rect.left + col /* x offset */, row /* y offset */,
                             src_rect->left + col * xrel, yoffset - (int) (row * yrel), 1, 1);
                 }
             } else {
                 glCopyTexSubImage2D(This->texture_target, This->texture_level,
-                        dst_rect->left /* x offset */, row /* y offset */,
-                        src_rect->left, yoffset - (int) (row * yrel), dst_rect->right-dst_rect->left, 1);
+                        dst_rect.left /* x offset */, row /* y offset */,
+                        src_rect->left, yoffset - (int) (row * yrel), dst_rect.right - dst_rect.left, 1);
             }
         }
     }
@@ -3504,8 +3515,8 @@ static inline void fb_copy_to_texture_direct(IWineD3DSurfaceImpl *This, IWineD3D
 
 /* Uses the hardware to stretch and flip the image */
 static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWineD3DSurface *SrcSurface,
-        IWineD3DSwapChainImpl *swapchain, const RECT *src_rect, const RECT *dst_rect,
-        BOOL upsidedown, WINED3DTEXTUREFILTERTYPE Filter)
+        IWineD3DSwapChainImpl *swapchain, const RECT *src_rect, const RECT *dst_rect_in,
+        WINED3DTEXTUREFILTERTYPE Filter)
 {
     IWineD3DDeviceImpl *myDevice = This->resource.device;
     GLuint src, backup = 0;
@@ -3518,6 +3529,8 @@ static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWine
     GLenum texture_target;
     BOOL noBackBufferBackup;
     BOOL src_offscreen;
+    BOOL upsidedown = FALSE;
+    RECT dst_rect = *dst_rect_in;
 
     TRACE("Using hwstretch blit\n");
     /* Activate the Proper context for reading from the source surface, set it up for blitting */
@@ -3567,6 +3580,16 @@ static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWine
         Src->Flags &= ~SFLAG_INTEXTURE;
     }
 
+    /* Make sure that the top pixel is always above the bottom pixel, and keep a separate upside down flag
+     * glCopyTexSubImage is a bit picky about the parameters we pass to it
+     */
+    if(dst_rect.top > dst_rect.bottom) {
+        UINT tmp = dst_rect.bottom;
+        dst_rect.bottom = dst_rect.top;
+        dst_rect.top = tmp;
+        upsidedown = TRUE;
+    }
+
     if (src_offscreen)
     {
         TRACE("Reading from an offscreen target\n");
@@ -3666,15 +3689,15 @@ static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWine
 
         /* top left */
         glTexCoord2f(left, top);
-        glVertex2i(0, fbheight - dst_rect->bottom - dst_rect->top);
+        glVertex2i(0, fbheight - dst_rect.bottom - dst_rect.top);
 
         /* top right */
         glTexCoord2f(right, top);
-        glVertex2i(dst_rect->right - dst_rect->left, fbheight - dst_rect->bottom - dst_rect->top);
+        glVertex2i(dst_rect.right - dst_rect.left, fbheight - dst_rect.bottom - dst_rect.top);
 
         /* bottom right */
         glTexCoord2f(right, bottom);
-        glVertex2i(dst_rect->right - dst_rect->left, fbheight);
+        glVertex2i(dst_rect.right - dst_rect.left, fbheight);
     glEnd();
     checkGLcall("glEnd and previous");
 
@@ -3690,9 +3713,9 @@ static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWine
     checkGLcall("glBindTexture");
     glCopyTexSubImage2D(texture_target,
                         0,
-                        dst_rect->left, dst_rect->top, /* xoffset, yoffset */
+                        dst_rect.left, dst_rect.top, /* xoffset, yoffset */
                         0, 0, /* We blitted the image to the origin */
-                        dst_rect->right - dst_rect->left, dst_rect->bottom - dst_rect->top);
+                        dst_rect.right - dst_rect.left, dst_rect.bottom - dst_rect.top);
     checkGLcall("glCopyTexSubImage2D");
 
     if(drawBuffer == GL_BACK) {
@@ -3917,7 +3940,7 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const
 
     if((srcSwapchain || SrcSurface == myDevice->render_targets[0]) && !dstSwapchain) {
         /* Blit from render target to texture */
-        BOOL upsideDown = FALSE, stretchx;
+        BOOL stretchx;
         BOOL paletteOverride = FALSE;
 
         if(Flags & (WINEDDBLT_KEYSRC | WINEDDBLT_KEYSRCOVERRIDE)) {
@@ -3926,16 +3949,6 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const
             /* Destination color key is checked above */
         }
 
-        /* Make sure that the top pixel is always above the bottom pixel, and keep a separate upside down flag
-         * glCopyTexSubImage is a bit picky about the parameters we pass to it
-         */
-        if(dst_rect.top > dst_rect.bottom) {
-            UINT tmp = dst_rect.bottom;
-            dst_rect.bottom = dst_rect.top;
-            dst_rect.top = tmp;
-            upsideDown = TRUE;
-        }
-
         if(dst_rect.right - dst_rect.left != src_rect.right - src_rect.left) {
             stretchx = TRUE;
         } else {
@@ -3971,14 +3984,14 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const
                 && surface_can_stretch_rect(Src, This))
         {
             stretch_rect_fbo((IWineD3DDevice *)myDevice, SrcSurface, &src_rect,
-                    (IWineD3DSurface *)This, &dst_rect, Filter, upsideDown);
+                    (IWineD3DSurface *)This, &dst_rect, Filter);
         } else if((!stretchx) || dst_rect.right - dst_rect.left > Src->currentDesc.Width ||
                                     dst_rect.bottom - dst_rect.top > Src->currentDesc.Height) {
             TRACE("No stretching in x direction, using direct framebuffer -> texture copy\n");
-            fb_copy_to_texture_direct(This, SrcSurface, &src_rect, &dst_rect, upsideDown, Filter);
+            fb_copy_to_texture_direct(This, SrcSurface, &src_rect, &dst_rect, Filter);
         } else {
             TRACE("Using hardware stretching to flip / stretch the texture\n");
-            fb_copy_to_texture_hwstretch(This, SrcSurface, srcSwapchain, &src_rect, &dst_rect, upsideDown, Filter);
+            fb_copy_to_texture_hwstretch(This, SrcSurface, srcSwapchain, &src_rect, &dst_rect, Filter);
         }
 
         /* Clear the palette as the surface didn't have a palette attached, it would confuse GetPalette and other calls */
@@ -4024,7 +4037,7 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const
              * contents are never upside down
              */
             stretch_rect_fbo((IWineD3DDevice *)myDevice, SrcSurface, &src_rect,
-                              (IWineD3DSurface *)This, &dst_rect, Filter, FALSE);
+                              (IWineD3DSurface *)This, &dst_rect, Filter);
 
             /* Clear the palette as the surface didn't have a palette attached, it would confuse GetPalette and other calls */
             if(paletteOverride)
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index eb9ae9f..e571943 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -3023,7 +3023,7 @@ static inline BOOL use_ps(IWineD3DStateBlockImpl *stateblock)
 
 void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface,
         const RECT *src_rect, IWineD3DSurface *dst_surface, const RECT *dst_rect,
-        const WINED3DTEXTUREFILTERTYPE filter, BOOL flip) DECLSPEC_HIDDEN;
+        const WINED3DTEXTUREFILTERTYPE filter) DECLSPEC_HIDDEN;
 
 /* The WNDCLASS-Name for the fake window which we use to retrieve the GL capabilities */
 #define WINED3D_OPENGL_WINDOW_CLASS_NAME "WineD3D_OpenGL"
-- 
1.6.3.3




More information about the wine-patches mailing list