WineD3D: Honor the pitch in a few more places

Stefan Dösinger stefan at codeweavers.com
Thu Oct 5 14:35:10 CDT 2006


The surface conversion code and the dib section creation code ignored the 
pitch, this patch fixes that. It shouldn't make any difference because the 
gdi code ignores the size and the surface conversion happened on the full 
length, but this way it looks more correct(and will help if we do some 
conversion on R8G8B8 one day)
-------------- next part --------------
From fa5b8db71a270a06cd21c7953be8e05c5b0a9536 Mon Sep 17 00:00:00 2001
From: Stefan Doesinger <stefan at codeweavers.com>
Date: Thu, 5 Oct 2006 21:19:39 +0200
Subject: [PATCH] WineD3D: Honor the pitch in a few places
---
 dlls/wined3d/surface.c |   75 +++++++++++++++++++++++++++++-------------------
 1 files changed, 46 insertions(+), 29 deletions(-)

diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index b3a8e98..71c2815 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -47,7 +47,7 @@ typedef enum {
     CONVERT_RGB32_888
 } CONVERT_TYPES;
 
-HRESULT d3dfmt_convert_surface(BYTE *src, BYTE *dst, unsigned long len, CONVERT_TYPES convert, IWineD3DSurfaceImpl *surf);
+HRESULT d3dfmt_convert_surface(BYTE *src, BYTE *dst, UINT pitch, UINT height, UINT outpitch, CONVERT_TYPES convert, IWineD3DSurfaceImpl *surf);
 
 static void surface_download_data(IWineD3DSurfaceImpl *This) {
     if (This->resource.format == WINED3DFMT_DXT1 ||
@@ -992,7 +992,9 @@ static void flush_to_framebuffer_drawpix
             }
             d3dfmt_convert_surface(This->resource.allocatedMemory,
                                    mem,
-                                   pitch*height,
+                                   pitch,
+                                   height,
+                                   pitch * 4,
                                    CONVERT_PALETTED,
                                    This);
         }
@@ -1340,14 +1342,14 @@ HRESULT WINAPI IWineD3DSurfaceImpl_GetDC
         if( (NP2_REPACK == wined3d_settings.nonpower2_mode || This->resource.usage & WINED3DUSAGE_RENDERTARGET)) {
             b_info->bmiHeader.biWidth = This->currentDesc.Width;
             b_info->bmiHeader.biHeight = -This->currentDesc.Height -extraline;
-            b_info->bmiHeader.biSizeImage = This->currentDesc.Width * This->currentDesc.Height * This->bytesPerPixel;
+            b_info->bmiHeader.biSizeImage = ( This->currentDesc.Height + extraline) * IWineD3DSurface_GetPitch(iface);
             /* Use the full pow2 image size(assigned below) because LockRect
              * will need it for a full glGetTexImage call
              */
         } else {
             b_info->bmiHeader.biWidth = This->pow2Width;
             b_info->bmiHeader.biHeight = -This->pow2Height -extraline;
-            b_info->bmiHeader.biSizeImage = This->resource.size;
+            b_info->bmiHeader.biSizeImage = This->resource.size + extraline  * IWineD3DSurface_GetPitch(iface);
         }
         b_info->bmiHeader.biPlanes = 1;
         b_info->bmiHeader.biBitCount = This->bytesPerPixel * 8;
@@ -1580,13 +1582,14 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceI
     return WINED3D_OK;
 }
 
