[PATCH 3/5] ddraw: Validate the pitch for user memory surfaces against the unaligned minimum pitch.

Henri Verbeet hverbeet at codeweavers.com
Wed Apr 23 07:35:20 CDT 2014


User memory surfaces have a different minimum alignment from regular surfaces.
This fixes a regression introduced by commit
9c138d772c692d44103a6641c32f3b74dc83303e.
---
 dlls/ddraw/surface.c      |    3 ++-
 dlls/ddraw/tests/ddraw1.c |   10 +++++-----
 dlls/ddraw/tests/ddraw2.c |   10 +++++-----
 dlls/ddraw/tests/ddraw4.c |   20 +++++++++++---------
 dlls/ddraw/tests/ddraw7.c |   20 +++++++++++---------
 dlls/wined3d/directx.c    |   15 +++++++++++++++
 dlls/wined3d/wined3d.spec |    1 +
 include/wine/wined3d.h    |    2 ++
 8 files changed, 52 insertions(+), 29 deletions(-)

diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c
index 5717956..13458f6 100644
--- a/dlls/ddraw/surface.c
+++ b/dlls/ddraw/surface.c
@@ -6102,7 +6102,8 @@ HRESULT ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw, s
 
     if (desc->dwFlags & DDSD_LPSURFACE)
     {
-        if (desc->u1.lPitch < wined3d_surface_get_pitch(wined3d_surface) || desc->u1.lPitch & 3)
+        if (desc->u1.lPitch < wined3d_calculate_format_pitch(ddraw->wined3d, WINED3DADAPTER_DEFAULT,
+                wined3d_desc.format, wined3d_desc.width) || desc->u1.lPitch & 3)
         {
             WARN("Invalid pitch %u specified.\n", desc->u1.lPitch);
             return DDERR_INVALIDPARAMS;
diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c
index 512cae6..98bb10e 100644
--- a/dlls/ddraw/tests/ddraw1.c
+++ b/dlls/ddraw/tests/ddraw1.c
@@ -4458,7 +4458,7 @@ static void test_create_surface_pitch(void)
                                 DDSD_PITCH,                     0x100},
         {DDSCAPS_VIDEOMEMORY,   DDSD_PITCH,                     0x104,  DD_OK,
                                 DDSD_PITCH,                     0x100},
-        {DDSCAPS_VIDEOMEMORY,   DDSD_PITCH,                     0x0fc,  DD_OK,
+        {DDSCAPS_VIDEOMEMORY,   DDSD_PITCH,                     0x0f8,  DD_OK,
                                 DDSD_PITCH,                     0x100},
         {DDSCAPS_VIDEOMEMORY,   DDSD_LPSURFACE | DDSD_PITCH,    0x100,  DDERR_INVALIDCAPS,
                                 0,                              0    },
@@ -4466,7 +4466,7 @@ static void test_create_surface_pitch(void)
                                 DDSD_PITCH,                     0x100},
         {DDSCAPS_SYSTEMMEMORY,  DDSD_PITCH,                     0x104,  DD_OK,
                                 DDSD_PITCH,                     0x100},
-        {DDSCAPS_SYSTEMMEMORY,  DDSD_PITCH,                     0x0fc,  DD_OK,
+        {DDSCAPS_SYSTEMMEMORY,  DDSD_PITCH,                     0x0f8,  DD_OK,
                                 DDSD_PITCH,                     0x100},
         {DDSCAPS_SYSTEMMEMORY,  DDSD_LPSURFACE,                 0,      DDERR_INVALIDPARAMS,
                                 0,                              0    },
@@ -4482,7 +4482,7 @@ static void test_create_surface_pitch(void)
     hr = IDirectDraw_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
     ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
 
-    mem = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ((64 * 4) + 4) * 64);
+    mem = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ((63 * 4) + 8) * 63);
 
     for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
     {
@@ -4490,8 +4490,8 @@ static void test_create_surface_pitch(void)
         surface_desc.dwSize = sizeof(surface_desc);
         surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | test_data[i].flags_in;
         surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | test_data[i].placement;
-        surface_desc.dwWidth = 64;
-        surface_desc.dwHeight = 64;
+        surface_desc.dwWidth = 63;
+        surface_desc.dwHeight = 63;
         U1(surface_desc).lPitch = test_data[i].pitch_in;
         surface_desc.lpSurface = mem;
         surface_desc.ddpfPixelFormat.dwSize = sizeof(surface_desc.ddpfPixelFormat);
diff --git a/dlls/ddraw/tests/ddraw2.c b/dlls/ddraw/tests/ddraw2.c
index 0103c96..043653f 100644
--- a/dlls/ddraw/tests/ddraw2.c
+++ b/dlls/ddraw/tests/ddraw2.c
@@ -5563,7 +5563,7 @@ static void test_create_surface_pitch(void)
                                 DDSD_PITCH,                     0x100},
         {DDSCAPS_VIDEOMEMORY,   DDSD_PITCH,                     0x104,  DD_OK,
                                 DDSD_PITCH,                     0x100},
