[PATCH] wined3d: Ignore clears if count = 0 and rects != NULL

Stefan Dösinger stefan at codeweavers.com
Wed Jan 23 06:14:24 CST 2013


Fixes bug 19773.

In cutscenes, Largo Winch clears an area on the top and bottom of the
screen with a clear that clears two rectangles. Outside of the
cutscenes, it still performs the clear call, but sets the rectangle
count to 0. The rectangles contain whatever area is left over from the
cutscene fade-out effect, usually the bottom two lines. Wine currently
ignores the rectangles and clears the entire screen to black.
---
 dlls/d3d8/tests/visual.c  | 17 +++++++++++++++++
 dlls/d3d9/tests/visual.c  | 16 ++++++++++++++++
 dlls/ddraw/tests/ddraw7.c | 36 ++++++++++++++++++++++++++++++++++++
 dlls/wined3d/device.c     |  6 ++++++
 4 files changed, 75 insertions(+)

diff --git a/dlls/d3d8/tests/visual.c b/dlls/d3d8/tests/visual.c
index 6aaf365..5ae2ed5 100644
--- a/dlls/d3d8/tests/visual.c
+++ b/dlls/d3d8/tests/visual.c
@@ -347,6 +347,23 @@ static void clear_test(IDirect3DDevice8 *device)
     ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
 
     IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
+
+    hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
+    ok(SUCCEEDED(hr), "IDirect3DDevice8_Clear failed with %#08x\n", hr);
+
+    /* Pass a rectangle but set the rectangle count to 0. The clear is ignored */
+    rect[0].x1 = 0;
+    rect[0].y1 = 0;
+    rect[0].x2 = 640;
+    rect[0].y2 = 480;
+    hr = IDirect3DDevice8_Clear(device, 0, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
+    ok(SUCCEEDED(hr), "IDirect3DDevice8_Clear failed with %#08x\n", hr);
+
+    color = getPixelColor(device, 320, 240);
+    ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xFF, 0xFF, 0xFF), 1),
+            "Clear with count = 0, rect != NULL has color %#08x\n", color);
+
+    IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
 }
 
 struct sVertex {
diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c
index a9c5c44..2302ce8 100644
--- a/dlls/d3d9/tests/visual.c
+++ b/dlls/d3d9/tests/visual.c
@@ -678,6 +678,22 @@ static void clear_test(IDirect3DDevice9 *device)
     ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
 
     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
+
+    hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
+    ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
+    /* Test a clear with count = 0 and rects != NULL. The clear is ignored */
+    rect[0].x1 = 0;
+    rect[0].y1 = 0;
+    rect[0].x2 = 640;
+    rect[0].y2 = 480;
+    hr = IDirect3DDevice9_Clear(device, 0, rect, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
+    ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
+
+    color = getPixelColor(device, 320, 240);
+    ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xFF, 0xFF, 0xFF), 1),
+            "Clear with count = 0, rect != NULL has color %08x\n", color);
+
+    IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
 }
 
 static void color_fill_test(IDirect3DDevice9 *device)
diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c
index 6b6f6d6..c5935b7 100644
--- a/dlls/ddraw/tests/ddraw7.c
+++ b/dlls/ddraw/tests/ddraw7.c
@@ -2839,6 +2839,41 @@ static void test_draw_strided(void)
     DestroyWindow(window);
 }
 
+static void test_clear_rect_count(void)
+{
+    IDirectDrawSurface7 *rt;
+    IDirect3DDevice7 *device;
+    D3DCOLOR color;
+    HWND window;
+    HRESULT hr;
+    D3DRECT rect = {0, 0, 640, 480};
+
+    window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
+            0, 0, 640, 480, 0, 0, 0, 0);
+
+    if (!(device = create_device(window, DDSCL_NORMAL)))
+    {
+        skip("Failed to create D3D device, skipping test.\n");
+        DestroyWindow(window);
+        return;
+    }
+
+    hr = IDirect3DDevice7_GetRenderTarget(device, &rt);
+    ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
+
+    hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 1.0f, 0);
+    ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
+    hr = IDirect3DDevice7_Clear(device, 0, &rect, D3DCLEAR_TARGET, 0x00ff0000, 1.0f, 0);
+    ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
+
+    color = get_surface_color(rt, 320, 240);
+    ok(compare_color(color, 0x00ffffff, 1), "Got unexpected color %#08x.\n", color);
+
+    IDirectDrawSurface7_Release(rt);
+    IDirect3DDevice7_Release(device);
+    DestroyWindow(window);
+}
+
 START_TEST(ddraw7)
 {
     HMODULE module = GetModuleHandleA("ddraw.dll");
@@ -2872,4 +2907,5 @@ START_TEST(ddraw7)
     test_vb_discard();
     test_coop_level_multi_window();
     test_draw_strided();
+    test_clear_rect_count();
 }
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index cedb39e..e8e68ce 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -4011,6 +4011,12 @@ HRESULT CDECL wined3d_device_clear(struct wined3d_device *device, DWORD rect_cou
     TRACE("device %p, rect_count %u, rects %p, flags %#x, color {%.8e, %.8e, %.8e, %.8e}, depth %.8e, stencil %u.\n",
             device, rect_count, rects, flags, color->r, color->g, color->b, color->a, depth, stencil);
 
+    if (!rect_count && rects)
+    {
+        WARN("Rects is %p, but rect_count is 0, ignoring clear\n");
+        return WINED3D_OK;
+    }
+
     if (flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL))
     {
         struct wined3d_surface *ds = device->fb.depth_stencil;
-- 
1.7.12.4




More information about the wine-patches mailing list