-HRESULT d3dfmt_convert_surface(BYTE *src, BYTE *dst, unsigned long len, CONVERT_TYPES convert, IWineD3DSurfaceImpl *surf) {
-    TRACE("(%p)->(%p),(%ld,%d,%p)\n", src, dst, len, convert, surf);
+HRESULT d3dfmt_convert_surface(BYTE *src, BYTE *dst, UINT pitch, UINT height, UINT outpitch, CONVERT_TYPES convert, IWineD3DSurfaceImpl *surf) {
+    BYTE *dest;
+    TRACE("(%p)->(%p),(%d,%d,%d,%d,%p)\n", src, dst, pitch, height, outpitch, convert, surf);
 
     switch (convert) {
         case NO_CONVERSION:
         {
-            memcpy(dst, src, len * surf->bytesPerPixel);
+            memcpy(dst, src, pitch * height);
             break;
         }
         case CONVERT_PALETTED:
@@ -1595,7 +1598,7 @@ HRESULT d3dfmt_convert_surface(BYTE *src
             IWineD3DPaletteImpl* pal = surf->palette;
             BYTE table[256][4];
             unsigned int i;
-            unsigned int x;
+            unsigned int x, y;
 
             if( pal == NULL) {
                 /* TODO: If we are a sublevel, try to get the palette from level 0 */
@@ -1641,12 +1644,17 @@ HRESULT d3dfmt_convert_surface(BYTE *src
                 }
             }
 
-            for (x = 0; x < len; x++) {
-                BYTE color = *src++;
-                *dst++ = table[color][0];
-                *dst++ = table[color][1];
-                *dst++ = table[color][2];
-                *dst++ = table[color][3];
+            for (y = 0; y < height; y++)
+            {
+                dest = dst + outpitch * y;
+                /* This is an 1 bpp format, using the pitch here is fine */
+                for (x = 0; x < pitch; x++) {
+                    BYTE color = *src++;
+                    *dest++ = table[color][0];
+                    *dest++ = table[color][1];
+                    *dest++ = table[color][2];
+                    *dest++ = table[color][3];
+                }
             }
         }
         break;
@@ -1663,20 +1671,24 @@ HRESULT d3dfmt_convert_surface(BYTE *src
               Note2: Nvidia documents say that their driver does not support alpha + color keying
                      on the same surface and disables color keying in such a case
             */
-            unsigned int x;
-            WORD *Source = (WORD *) src;
-            WORD *Dest = (WORD *) dst;
+            unsigned int x, y;
+            WORD *Source;
+            WORD *Dest;
 
             TRACE("Color keyed 565\n");
 
-            for (x = 0; x < len; x++ ) {
-                WORD color = *Source++;
-                *Dest = ((color & 0xFFC0) | ((color & 0x1F) << 1));
-                if ((color < surf->SrcBltCKey.dwColorSpaceLowValue) ||
-                    (color > surf->SrcBltCKey.dwColorSpaceHighValue)) {
-                    *Dest |= 0x0001;
+            for (y = 0; y < height; y++) {
+                Source = (WORD *) (src + y * pitch);
+                Dest = (WORD *) (dst + y * outpitch);
+                for (x = 0; x < pitch / 2; x++ ) {
+                    WORD color = *Source++;
+                    *Dest = ((color & 0xFFC0) | ((color & 0x1F) << 1));
+                    if ((color < surf->SrcBltCKey.dwColorSpaceLowValue) ||
+                        (color > surf->SrcBltCKey.dwColorSpaceHighValue)) {
+                        *Dest |= 0x0001;
+                    }
+                    Dest++;
                 }
-                Dest++;
             }
         }
         break;
@@ -1684,7 +1696,6 @@ HRESULT d3dfmt_convert_surface(BYTE *src
         default:
             ERR("Unsupported conversation type %d\n", convert);
     }
-
     return WINED3D_OK;
 }
 
@@ -1745,7 +1756,7 @@ static HRESULT WINAPI IWineD3DSurfaceImp
     GLenum format, internal, type;
     CONVERT_TYPES convert;
     int bpp;
-    int width;
+    int width, pitch, outpitch;
     BYTE *mem;
 
     if (This->Flags & SFLAG_INTEXTURE) {
@@ -1834,15 +1845,21 @@ static HRESULT WINAPI IWineD3DSurfaceImp
     else
         width = This->pow2Width;
 
+    pitch = IWineD3DSurface_GetPitch(iface);
+
     if((convert != NO_CONVERSION) && This->resource.allocatedMemory) {
         int height = This->glRect.bottom - This->glRect.top;
 
-        mem = HeapAlloc(GetProcessHeap(), 0, width * height * bpp);
+        /* Stick to the alignment for the converted surface too, makes it easier to load the surface */
+        outpitch = width * bpp;
+        outpitch = (outpitch + 3) & ~3;
+
+        mem = HeapAlloc(GetProcessHeap(), 0, outpitch * height);
         if(!mem) {
-            ERR("Out of memory %d, %d!\n", width, height);
+            ERR("Out of memory %d, %d!\n", outpitch, height);
             return WINED3DERR_OUTOFVIDEOMEMORY;
         }
-        d3dfmt_convert_surface(This->resource.allocatedMemory, mem, width * height, convert, This);
+        d3dfmt_convert_surface(This->resource.allocatedMemory, mem, pitch, height, outpitch, convert, This);
 
         This->Flags |= SFLAG_CONVERTED;
     } else if (This->resource.format == WINED3DFMT_P8 && GL_SUPPORT(EXT_PALETTED_TEXTURE)) {
-- 
1.4.1.1



More information about the wine-patches mailing list