-        {DDSCAPS_VIDEOMEMORY,   DDSD_PITCH,                     0x0fc,  DD_OK,
+        {DDSCAPS_VIDEOMEMORY,   DDSD_PITCH,                     0x0f8,  DD_OK,
                                 DDSD_PITCH,                     0x100},
         {DDSCAPS_VIDEOMEMORY,   DDSD_LPSURFACE | DDSD_PITCH,    0x100,  DDERR_INVALIDCAPS,
                                 0,                              0    },
@@ -5571,7 +5571,7 @@ static void test_create_surface_pitch(void)
                                 DDSD_PITCH,                     0x100},
         {DDSCAPS_SYSTEMMEMORY,  DDSD_PITCH,                     0x104,  DD_OK,
                                 DDSD_PITCH,                     0x100},
-        {DDSCAPS_SYSTEMMEMORY,  DDSD_PITCH,                     0x0fc,  DD_OK,
+        {DDSCAPS_SYSTEMMEMORY,  DDSD_PITCH,                     0x0f8,  DD_OK,
                                 DDSD_PITCH,                     0x100},
         {DDSCAPS_SYSTEMMEMORY,  DDSD_LPSURFACE,                 0,      DDERR_INVALIDPARAMS,
                                 0,                              0    },
@@ -5587,7 +5587,7 @@ static void test_create_surface_pitch(void)
     hr = IDirectDraw_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
     ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
 
-    mem = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ((64 * 4) + 4) * 64);
+    mem = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ((63 * 4) + 8) * 63);
 
     for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
     {
@@ -5595,8 +5595,8 @@ static void test_create_surface_pitch(void)
         surface_desc.dwSize = sizeof(surface_desc);
         surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | test_data[i].flags_in;
         surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | test_data[i].placement;
-        surface_desc.dwWidth = 64;
-        surface_desc.dwHeight = 64;
+        surface_desc.dwWidth = 63;
+        surface_desc.dwHeight = 63;
         U1(surface_desc).lPitch = test_data[i].pitch_in;
         surface_desc.lpSurface = mem;
         surface_desc.ddpfPixelFormat.dwSize = sizeof(surface_desc.ddpfPixelFormat);
diff --git a/dlls/ddraw/tests/ddraw4.c b/dlls/ddraw/tests/ddraw4.c
index 1d810ad..556d4ef 100644
--- a/dlls/ddraw/tests/ddraw4.c
+++ b/dlls/ddraw/tests/ddraw4.c
@@ -6427,7 +6427,7 @@ static void test_create_surface_pitch(void)
                                 DDSD_PITCH,                     0x100},
         {DDSCAPS_VIDEOMEMORY,   DDSD_PITCH,                     0x104,  DD_OK,
                                 DDSD_PITCH,                     0x100},
-        {DDSCAPS_VIDEOMEMORY,   DDSD_PITCH,                     0x0fc,  DD_OK,
+        {DDSCAPS_VIDEOMEMORY,   DDSD_PITCH,                     0x0f8,  DD_OK,
                                 DDSD_PITCH,                     0x100},
         {DDSCAPS_VIDEOMEMORY,   DDSD_LPSURFACE | DDSD_PITCH,    0x100,  DDERR_INVALIDCAPS,
                                 0,                              0    },
@@ -6435,15 +6435,17 @@ static void test_create_surface_pitch(void)
                                 DDSD_PITCH,                     0x100},
         {DDSCAPS_SYSTEMMEMORY,  DDSD_PITCH,                     0x104,  DD_OK,
                                 DDSD_PITCH,                     0x100},
