diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c index 57179567155..13458f632c0 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 512cae635ad..98bb10e73b3 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 0103c96f552..043653f3508 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 1d810ad6072..556d4ef756b 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 5a2b0a2425f..752f3c97caf 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 36a638dbedf..95031f1a383 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 bdfe017b670..99cf6bf03b8 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 a4b32f945a5..56bedcea842 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);