Resend of 7428 with rewritten tests and a few minor formatting tweaks.
From: Yuri Hérouard yuri.herouard@gmail.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57283 --- dlls/wined3d/surface.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+)
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index 14cfebd7074..067b3afc30e 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -609,6 +609,7 @@ static HRESULT surface_cpu_blt(struct wined3d_texture *dst_texture, unsigned int struct wined3d_context *context; struct wined3d_range dst_range; unsigned int texture_level; + BYTE *tmp_buffer = NULL; HRESULT hr = WINED3D_OK; BOOL same_sub_resource; BOOL upload = FALSE; @@ -808,18 +809,43 @@ static HRESULT surface_cpu_blt(struct wined3d_texture *dst_texture, unsigned int else { /* Stretching in y direction only. */ + + if (same_sub_resource) + { + /* Use a temporary buffer if blitting a surface to itself. */ + if ((tmp_buffer = malloc(src_height * src_map.row_pitch))) + { + memcpy(tmp_buffer, sbase, src_height * src_map.row_pitch); + sbase = tmp_buffer; + } + } + for (y = sy = 0; y < dst_height; ++y, sy += yinc) { sbuf = sbase + (sy >> 16) * src_map.row_pitch; memcpy(dbuf, sbuf, row_byte_count); dbuf += dst_map.row_pitch; } + + if (same_sub_resource) + free(tmp_buffer); } } else { /* Stretching in X direction. */ unsigned int last_sy = ~0u; + + if (same_sub_resource) + { + /* Use a temporary buffer if blitting a surface to itself. */ + if ((tmp_buffer = malloc(src_height * src_map.row_pitch))) + { + memcpy(tmp_buffer, sbase, src_height * src_map.row_pitch); + sbase = tmp_buffer; + } + } + for (y = sy = 0; y < dst_height; ++y, sy += yinc) { sbuf = sbase + (sy >> 16) * src_map.row_pitch; @@ -878,6 +904,9 @@ do { \ dbuf += dst_map.row_pitch; last_sy = sy; } + + if (same_sub_resource) + free(tmp_buffer); } } else
From: Elizabeth Figura zfigura@codeweavers.com
--- dlls/ddraw/tests/ddraw1.c | 99 +++++++++++++++++++++++++++++++++++++++ dlls/ddraw/tests/ddraw2.c | 99 +++++++++++++++++++++++++++++++++++++++ dlls/ddraw/tests/ddraw4.c | 99 +++++++++++++++++++++++++++++++++++++++ dlls/ddraw/tests/ddraw7.c | 99 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 396 insertions(+)
diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c index e62d9283aaa..5b482459d3e 100644 --- a/dlls/ddraw/tests/ddraw1.c +++ b/dlls/ddraw/tests/ddraw1.c @@ -16119,6 +16119,104 @@ static void test_yuv_blit(void) DestroyWindow(window); }
+static void test_blit_to_self(void) +{ + DDSURFACEDESC surface_desc = {sizeof(surface_desc)}; + const unsigned int width = 64, height = 64; + IDirectDrawSurface *surface; + unsigned int refcount; + IDirectDraw *ddraw; + HWND window; + HRESULT hr; + + struct + { + RECT src, dst; + } + tests[] = + { + {{16, 16, 24, 24}, {18, 18, 26, 26}}, + {{16, 16, 24, 24}, {14, 14, 22, 22}}, + {{16, 16, 24, 24}, {12, 12, 28, 28}}, + {{16, 16, 24, 24}, {18, 18, 22, 22}}, + }; + + window = create_window(); + ddraw = create_ddraw(); + hr = IDirectDraw_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + surface_desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT; + surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; + surface_desc.dwWidth = width; + surface_desc.dwHeight = height; + init_format_b8g8r8x8(&surface_desc.ddpfPixelFormat); + + hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &surface, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + for (unsigned int i = 0; i < ARRAY_SIZE(tests); ++i) + { + hr = IDirectDrawSurface_Lock(surface, NULL, &surface_desc, DDLOCK_WAIT, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + for (unsigned int y = 0; y < height; ++y) + { + for (unsigned int x = 0; x < width; ++x) + ((unsigned int *)surface_desc.lpSurface)[y * width + x] = (y << 8) | x; + } + hr = IDirectDrawSurface_Unlock(surface, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + hr = IDirectDrawSurface_Blt(surface, &tests[i].dst, surface, &tests[i].src, DDBLT_WAIT, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + hr = IDirectDrawSurface_Lock(surface, NULL, &surface_desc, DDLOCK_WAIT | DDLOCK_READONLY, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + for (unsigned int y = 0; y < height; ++y) + { + for (unsigned int x = 0; x < width; ++x) + { + unsigned int colour = ((unsigned int *)surface_desc.lpSurface)[y * width + x]; + + if (x >= tests[i].dst.left && x < tests[i].dst.right + && y >= tests[i].dst.top && y < tests[i].dst.bottom) + { + unsigned int src_x = (x - tests[i].dst.left) + * (tests[i].src.right - tests[i].src.left) + / (tests[i].dst.right - tests[i].dst.left) + + tests[i].src.left; + unsigned int src_y = (y - tests[i].dst.top) + * (tests[i].src.bottom - tests[i].src.top) + / (tests[i].dst.bottom - tests[i].dst.top) + + tests[i].src.top; + if (colour != ((src_y << 8) | src_x)) + { + ok(0, "Got colour 0x%08x at (%u, %u), expected 0x%08x.\n", + colour, x, y, ((src_y << 8) | src_x)); + goto out; + } + } + else + { + if (colour != ((y << 8) | x)) + { + ok(0, "Got colour 0x%08x at (%u, %u).\n", colour, x, y); + goto out; + } + } + } + } +out: + hr = IDirectDrawSurface_Unlock(surface, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + } + + IDirectDrawSurface_Release(surface); + refcount = IDirectDraw_Release(ddraw); + ok(!refcount, "Device has %u references left.\n", refcount); + DestroyWindow(window); +} + START_TEST(ddraw1) { DDDEVICEIDENTIFIER identifier; @@ -16242,4 +16340,5 @@ START_TEST(ddraw1) test_multiple_devices(); test_sysmem_x_channel(); test_yuv_blit(); + test_blit_to_self(); } diff --git a/dlls/ddraw/tests/ddraw2.c b/dlls/ddraw/tests/ddraw2.c index 0f11b27c130..d7daa4e989d 100644 --- a/dlls/ddraw/tests/ddraw2.c +++ b/dlls/ddraw/tests/ddraw2.c @@ -17151,6 +17151,104 @@ static void test_yuv_blit(void) DestroyWindow(window); }
+static void test_blit_to_self(void) +{ + DDSURFACEDESC surface_desc = {sizeof(surface_desc)}; + const unsigned int width = 64, height = 64; + IDirectDrawSurface *surface; + unsigned int refcount; + IDirectDraw2 *ddraw; + HWND window; + HRESULT hr; + + struct + { + RECT src, dst; + } + tests[] = + { + {{16, 16, 24, 24}, {18, 18, 26, 26}}, + {{16, 16, 24, 24}, {14, 14, 22, 22}}, + {{16, 16, 24, 24}, {12, 12, 28, 28}}, + {{16, 16, 24, 24}, {18, 18, 22, 22}}, + }; + + window = create_window(); + ddraw = create_ddraw(); + hr = IDirectDraw2_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + surface_desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT; + surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; + surface_desc.dwWidth = width; + surface_desc.dwHeight = height; + init_format_b8g8r8x8(&surface_desc.ddpfPixelFormat); + + hr = IDirectDraw2_CreateSurface(ddraw, &surface_desc, &surface, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + for (unsigned int i = 0; i < ARRAY_SIZE(tests); ++i) + { + hr = IDirectDrawSurface_Lock(surface, NULL, &surface_desc, DDLOCK_WAIT, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + for (unsigned int y = 0; y < height; ++y) + { + for (unsigned int x = 0; x < width; ++x) + ((unsigned int *)surface_desc.lpSurface)[y * width + x] = (y << 8) | x; + } + hr = IDirectDrawSurface_Unlock(surface, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + hr = IDirectDrawSurface_Blt(surface, &tests[i].dst, surface, &tests[i].src, DDBLT_WAIT, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + hr = IDirectDrawSurface_Lock(surface, NULL, &surface_desc, DDLOCK_WAIT | DDLOCK_READONLY, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + for (unsigned int y = 0; y < height; ++y) + { + for (unsigned int x = 0; x < width; ++x) + { + unsigned int colour = ((unsigned int *)surface_desc.lpSurface)[y * width + x]; + + if (x >= tests[i].dst.left && x < tests[i].dst.right + && y >= tests[i].dst.top && y < tests[i].dst.bottom) + { + unsigned int src_x = (x - tests[i].dst.left) + * (tests[i].src.right - tests[i].src.left) + / (tests[i].dst.right - tests[i].dst.left) + + tests[i].src.left; + unsigned int src_y = (y - tests[i].dst.top) + * (tests[i].src.bottom - tests[i].src.top) + / (tests[i].dst.bottom - tests[i].dst.top) + + tests[i].src.top; + if (colour != ((src_y << 8) | src_x)) + { + ok(0, "Got colour 0x%08x at (%u, %u), expected 0x%08x.\n", + colour, x, y, ((src_y << 8) | src_x)); + goto out; + } + } + else + { + if (colour != ((y << 8) | x)) + { + ok(0, "Got colour 0x%08x at (%u, %u).\n", colour, x, y); + goto out; + } + } + } + } +out: + hr = IDirectDrawSurface_Unlock(surface, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + } + + IDirectDrawSurface_Release(surface); + refcount = IDirectDraw2_Release(ddraw); + ok(!refcount, "Device has %u references left.\n", refcount); + DestroyWindow(window); +} + START_TEST(ddraw2) { DDDEVICEIDENTIFIER identifier; @@ -17280,4 +17378,5 @@ START_TEST(ddraw2) test_d3d_state_reset(); test_sysmem_x_channel(); test_yuv_blit(); + test_blit_to_self(); } diff --git a/dlls/ddraw/tests/ddraw4.c b/dlls/ddraw/tests/ddraw4.c index 4571a5426bb..8345b6b3434 100644 --- a/dlls/ddraw/tests/ddraw4.c +++ b/dlls/ddraw/tests/ddraw4.c @@ -20224,6 +20224,104 @@ static void test_yuv_blit(void) DestroyWindow(window); }
+static void test_blit_to_self(void) +{ + DDSURFACEDESC2 surface_desc = {sizeof(surface_desc)}; + const unsigned int width = 64, height = 64; + IDirectDrawSurface4 *surface; + unsigned int refcount; + IDirectDraw4 *ddraw; + HWND window; + HRESULT hr; + + struct + { + RECT src, dst; + } + tests[] = + { + {{16, 16, 24, 24}, {18, 18, 26, 26}}, + {{16, 16, 24, 24}, {14, 14, 22, 22}}, + {{16, 16, 24, 24}, {12, 12, 28, 28}}, + {{16, 16, 24, 24}, {18, 18, 22, 22}}, + }; + + window = create_window(); + ddraw = create_ddraw(); + hr = IDirectDraw4_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + surface_desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT; + surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; + surface_desc.dwWidth = width; + surface_desc.dwHeight = height; + init_format_b8g8r8x8(&surface_desc.ddpfPixelFormat); + + hr = IDirectDraw4_CreateSurface(ddraw, &surface_desc, &surface, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + for (unsigned int i = 0; i < ARRAY_SIZE(tests); ++i) + { + hr = IDirectDrawSurface4_Lock(surface, NULL, &surface_desc, DDLOCK_WAIT, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + for (unsigned int y = 0; y < height; ++y) + { + for (unsigned int x = 0; x < width; ++x) + ((unsigned int *)surface_desc.lpSurface)[y * width + x] = (y << 8) | x; + } + hr = IDirectDrawSurface4_Unlock(surface, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + hr = IDirectDrawSurface4_Blt(surface, &tests[i].dst, surface, &tests[i].src, DDBLT_WAIT, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + hr = IDirectDrawSurface4_Lock(surface, NULL, &surface_desc, DDLOCK_WAIT | DDLOCK_READONLY, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + for (unsigned int y = 0; y < height; ++y) + { + for (unsigned int x = 0; x < width; ++x) + { + unsigned int colour = ((unsigned int *)surface_desc.lpSurface)[y * width + x]; + + if (x >= tests[i].dst.left && x < tests[i].dst.right + && y >= tests[i].dst.top && y < tests[i].dst.bottom) + { + unsigned int src_x = (x - tests[i].dst.left) + * (tests[i].src.right - tests[i].src.left) + / (tests[i].dst.right - tests[i].dst.left) + + tests[i].src.left; + unsigned int src_y = (y - tests[i].dst.top) + * (tests[i].src.bottom - tests[i].src.top) + / (tests[i].dst.bottom - tests[i].dst.top) + + tests[i].src.top; + if (colour != ((src_y << 8) | src_x)) + { + ok(0, "Got colour 0x%08x at (%u, %u), expected 0x%08x.\n", + colour, x, y, ((src_y << 8) | src_x)); + goto out; + } + } + else + { + if (colour != ((y << 8) | x)) + { + ok(0, "Got colour 0x%08x at (%u, %u).\n", colour, x, y); + goto out; + } + } + } + } +out: + hr = IDirectDrawSurface4_Unlock(surface, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + } + + IDirectDrawSurface4_Release(surface); + refcount = IDirectDraw4_Release(ddraw); + ok(!refcount, "Device has %u references left.\n", refcount); + DestroyWindow(window); +} + START_TEST(ddraw4) { DDDEVICEIDENTIFIER identifier; @@ -20370,4 +20468,5 @@ START_TEST(ddraw4) test_d3d_state_reset(); test_sysmem_x_channel(); test_yuv_blit(); + test_blit_to_self(); } diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c index d4980250a8c..aebca7727b9 100644 --- a/dlls/ddraw/tests/ddraw7.c +++ b/dlls/ddraw/tests/ddraw7.c @@ -20659,6 +20659,104 @@ static void test_yuv_blit(void) DestroyWindow(window); }
+static void test_blit_to_self(void) +{ + DDSURFACEDESC2 surface_desc = {sizeof(surface_desc)}; + const unsigned int width = 64, height = 64; + IDirectDrawSurface7 *surface; + unsigned int refcount; + IDirectDraw7 *ddraw; + HWND window; + HRESULT hr; + + struct + { + RECT src, dst; + } + tests[] = + { + {{16, 16, 24, 24}, {18, 18, 26, 26}}, + {{16, 16, 24, 24}, {14, 14, 22, 22}}, + {{16, 16, 24, 24}, {12, 12, 28, 28}}, + {{16, 16, 24, 24}, {18, 18, 22, 22}}, + }; + + window = create_window(); + ddraw = create_ddraw(); + hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + surface_desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT; + surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; + surface_desc.dwWidth = width; + surface_desc.dwHeight = height; + init_format_b8g8r8x8(&surface_desc.ddpfPixelFormat); + + hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &surface, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + for (unsigned int i = 0; i < ARRAY_SIZE(tests); ++i) + { + hr = IDirectDrawSurface7_Lock(surface, NULL, &surface_desc, DDLOCK_WAIT, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + for (unsigned int y = 0; y < height; ++y) + { + for (unsigned int x = 0; x < width; ++x) + ((unsigned int *)surface_desc.lpSurface)[y * width + x] = (y << 8) | x; + } + hr = IDirectDrawSurface7_Unlock(surface, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + hr = IDirectDrawSurface7_Blt(surface, &tests[i].dst, surface, &tests[i].src, DDBLT_WAIT, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + hr = IDirectDrawSurface7_Lock(surface, NULL, &surface_desc, DDLOCK_WAIT | DDLOCK_READONLY, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + for (unsigned int y = 0; y < height; ++y) + { + for (unsigned int x = 0; x < width; ++x) + { + unsigned int colour = ((unsigned int *)surface_desc.lpSurface)[y * width + x]; + + if (x >= tests[i].dst.left && x < tests[i].dst.right + && y >= tests[i].dst.top && y < tests[i].dst.bottom) + { + unsigned int src_x = (x - tests[i].dst.left) + * (tests[i].src.right - tests[i].src.left) + / (tests[i].dst.right - tests[i].dst.left) + + tests[i].src.left; + unsigned int src_y = (y - tests[i].dst.top) + * (tests[i].src.bottom - tests[i].src.top) + / (tests[i].dst.bottom - tests[i].dst.top) + + tests[i].src.top; + if (colour != ((src_y << 8) | src_x)) + { + ok(0, "Got colour 0x%08x at (%u, %u), expected 0x%08x.\n", + colour, x, y, ((src_y << 8) | src_x)); + goto out; + } + } + else + { + if (colour != ((y << 8) | x)) + { + ok(0, "Got colour 0x%08x at (%u, %u).\n", colour, x, y); + goto out; + } + } + } + } +out: + hr = IDirectDrawSurface7_Unlock(surface, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + } + + IDirectDrawSurface7_Release(surface); + refcount = IDirectDraw7_Release(ddraw); + ok(!refcount, "Device has %u references left.\n", refcount); + DestroyWindow(window); +} + START_TEST(ddraw7) { DDDEVICEIDENTIFIER2 identifier; @@ -20839,4 +20937,5 @@ START_TEST(ddraw7) test_d3d_state_reset(); test_sysmem_x_channel(); test_yuv_blit(); + test_blit_to_self(); }
This merge request was approved by Elizabeth Figura.
This merge request was approved by Jan Sikorski.