-        {DDSCAPS_SYSTEMMEMORY,  DDSD_PITCH,                     0x0fc,  DD_OK,
+        {DDSCAPS_SYSTEMMEMORY,  DDSD_PITCH,                     0x0f8,  DD_OK,
                                 DDSD_PITCH,                     0x100},
         {DDSCAPS_SYSTEMMEMORY,  DDSD_LPSURFACE,                 0,      DDERR_INVALIDPARAMS,
                                 0,                              0    },
-        {DDSCAPS_SYSTEMMEMORY,  DDSD_LPSURFACE | DDSD_PITCH,    0x104,  DD_OK,
-                                DDSD_PITCH,                     0x104},
-        {DDSCAPS_SYSTEMMEMORY,  DDSD_LPSURFACE | DDSD_PITCH,    0x102,  DDERR_INVALIDPARAMS,
+        {DDSCAPS_SYSTEMMEMORY,  DDSD_LPSURFACE | DDSD_PITCH,    0x100,  DD_OK,
+                                DDSD_PITCH,                     0x100},
+        {DDSCAPS_SYSTEMMEMORY,  DDSD_LPSURFACE | DDSD_PITCH,    0x0fe,  DDERR_INVALIDPARAMS,
                                 0,                              0    },
-        {DDSCAPS_SYSTEMMEMORY,  DDSD_LPSURFACE | DDSD_PITCH,    0x0fc,  DDERR_INVALIDPARAMS,
+        {DDSCAPS_SYSTEMMEMORY,  DDSD_LPSURFACE | DDSD_PITCH,    0x0fc,  DD_OK,
+                                DDSD_PITCH,                     0x0fc},
+        {DDSCAPS_SYSTEMMEMORY,  DDSD_LPSURFACE | DDSD_PITCH,    0x0f8,  DDERR_INVALIDPARAMS,
                                 0,                              0    },
     };
     DWORD flags_mask = DDSD_PITCH | DDSD_LPSURFACE;
@@ -6455,7 +6457,7 @@ static void test_create_surface_pitch(void)
     hr = IDirectDraw_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
     ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
 
-    mem = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ((64 * 4) + 4) * 64);
+    mem = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ((63 * 4) + 8) * 63);
 
     for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
     {
@@ -6463,8 +6465,8 @@ static void test_create_surface_pitch(void)
         surface_desc.dwSize = sizeof(surface_desc);
         surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | test_data[i].flags_in;
         surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | test_data[i].placement;
-        surface_desc.dwWidth = 64;
-        surface_desc.dwHeight = 64;
+        surface_desc.dwWidth = 63;
+        surface_desc.dwHeight = 63;
         U1(surface_desc).lPitch = test_data[i].pitch_in;
         surface_desc.lpSurface = mem;
         U4(surface_desc).ddpfPixelFormat.dwSize = sizeof(U4(surface_desc).ddpfPixelFormat);
diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c
index 5a2b0a2..752f3c9 100644
--- a/dlls/ddraw/tests/ddraw7.c
+++ b/dlls/ddraw/tests/ddraw7.c
@@ -6282,7 +6282,7 @@ static void test_create_surface_pitch(void)
                                 DDSD_PITCH,                     0x100},
         {DDSCAPS_VIDEOMEMORY,   DDSD_PITCH,                     0x104,  DD_OK,
                                 DDSD_PITCH,                     0x100},
-        {DDSCAPS_VIDEOMEMORY,   DDSD_PITCH,                     0x0fc,  DD_OK,
+        {DDSCAPS_VIDEOMEMORY,   DDSD_PITCH,                     0x0f8,  DD_OK,
                                 DDSD_PITCH,                     0x100},
         {DDSCAPS_VIDEOMEMORY,   DDSD_LPSURFACE | DDSD_PITCH,    0x100,  DDERR_INVALIDCAPS,
                                 0,                              0    },
@@ -6290,15 +6290,17 @@ static void test_create_surface_pitch(void)
                                 DDSD_PITCH,                     0x100},
         {DDSCAPS_SYSTEMMEMORY,  DDSD_PITCH,                     0x104,  DD_OK,
                                 DDSD_PITCH,                     0x100},
