WineD3D: Surface data is 32 bit aligned

Stefan Dösinger stefan at codeweavers.com
Sun Sep 24 02:49:05 CDT 2006


Am Sonntag 24 September 2006 00:00 schrieb Stefan Dösinger:
> The pitch of a d3d surface is always a multiple of 4. This is shown by a
> test case creating a 5x5 D3DFMT_R5G6B6 surface, which ends up with a pitch
> of 12. The pitch and size calculations in wined3d is adjusted accordingly.
>
> The only formats that can be used for this test are R5G6B5 and A1R5G5B5(and
> X1R5G5B5). This is because D3DFMT_R8G8B8 is not supported on
> windows(apparently), and D3DFMT_P8 is only supported on elderly hardware.
>
> The test is marked as todo because WineD3D still has the non power of 2
> support which reports the power of 2 pitch to the application. Henri
> Verbeet has some pending patches for this.
Use this patch instead, it contains the test too

-------------- next part --------------
From 3517363f2001d1e3ce4cac57cb71c91b49321a9d Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Stefan_D=F6singer?= <stefan at codeweavers.com>
Date: Sun, 24 Sep 2006 09:47:53 +0200
Subject: [PATCH] WineD3D: Surface pitches are multiples of 4
---
 dlls/d3d9/tests/surface.c  |   22 ++++++++++++++++++++++
 dlls/wined3d/device.c      |    5 ++++-
 dlls/wined3d/surface.c     |    6 +++++-
 dlls/wined3d/surface_gdi.c |    2 +-
 4 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/dlls/d3d9/tests/surface.c b/dlls/d3d9/tests/surface.c
index 23b8d73..7934d1f 100644
--- a/dlls/d3d9/tests/surface.c
+++ b/dlls/d3d9/tests/surface.c
@@ -113,6 +113,27 @@ cleanup:
     if (surface_ptr) IDirect3DSurface9_Release(surface_ptr);
 }
 
+static void test_surface_alignment(IDirect3DDevice9 *device_ptr)
+{
+    IDirect3DSurface9 *surface_ptr = 0;
+    HRESULT hr;
+
+    /* Test a sysmem surface as those aren't affected by the hardware's np2 restrictions */
+    hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device_ptr, 5, 5, D3DFMT_R5G6B5, D3DPOOL_SYSTEMMEM, &surface_ptr, 0);
+    ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface returned %08lx\n", hr);
+
+    if(surface_ptr)
+    {
+        D3DLOCKED_RECT lockedRect;
+        hr = IDirect3DSurface9_LockRect(surface_ptr, &lockedRect, NULL, 0);
+        ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08lx\n", hr);
+        /* test is deactivated until out np2 support doesn't report the full power of 2 pitch to the app */
+        todo_wine ok(lockedRect.Pitch == 12, "Got pitch %d, expected 12\n", lockedRect.Pitch);
+        hr = IDirect3DSurface9_UnlockRect(surface_ptr);
+        IDirect3DSurface9_Release(surface_ptr);
+    }
+}
+
 START_TEST(surface)
 {
     HMODULE d3d9_handle;
@@ -129,4 +150,5 @@ START_TEST(surface)
     if (!device_ptr) return;
 
     test_surface_get_container(device_ptr);
+    test_surface_alignment(device_ptr);
 }
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index e32b824..864aec0 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -1001,7 +1001,10 @@ static HRESULT  WINAPI IWineD3DDeviceImp
                Format == WINED3DFMT_DXT4 || Format == WINED3DFMT_DXT5) {
        Size = ((max(pow2Width,4) * tableEntry->bpp) * max(pow2Height,4));
     } else {
-       Size = (pow2Width * tableEntry->bpp) * pow2Height;
+       Size = (pow2Width * tableEntry->bpp);
+       /* The pitch is a multiple of 4 bytes */
+       if(Size % 4 == 0) Size += 4 - Size % 4;
+       Size *= pow2Height;
     }
 
     /** Create and initialise the surface resource **/
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 908211e..9c7564f 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -2170,7 +2170,9 @@ HRESULT WINAPI IWineD3DSurfaceImpl_SetFo
                format == WINED3DFMT_DXT4 || format == WINED3DFMT_DXT5) {
         This->resource.size = ((max(This->pow2Width, 4) * formatEntry->bpp) * max(This->pow2Height, 4));
     } else {
-        This->resource.size = (This->pow2Width * formatEntry->bpp) * This->pow2Height;
+        This->resource.size = (This->pow2Width * formatEntry->bpp);
+        if(This->resource.size % 4 == 0) This->resource.size += 4 - This->resource.size % 4;
+        This->resource.size *= This->pow2Height;
     }
 
 
@@ -3063,6 +3065,8 @@ DWORD WINAPI IWineD3DSurfaceImpl_GetPitc
         } else {
             ret = This->bytesPerPixel * This->pow2Width;
         }
+        /* Surfaces are 32 bit aligned */
+        if(ret % 4 != 0) ret += 4 - ret % 4;
     }
     TRACE("(%p) Returning %ld\n", This, ret);
     return ret;
diff --git a/dlls/wined3d/surface_gdi.c b/dlls/wined3d/surface_gdi.c
index f9b20c1..65c8aae 100644
--- a/dlls/wined3d/surface_gdi.c
+++ b/dlls/wined3d/surface_gdi.c
@@ -1516,7 +1516,7 @@ IWineGDISurfaceImpl_PrivateSetup(IWineD3
     This->resource.allocatedMemory = NULL;
 
     /* We don't mind the nonpow2 stuff in GDI */
-    This->resource.size = This->currentDesc.Width * getFormatDescEntry(This->resource.format)->bpp * This->currentDesc.Height;
+    This->resource.size = IWineD3DSurface_GetPitch(iface) * This->currentDesc.Height;
     This->pow2Size = This->resource.size;
     This->pow2Width = This->currentDesc.Width;
     This->pow2Height = This->currentDesc.Height;
-- 
1.4.1.1



More information about the wine-patches mailing list