[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