ddraw: Validate the pitch for user memory surfaces against the unaligned minimum pitch.

User memory surfaces have a different minimum alignment from regular surfaces.
This fixes a regression introduced by commit
9c138d772c.
This commit is contained in:
Henri Verbeet 2014-04-23 14:35:20 +02:00 committed by Alexandre Julliard
parent 81fb749ecf
commit ac70dd2c97
8 changed files with 52 additions and 29 deletions

View file

@ -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;

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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)
{

View file

@ -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)

View file

@ -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);