-        {DDSCAPS_SYSTEMMEMORY,  DDSD_PITCH,                     0x0fc,  DD_OK,
+        {DDSCAPS_SYSTEMMEMORY,  DDSD_PITCH,                     0x0f8,  DD_OK,
                                 DDSD_PITCH,                     0x100},
         {DDSCAPS_SYSTEMMEMORY,  DDSD_LPSURFACE,                 0,      DDERR_INVALIDPARAMS,
                                 0,                              0    },
-        {DDSCAPS_SYSTEMMEMORY,  DDSD_LPSURFACE | DDSD_PITCH,    0x104,  DD_OK,
-                                DDSD_PITCH,                     0x104},
-        {DDSCAPS_SYSTEMMEMORY,  DDSD_LPSURFACE | DDSD_PITCH,    0x102,  DDERR_INVALIDPARAMS,
+        {DDSCAPS_SYSTEMMEMORY,  DDSD_LPSURFACE | DDSD_PITCH,    0x100,  DD_OK,
+                                DDSD_PITCH,                     0x100},
+        {DDSCAPS_SYSTEMMEMORY,  DDSD_LPSURFACE | DDSD_PITCH,    0x0fe,  DDERR_INVALIDPARAMS,
                                 0,                              0    },
-        {DDSCAPS_SYSTEMMEMORY,  DDSD_LPSURFACE | DDSD_PITCH,    0x0fc,  DDERR_INVALIDPARAMS,
+        {DDSCAPS_SYSTEMMEMORY,  DDSD_LPSURFACE | DDSD_PITCH,    0x0fc,  DD_OK,
+                                DDSD_PITCH,                     0x0fc},
+        {DDSCAPS_SYSTEMMEMORY,  DDSD_LPSURFACE | DDSD_PITCH,    0x0f8,  DDERR_INVALIDPARAMS,
                                 0,                              0    },
     };
     DWORD flags_mask = DDSD_PITCH | DDSD_LPSURFACE;
@@ -6310,7 +6312,7 @@ static void test_create_surface_pitch(void)
     hr = IDirectDraw_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
     ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
 
-    mem = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ((64 * 4) + 4) * 64);
+    mem = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ((63 * 4) + 8) * 63);
 
     for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
     {
@@ -6318,8 +6320,8 @@ static void test_create_surface_pitch(void)
         surface_desc.dwSize = sizeof(surface_desc);
         surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | test_data[i].flags_in;
         surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | test_data[i].placement;
-        surface_desc.dwWidth = 64;
-        surface_desc.dwHeight = 64;
+        surface_desc.dwWidth = 63;
+        surface_desc.dwHeight = 63;
         U1(surface_desc).lPitch = test_data[i].pitch_in;
         surface_desc.lpSurface = mem;
         U4(surface_desc).ddpfPixelFormat.dwSize = sizeof(U4(surface_desc).ddpfPixelFormat);
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 36a638d..95031f1 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -4039,6 +4039,21 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad
     return WINED3D_OK;
 }
 
+UINT CDECL wined3d_calculate_format_pitch(const struct wined3d *wined3d, UINT adapter_idx,
+        enum wined3d_format_id format_id, UINT width)
+{
+    const struct wined3d_gl_info *gl_info;
+
+    TRACE("wined3d %p, adapter_idx %u, format_id %s, width %u.\n",
+            wined3d, adapter_idx, debug_d3dformat(format_id), width);
+
+    if (adapter_idx >= wined3d->adapter_count)
+        return ~0u;
+
+    gl_info = &wined3d->adapters[adapter_idx].gl_info;
+    return wined3d_format_calculate_pitch(wined3d_get_format(gl_info, format_id), width);
+}
+
 HRESULT CDECL wined3d_check_device_format_conversion(const struct wined3d *wined3d, UINT adapter_idx,
         enum wined3d_device_type device_type, enum wined3d_format_id src_format, enum wined3d_format_id dst_format)
 {
diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec
index bdfe017..99cf6bf 100644
--- a/dlls/wined3d/wined3d.spec
+++ b/dlls/wined3d/wined3d.spec
@@ -1,6 +1,7 @@
 @ stdcall wined3d_mutex_lock()
 @ stdcall wined3d_mutex_unlock()
 
+@ cdecl wined3d_calculate_format_pitch(ptr long long long)
 @ cdecl wined3d_check_depth_stencil_match(ptr long long long long long)
 @ cdecl wined3d_check_device_format(ptr long long long long long long)
 @ cdecl wined3d_check_device_format_conversion(ptr long long long long)
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index a4b32f9..56bedce 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -2015,6 +2015,8 @@ typedef HRESULT (CDECL *wined3d_device_reset_cb)(struct wined3d_resource *resour
 void __stdcall wined3d_mutex_lock(void);
 void __stdcall wined3d_mutex_unlock(void);
 
+UINT __cdecl wined3d_calculate_format_pitch(const struct wined3d *wined3d, UINT adapter_idx,
+        enum wined3d_format_id format_id, UINT width);
 HRESULT __cdecl wined3d_check_depth_stencil_match(const struct wined3d *wined3d, UINT adapter_idx,
         enum wined3d_device_type device_type, enum wined3d_format_id adapter_format_id,
         enum wined3d_format_id render_target_format_id, enum wined3d_format_id depth_stencil_format_id);
-- 
1.7.10.4




More information about the wine-patches mailing list