-- v2: ddraw: Clear sysmem textures on the CPU.
From: Elizabeth Figura zfigura@codeweavers.com
--- dlls/ddraw/tests/ddraw1.c | 52 +++++++++++++++++++++++++++++++++++++++ dlls/ddraw/tests/ddraw2.c | 52 +++++++++++++++++++++++++++++++++++++++ dlls/ddraw/tests/ddraw4.c | 52 +++++++++++++++++++++++++++++++++++++++ dlls/ddraw/tests/ddraw7.c | 42 +++++++++++++++++++++++++++++++ 4 files changed, 198 insertions(+)
diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c index 167ef8a3dc4..060e65a0faa 100644 --- a/dlls/ddraw/tests/ddraw1.c +++ b/dlls/ddraw/tests/ddraw1.c @@ -1413,6 +1413,16 @@ static void init_format_b5g6r5(DDPIXELFORMAT *format) format->dwBBitMask = 0x001f; }
+static void init_format_b8g8r8x8(DDPIXELFORMAT *format) +{ + format->dwSize = sizeof(*format); + format->dwFlags = DDPF_RGB; + format->dwRGBBitCount = 32; + format->dwRBitMask = 0x00ff0000; + format->dwGBitMask = 0x0000ff00; + format->dwBBitMask = 0x000000ff; +} + static ULONG get_refcount(IUnknown *test_iface) { IUnknown_AddRef(test_iface); @@ -15703,6 +15713,47 @@ static void test_multiple_devices(void) DestroyWindow(window); }
+/* The Egyptian Prophecy: The Fate of Ramses does this. */ +static void test_sysmem_x_channel(void) +{ + DDSURFACEDESC surface_desc = {sizeof(surface_desc)}; + DDBLTFX fx = {.dwSize = sizeof(fx)}; + unsigned int colour, refcount; + IDirectDrawSurface *surface; + IDirectDraw *ddraw; + HWND window; + HRESULT hr; + + 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_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; + surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; + surface_desc.dwWidth = 32; + surface_desc.dwHeight = 32; + init_format_b8g8r8x8(&surface_desc.ddpfPixelFormat); + hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &surface, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + fx.dwFillColor = 0x0000ff00; + hr = IDirectDrawSurface_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + hr = IDirectDrawSurface_Lock(surface, NULL, &surface_desc, DDLOCK_READONLY, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + colour = *(unsigned int *)surface_desc.lpSurface; + todo_wine ok(colour == 0x0000ff00, "Got colour %08x.\n", colour); + 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; @@ -15824,4 +15875,5 @@ START_TEST(ddraw1) test_enum_devices(); test_pinned_sysmem(); test_multiple_devices(); + test_sysmem_x_channel(); } diff --git a/dlls/ddraw/tests/ddraw2.c b/dlls/ddraw/tests/ddraw2.c index de4778e8d24..c0d4f98daeb 100644 --- a/dlls/ddraw/tests/ddraw2.c +++ b/dlls/ddraw/tests/ddraw2.c @@ -1596,6 +1596,16 @@ static BOOL compare_mode_rect(const DEVMODEW *mode1, const DEVMODEW *mode2) && mode1->dmPelsHeight == mode2->dmPelsHeight; }
+static void init_format_b8g8r8x8(DDPIXELFORMAT *format) +{ + format->dwSize = sizeof(*format); + format->dwFlags = DDPF_RGB; + format->dwRGBBitCount = 32; + format->dwRBitMask = 0x00ff0000; + format->dwGBitMask = 0x0000ff00; + format->dwBBitMask = 0x000000ff; +} + static ULONG get_refcount(IUnknown *test_iface) { IUnknown_AddRef(test_iface); @@ -16763,6 +16773,47 @@ static void test_d3d_state_reset(void) DestroyWindow(window); }
+/* The Egyptian Prophecy: The Fate of Ramses does this. */ +static void test_sysmem_x_channel(void) +{ + DDSURFACEDESC surface_desc = {sizeof(surface_desc)}; + DDBLTFX fx = {.dwSize = sizeof(fx)}; + unsigned int colour, refcount; + IDirectDrawSurface *surface; + IDirectDraw2 *ddraw; + HWND window; + HRESULT hr; + + 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_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; + surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; + surface_desc.dwWidth = 32; + surface_desc.dwHeight = 32; + init_format_b8g8r8x8(&surface_desc.ddpfPixelFormat); + hr = IDirectDraw2_CreateSurface(ddraw, &surface_desc, &surface, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + fx.dwFillColor = 0x0000ff00; + hr = IDirectDrawSurface_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + hr = IDirectDrawSurface_Lock(surface, NULL, &surface_desc, DDLOCK_READONLY, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + colour = *(unsigned int *)surface_desc.lpSurface; + todo_wine ok(colour == 0x0000ff00, "Got colour %08x.\n", colour); + 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; @@ -16890,4 +16941,5 @@ START_TEST(ddraw2) test_enum_devices(); test_multiple_devices(); test_d3d_state_reset(); + test_sysmem_x_channel(); } diff --git a/dlls/ddraw/tests/ddraw4.c b/dlls/ddraw/tests/ddraw4.c index 96bdbf37183..a8c4f3ab621 100644 --- a/dlls/ddraw/tests/ddraw4.c +++ b/dlls/ddraw/tests/ddraw4.c @@ -1767,6 +1767,16 @@ static BOOL compare_mode_rect(const DEVMODEW *mode1, const DEVMODEW *mode2) && mode1->dmPelsHeight == mode2->dmPelsHeight; }
+static void init_format_b8g8r8x8(DDPIXELFORMAT *format) +{ + format->dwSize = sizeof(*format); + format->dwFlags = DDPF_RGB; + format->dwRGBBitCount = 32; + format->dwRBitMask = 0x00ff0000; + format->dwGBitMask = 0x0000ff00; + format->dwBBitMask = 0x000000ff; +} + static ULONG get_refcount(IUnknown *test_iface) { IUnknown_AddRef(test_iface); @@ -19838,6 +19848,47 @@ static void test_d3d_state_reset(void) DestroyWindow(window); }
+/* The Egyptian Prophecy: The Fate of Ramses does this. */ +static void test_sysmem_x_channel(void) +{ + DDSURFACEDESC2 surface_desc = {sizeof(surface_desc)}; + DDBLTFX fx = {.dwSize = sizeof(fx)}; + unsigned int colour, refcount; + IDirectDrawSurface4 *surface; + IDirectDraw4 *ddraw; + HWND window; + HRESULT hr; + + 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_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; + surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; + surface_desc.dwWidth = 32; + surface_desc.dwHeight = 32; + init_format_b8g8r8x8(&surface_desc.ddpfPixelFormat); + hr = IDirectDraw4_CreateSurface(ddraw, &surface_desc, &surface, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + fx.dwFillColor = 0x0000ff00; + hr = IDirectDrawSurface4_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + hr = IDirectDrawSurface4_Lock(surface, NULL, &surface_desc, DDLOCK_READONLY, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + colour = *(unsigned int *)surface_desc.lpSurface; + todo_wine ok(colour == 0x0000ff00, "Got colour %08x.\n", colour); + 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; @@ -19982,4 +20033,5 @@ START_TEST(ddraw4) test_multiple_devices(); test_vb_desc(); test_d3d_state_reset(); + test_sysmem_x_channel(); } diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c index 343ca652214..9c7be81636f 100644 --- a/dlls/ddraw/tests/ddraw7.c +++ b/dlls/ddraw/tests/ddraw7.c @@ -20284,6 +20284,47 @@ static void test_d3d_state_reset(void) DestroyWindow(window); }
+/* The Egyptian Prophecy: The Fate of Ramses does this. */ +static void test_sysmem_x_channel(void) +{ + DDSURFACEDESC2 surface_desc = {sizeof(surface_desc)}; + DDBLTFX fx = {.dwSize = sizeof(fx)}; + unsigned int colour, refcount; + IDirectDrawSurface7 *surface; + IDirectDraw7 *ddraw; + HWND window; + HRESULT hr; + + 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_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; + surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; + surface_desc.dwWidth = 32; + surface_desc.dwHeight = 32; + init_format_b8g8r8x8(&surface_desc.ddpfPixelFormat); + hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &surface, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + fx.dwFillColor = 0x0000ff00; + hr = IDirectDrawSurface7_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + hr = IDirectDrawSurface7_Lock(surface, NULL, &surface_desc, DDLOCK_READONLY, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + colour = *(unsigned int *)surface_desc.lpSurface; + todo_wine ok(colour == 0x0000ff00, "Got colour %08x.\n", colour); + 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; @@ -20462,4 +20503,5 @@ START_TEST(ddraw7) test_multiple_devices(); test_vb_desc(); test_d3d_state_reset(); + test_sysmem_x_channel(); }
From: Elizabeth Figura zfigura@codeweavers.com
--- dlls/wined3d/surface.c | 59 +++++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 27 deletions(-)
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index 9620b054e5a..028dc4e94b2 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -1125,12 +1125,11 @@ release: return hr; }
-static void surface_cpu_blt_colour_fill(struct wined3d_rendertarget_view *view, +static void cpu_blitter_clear_texture(struct wined3d_texture *texture, unsigned int sub_resource_idx, const struct wined3d_box *box, const struct wined3d_color *colour) { - struct wined3d_device *device = view->resource->device; + struct wined3d_device *device = texture->resource.device; struct wined3d_context *context; - struct wined3d_texture *texture; struct wined3d_bo_address data; struct wined3d_box level_box; struct wined3d_map_desc map; @@ -1139,48 +1138,54 @@ static void surface_cpu_blt_colour_fill(struct wined3d_rendertarget_view *view, unsigned int level; DWORD map_binding;
- TRACE("view %p, box %s, colour %s.\n", view, debug_box(box), debug_color(colour)); + TRACE("texture %p, sub_resource_idx %u, box %s, colour %s.\n", + texture, sub_resource_idx, debug_box(box), debug_color(colour));
- if (view->format_attrs & WINED3D_FORMAT_ATTR_BLOCKS) + if (texture->resource.format_attrs & WINED3D_FORMAT_ATTR_BLOCKS) { - FIXME("Not implemented for format %s.\n", debug_d3dformat(view->format->id)); - return; - } - - if (view->format->id != view->resource->format->id) - FIXME("View format %s doesn't match resource format %s.\n", - debug_d3dformat(view->format->id), debug_d3dformat(view->resource->format->id)); - - if (view->resource->type == WINED3D_RTYPE_BUFFER) - { - FIXME("Not implemented for buffers.\n"); + FIXME("Not implemented for format %s.\n", debug_d3dformat(texture->resource.format->id)); return; }
context = context_acquire(device, NULL, 0);
- texture = texture_from_resource(view->resource); - level = view->sub_resource_idx % texture->level_count; - wined3d_texture_get_level_box(texture_from_resource(view->resource), level, &level_box); + level = sub_resource_idx % texture->level_count; + wined3d_texture_get_level_box(texture, level, &level_box); full_subresource = !memcmp(box, &level_box, sizeof(*box));
map_binding = texture->resource.map_binding; - if (!wined3d_texture_load_location(texture, view->sub_resource_idx, context, map_binding)) + if (!wined3d_texture_load_location(texture, sub_resource_idx, context, map_binding)) ERR("Failed to load the sub-resource into %s.\n", wined3d_debug_location(map_binding)); - wined3d_texture_invalidate_location(texture, view->sub_resource_idx, ~map_binding); + wined3d_texture_invalidate_location(texture, sub_resource_idx, ~map_binding); wined3d_texture_get_pitch(texture, level, &map.row_pitch, &map.slice_pitch); - wined3d_texture_get_bo_address(texture, view->sub_resource_idx, &data, map_binding); + wined3d_texture_get_bo_address(texture, sub_resource_idx, &data, map_binding); map.data = wined3d_context_map_bo_address(context, &data, - texture->sub_resources[view->sub_resource_idx].size, WINED3D_MAP_WRITE); + texture->sub_resources[sub_resource_idx].size, WINED3D_MAP_WRITE); range.offset = 0; - range.size = texture->sub_resources[view->sub_resource_idx].size; + range.size = texture->sub_resources[sub_resource_idx].size;
- wined3d_resource_memory_colour_fill(view->resource, &map, colour, box, full_subresource); + wined3d_resource_memory_colour_fill(&texture->resource, &map, colour, box, full_subresource);
wined3d_context_unmap_bo_address(context, &data, 1, &range); context_release(context); }
+static void cpu_blitter_clear_rtv(struct wined3d_rendertarget_view *view, + const struct wined3d_box *box, const struct wined3d_color *colour) +{ + if (view->format->id != view->resource->format->id) + FIXME("View format %s doesn't match resource format %s.\n", + debug_d3dformat(view->format->id), debug_d3dformat(view->resource->format->id)); + + if (view->resource->type == WINED3D_RTYPE_BUFFER) + { + FIXME("Not implemented for buffers.\n"); + return; + } + + cpu_blitter_clear_texture(texture_from_resource(view->resource), view->sub_resource_idx, box, colour); +} + static bool wined3d_box_intersect(struct wined3d_box *ret, const struct wined3d_box *b1, const struct wined3d_box *b2) { @@ -1225,7 +1230,7 @@ static void cpu_blitter_clear(struct wined3d_blitter *blitter, struct wined3d_de { wined3d_rendertarget_view_get_box(view, &box_view); if (wined3d_box_intersect(&box_clip, &box_view, &box)) - surface_cpu_blt_colour_fill(view, &box_clip, colour); + cpu_blitter_clear_rtv(view, &box_clip, colour); } } } @@ -1238,7 +1243,7 @@ static void cpu_blitter_clear(struct wined3d_blitter *blitter, struct wined3d_de
wined3d_rendertarget_view_get_box(view, &box_view); if (wined3d_box_intersect(&box_clip, &box_view, &box)) - surface_cpu_blt_colour_fill(view, &box_clip, &c); + cpu_blitter_clear_rtv(view, &box_clip, &c); } } }
From: Elizabeth Figura zfigura@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56205 --- dlls/ddraw/surface.c | 41 ++++----------- dlls/ddraw/tests/ddraw1.c | 2 +- dlls/ddraw/tests/ddraw2.c | 2 +- dlls/ddraw/tests/ddraw4.c | 2 +- dlls/ddraw/tests/ddraw7.c | 2 +- dlls/wined3d/cs.c | 92 ++++++++++++++++++++++++++++++++++ dlls/wined3d/surface.c | 2 +- dlls/wined3d/wined3d.spec | 1 + dlls/wined3d/wined3d_private.h | 3 ++ include/wine/wined3d.h | 3 ++ 10 files changed, 113 insertions(+), 37 deletions(-)
diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c index 8cdaa48b753..565c38b4887 100644 --- a/dlls/ddraw/surface.c +++ b/dlls/ddraw/surface.c @@ -1531,33 +1531,6 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface2_Flip(IDirectDrawSurface2 src_impl ? &src_impl->IDirectDrawSurface_iface : NULL, flags); }
-/* Emperor: Rise of the Middle Kingdom accesses the map pointer outside of - * Lock()/Unlock(), and expects those updates to be propagated by a Blt(). - * It also blits to the surface, and color-fills it. - * - * This function is called after a color-fill that might update the GPU side. - * We need to make sure the sysmem surface is synchronized. */ -static void ddraw_surface_sync_pinned_sysmem(struct ddraw_surface *surface) -{ - RECT rect; - - if (!surface->draw_texture) - return; - - if (!(surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY)) - return; - - SetRect(&rect, 0, 0, surface->surface_desc.dwWidth, surface->surface_desc.dwHeight); - wined3d_device_context_blt(surface->ddraw->immediate_context, - surface->wined3d_texture, surface->sub_resource_idx, &rect, - surface->draw_texture, surface->sub_resource_idx, &rect, - WINED3D_BLT_SYNCHRONOUS, NULL, WINED3D_TEXF_POINT); - - /* The sysmem surface may be updated at any time, so we must invalidate the - * draw texture location here. */ - surface->texture_location = DDRAW_SURFACE_LOCATION_DEFAULT; -} - static HRESULT ddraw_surface_blt(struct ddraw_surface *dst_surface, const RECT *dst_rect, struct ddraw_surface *src_surface, const RECT *src_rect, DWORD flags, DWORD fill_colour, const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter) @@ -1565,10 +1538,11 @@ static HRESULT ddraw_surface_blt(struct ddraw_surface *dst_surface, const RECT * struct ddraw *ddraw = dst_surface->ddraw; struct wined3d_color colour; DWORD wined3d_flags; - HRESULT hr;
if (flags & DDBLT_COLORFILL) { + unsigned int location_flags = dst_rect ? DDRAW_SURFACE_RW : DDRAW_SURFACE_WRITE; + wined3d_flags = WINED3DCLEAR_TARGET; if (!(flags & DDBLT_ASYNC)) wined3d_flags |= WINED3DCLEAR_SYNCHRONOUS; @@ -1577,12 +1551,15 @@ static HRESULT ddraw_surface_blt(struct ddraw_surface *dst_surface, const RECT * dst_surface->palette, fill_colour, &colour)) return DDERR_INVALIDPARAMS;
- ddraw_surface_get_draw_texture(dst_surface, dst_rect ? DDRAW_SURFACE_RW : DDRAW_SURFACE_WRITE); - hr = wined3d_device_context_clear_rendertarget_view(ddraw->immediate_context, + if (dst_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) + return wined3d_device_context_clear_sysmem_texture(ddraw->immediate_context, + ddraw_surface_get_default_texture(dst_surface, location_flags), + dst_surface->sub_resource_idx, dst_rect, wined3d_flags, &colour); + + ddraw_surface_get_draw_texture(dst_surface, location_flags); + return wined3d_device_context_clear_rendertarget_view(ddraw->immediate_context, ddraw_surface_get_rendertarget_view(dst_surface), dst_rect, wined3d_flags, &colour, 0.0f, 0); - ddraw_surface_sync_pinned_sysmem(dst_surface); - return hr; }
if (flags & DDBLT_DEPTHFILL) diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c index 060e65a0faa..6cafd6bb762 100644 --- a/dlls/ddraw/tests/ddraw1.c +++ b/dlls/ddraw/tests/ddraw1.c @@ -15744,7 +15744,7 @@ static void test_sysmem_x_channel(void) hr = IDirectDrawSurface_Lock(surface, NULL, &surface_desc, DDLOCK_READONLY, NULL); ok(hr == S_OK, "Got hr %#lx.\n", hr); colour = *(unsigned int *)surface_desc.lpSurface; - todo_wine ok(colour == 0x0000ff00, "Got colour %08x.\n", colour); + ok(colour == 0x0000ff00, "Got colour %08x.\n", colour); hr = IDirectDrawSurface_Unlock(surface, NULL); ok(hr == S_OK, "Got hr %#lx.\n", hr);
diff --git a/dlls/ddraw/tests/ddraw2.c b/dlls/ddraw/tests/ddraw2.c index c0d4f98daeb..bc7602c85ac 100644 --- a/dlls/ddraw/tests/ddraw2.c +++ b/dlls/ddraw/tests/ddraw2.c @@ -16804,7 +16804,7 @@ static void test_sysmem_x_channel(void) hr = IDirectDrawSurface_Lock(surface, NULL, &surface_desc, DDLOCK_READONLY, NULL); ok(hr == S_OK, "Got hr %#lx.\n", hr); colour = *(unsigned int *)surface_desc.lpSurface; - todo_wine ok(colour == 0x0000ff00, "Got colour %08x.\n", colour); + ok(colour == 0x0000ff00, "Got colour %08x.\n", colour); hr = IDirectDrawSurface_Unlock(surface, NULL); ok(hr == S_OK, "Got hr %#lx.\n", hr);
diff --git a/dlls/ddraw/tests/ddraw4.c b/dlls/ddraw/tests/ddraw4.c index a8c4f3ab621..7184215b962 100644 --- a/dlls/ddraw/tests/ddraw4.c +++ b/dlls/ddraw/tests/ddraw4.c @@ -19879,7 +19879,7 @@ static void test_sysmem_x_channel(void) hr = IDirectDrawSurface4_Lock(surface, NULL, &surface_desc, DDLOCK_READONLY, NULL); ok(hr == S_OK, "Got hr %#lx.\n", hr); colour = *(unsigned int *)surface_desc.lpSurface; - todo_wine ok(colour == 0x0000ff00, "Got colour %08x.\n", colour); + ok(colour == 0x0000ff00, "Got colour %08x.\n", colour); hr = IDirectDrawSurface4_Unlock(surface, NULL); ok(hr == S_OK, "Got hr %#lx.\n", hr);
diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c index 9c7be81636f..81b053b1d70 100644 --- a/dlls/ddraw/tests/ddraw7.c +++ b/dlls/ddraw/tests/ddraw7.c @@ -20315,7 +20315,7 @@ static void test_sysmem_x_channel(void) hr = IDirectDrawSurface7_Lock(surface, NULL, &surface_desc, DDLOCK_READONLY, NULL); ok(hr == S_OK, "Got hr %#lx.\n", hr); colour = *(unsigned int *)surface_desc.lpSurface; - todo_wine ok(colour == 0x0000ff00, "Got colour %08x.\n", colour); + ok(colour == 0x0000ff00, "Got colour %08x.\n", colour); hr = IDirectDrawSurface7_Unlock(surface, NULL); ok(hr == S_OK, "Got hr %#lx.\n", hr);
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index 1bd4e2b4242..da903e39488 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -136,6 +136,7 @@ enum wined3d_cs_op WINED3D_CS_OP_BLT_SUB_RESOURCE, WINED3D_CS_OP_UPDATE_SUB_RESOURCE, WINED3D_CS_OP_ADD_DIRTY_TEXTURE_REGION, + WINED3D_CS_OP_CLEAR_SYSMEM_TEXTURE, WINED3D_CS_OP_CLEAR_UNORDERED_ACCESS_VIEW, WINED3D_CS_OP_COPY_UAV_COUNTER, WINED3D_CS_OP_GENERATE_MIPMAPS, @@ -179,6 +180,15 @@ struct wined3d_cs_clear RECT rects[1]; };
+struct wined3d_cs_clear_sysmem_texture +{ + enum wined3d_cs_op opcode; + struct wined3d_texture *texture; + unsigned int sub_resource_idx; + struct wined3d_color color; + RECT rect; +}; + struct wined3d_cs_dispatch { enum wined3d_cs_op opcode; @@ -612,6 +622,7 @@ static const char *debug_cs_op(enum wined3d_cs_op op) WINED3D_TO_STR(WINED3D_CS_OP_BLT_SUB_RESOURCE); WINED3D_TO_STR(WINED3D_CS_OP_UPDATE_SUB_RESOURCE); WINED3D_TO_STR(WINED3D_CS_OP_ADD_DIRTY_TEXTURE_REGION); + WINED3D_TO_STR(WINED3D_CS_OP_CLEAR_SYSMEM_TEXTURE); WINED3D_TO_STR(WINED3D_CS_OP_CLEAR_UNORDERED_ACCESS_VIEW); WINED3D_TO_STR(WINED3D_CS_OP_COPY_UAV_COUNTER); WINED3D_TO_STR(WINED3D_CS_OP_GENERATE_MIPMAPS); @@ -868,6 +879,70 @@ void wined3d_device_context_emit_clear_rendertarget_view(struct wined3d_device_c wined3d_device_context_finish(context, WINED3D_CS_QUEUE_DEFAULT); }
+static void wined3d_cs_exec_clear_sysmem_texture(struct wined3d_cs *cs, const void *data) +{ + const struct wined3d_cs_clear_sysmem_texture *op = data; + struct wined3d_box box; + + box.left = op->rect.left; + box.right = op->rect.right; + box.top = op->rect.top; + box.bottom = op->rect.bottom; + box.front = 0; + box.back = 1; + cpu_blitter_clear_texture(op->texture, op->sub_resource_idx, &box, &op->color); +} + +HRESULT CDECL wined3d_device_context_clear_sysmem_texture(struct wined3d_device_context *context, + struct wined3d_texture *texture, unsigned int sub_resource_idx, const RECT *rect, + unsigned int flags, const struct wined3d_color *color) +{ + struct wined3d_cs_clear_sysmem_texture *op; + + TRACE("context %p, texture %p, sub_resource_idx %u, rect %s, flags %#x, color %s.\n", + context, texture, sub_resource_idx, wine_dbgstr_rect(rect), flags, debug_color(color)); + + if (rect) + { + struct wined3d_box b = {rect->left, rect->top, rect->right, rect->bottom, 0, 1}; + HRESULT hr; + + if (FAILED(hr = wined3d_resource_check_box_dimensions(&texture->resource, sub_resource_idx, &b))) + return hr; + } + + wined3d_device_context_lock(context); + + op = wined3d_device_context_require_space(context, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op->opcode = WINED3D_CS_OP_CLEAR_SYSMEM_TEXTURE; + op->texture = texture; + op->sub_resource_idx = sub_resource_idx; + op->color = *color; + + if (rect) + { + op->rect = *rect; + } + else + { + unsigned int level_idx = sub_resource_idx % texture->level_count; + + op->rect.left = 0; + op->rect.top = 0; + op->rect.right = wined3d_texture_get_level_width(texture, level_idx); + op->rect.bottom = wined3d_texture_get_level_height(texture, level_idx); + } + + wined3d_device_context_reference_resource(context, &texture->resource); + + wined3d_device_context_submit(context, WINED3D_CS_QUEUE_DEFAULT); + if (flags & WINED3DCLEAR_SYNCHRONOUS) + wined3d_device_context_finish(context, WINED3D_CS_QUEUE_DEFAULT); + + wined3d_device_context_unlock(context); + return S_OK; +} + static void reference_shader_resources(struct wined3d_device_context *context, unsigned int shader_mask) { const struct wined3d_state *state = context->state; @@ -2917,6 +2992,7 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void /* WINED3D_CS_OP_BLT_SUB_RESOURCE */ wined3d_cs_exec_blt_sub_resource, /* WINED3D_CS_OP_UPDATE_SUB_RESOURCE */ wined3d_cs_exec_update_sub_resource, /* WINED3D_CS_OP_ADD_DIRTY_TEXTURE_REGION */ wined3d_cs_exec_add_dirty_texture_region, + /* WINED3D_CS_OP_CLEAR_SYSMEM_TEXTURE */ wined3d_cs_exec_clear_sysmem_texture, /* WINED3D_CS_OP_CLEAR_UNORDERED_ACCESS_VIEW */ wined3d_cs_exec_clear_unordered_access_view, /* WINED3D_CS_OP_COPY_UAV_COUNTER */ wined3d_cs_exec_copy_uav_counter, /* WINED3D_CS_OP_GENERATE_MIPMAPS */ wined3d_cs_exec_generate_mipmaps, @@ -3738,6 +3814,14 @@ static void wined3d_cs_packet_decref_objects(const struct wined3d_cs_packet *pac break; }
+ case WINED3D_CS_OP_CLEAR_SYSMEM_TEXTURE: + { + struct wined3d_cs_clear_sysmem_texture *op = (struct wined3d_cs_clear_sysmem_texture *)packet->data; + + wined3d_texture_decref(op->texture); + break; + } + case WINED3D_CS_OP_DISPATCH: { struct wined3d_cs_dispatch *op = (struct wined3d_cs_dispatch *)packet->data; @@ -3979,6 +4063,14 @@ static void wined3d_cs_packet_incref_objects(struct wined3d_cs_packet *packet) break; }
+ case WINED3D_CS_OP_CLEAR_SYSMEM_TEXTURE: + { + struct wined3d_cs_clear_sysmem_texture *op = (struct wined3d_cs_clear_sysmem_texture *)packet->data; + + wined3d_texture_incref(op->texture); + break; + } + case WINED3D_CS_OP_DISPATCH: { struct wined3d_cs_dispatch *op = (struct wined3d_cs_dispatch *)packet->data; diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index 028dc4e94b2..4ad1e65fafb 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -1125,7 +1125,7 @@ release: return hr; }
-static void cpu_blitter_clear_texture(struct wined3d_texture *texture, unsigned int sub_resource_idx, +void cpu_blitter_clear_texture(struct wined3d_texture *texture, unsigned int sub_resource_idx, const struct wined3d_box *box, const struct wined3d_color *colour) { struct wined3d_device *device = texture->resource.device; diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index 16c7624eb9c..3052b47e172 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -91,6 +91,7 @@
@ cdecl wined3d_device_context_blt(ptr ptr long ptr ptr long ptr long ptr long) @ cdecl wined3d_device_context_clear_rendertarget_view(ptr ptr ptr long ptr float long) +@ cdecl wined3d_device_context_clear_sysmem_texture(ptr ptr long ptr long ptr) @ cdecl wined3d_device_context_clear_uav_float(ptr ptr ptr) @ cdecl wined3d_device_context_clear_uav_uint(ptr ptr ptr) @ cdecl wined3d_device_context_copy_resource(ptr ptr ptr) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 39a4aa5da9c..c98f8ef09a5 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2035,6 +2035,9 @@ struct wined3d_blitter_ops struct wined3d_blitter *wined3d_cpu_blitter_create(void); void wined3d_vk_blitter_create(struct wined3d_blitter **next);
+void cpu_blitter_clear_texture(struct wined3d_texture *texture, unsigned int sub_resource_idx, + const struct wined3d_box *box, const struct wined3d_color *colour); + BOOL wined3d_clip_blit(const RECT *clip_rect, RECT *clipped, RECT *other);
void context_invalidate_compute_state(struct wined3d_context *context, DWORD state_id); diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index b9ae23bac16..0f8b5e75081 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2431,6 +2431,9 @@ HRESULT __cdecl wined3d_device_context_blt(struct wined3d_device_context *contex struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, const RECT *dst_rect, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, const RECT *src_rect, unsigned int flags, const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter); +HRESULT __cdecl wined3d_device_context_clear_sysmem_texture(struct wined3d_device_context *context, + struct wined3d_texture *texture, unsigned int sub_resource_idx, const RECT *rect, + unsigned int flags, const struct wined3d_color *color); HRESULT __cdecl wined3d_device_context_clear_rendertarget_view(struct wined3d_device_context *context, struct wined3d_rendertarget_view *view, const RECT *rect, unsigned int flags, const struct wined3d_color *color, float depth, unsigned int stencil);
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=150434
Your paranoid android.
=== w1064_2qxl (64 bit report) ===
ddraw: ddraw2.c:3824: Test failed: Expected (0,0)-(640,480), got (-8,-8)-(648,488). ddraw2.c:3849: Test failed: Expected (0,0)-(640,480), got (-8,-8)-(648,488).
=== w10pro64_ja (64 bit report) ===
ddraw: ddraw7.c:3822: Test failed: Expected (0,0)-(640,480), got (-8,-8)-(648,488). ddraw7.c:3847: Test failed: Expected (0,0)-(640,480), got (-8,-8)-(648,488).
=== debian11b (64 bit WoW report) ===
user32: input.c:4305: Test succeeded inside todo block: button_down_hwnd_todo 1: got MSG_TEST_WIN hwnd 00000000019E010C, msg WM_LBUTTONDOWN, wparam 0x1, lparam 0x320032
v2: fix various errors in wined3d_device_context_clear_sysmem_texture(), thanks Henri
This merge request was approved by Jan Sikorski.