wined3d: Ignore clears if count = 0 and rects != NULL.

This commit is contained in:
Stefan Dösinger 2013-01-23 15:02:45 +01:00 committed by Alexandre Julliard
parent 8373f8b6f6
commit aaa11492db
8 changed files with 296 additions and 0 deletions

View File

@ -347,6 +347,33 @@ static void clear_test(IDirect3DDevice8 *device)
ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color); ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL); 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);
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);
hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
ok(SUCCEEDED(hr), "IDirect3DDevice8_Clear failed with %#08x\n", hr);
hr = IDirect3DDevice8_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ff00, 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, 0x00, 0xff, 0x00), 1),
"Clear with count = 1, rect = NULL has color %#08x\n", color);
IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
} }
struct sVertex { struct sVertex {

View File

@ -678,6 +678,33 @@ static void clear_test(IDirect3DDevice9 *device)
ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color); ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL); 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);
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);
hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ff00, 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, 0x00, 0xff, 0x00), 1),
"Clear with count = 1, rect = NULL has color %08x\n", color);
IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
} }
static void color_fill_test(IDirect3DDevice9 *device) static void color_fill_test(IDirect3DDevice9 *device)

View File

@ -1,5 +1,6 @@
/* /*
* Copyright 2011-2012 Henri Verbeet for CodeWeavers * Copyright 2011-2012 Henri Verbeet for CodeWeavers
* Copyright 2012-2013 Stefan Dösinger for CodeWeavers
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -2659,6 +2660,70 @@ static void test_coop_level_multi_window(void)
DestroyWindow(window1); DestroyWindow(window1);
} }
static void test_clear_rect_count(void)
{
static D3DRECT clear_rect = {{0}, {0}, {640}, {480}};
IDirect3DMaterial *white, *red, *green, *blue;
IDirect3DViewport *viewport;
IDirect3DDevice *device;
IDirectDrawSurface *rt;
IDirectDraw *ddraw;
D3DCOLOR color;
HWND window;
HRESULT hr;
window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
0, 0, 640, 480, 0, 0, 0, 0);
if (!(ddraw = create_ddraw()))
{
skip("Failed to create ddraw object, skipping test.\n");
DestroyWindow(window);
return;
}
if (!(device = create_device(ddraw, window, DDSCL_NORMAL)))
{
skip("Failed to create D3D device, skipping test.\n");
IDirectDraw_Release(ddraw);
DestroyWindow(window);
return;
}
hr = IDirect3DDevice_QueryInterface(device, &IID_IDirectDrawSurface, (void **)&rt);
ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
white = create_diffuse_material(device, 1.0f, 1.0f, 1.0f, 1.0f);
red = create_diffuse_material(device, 1.0f, 0.0f, 0.0f, 1.0f);
green = create_diffuse_material(device, 0.0f, 1.0f, 0.0f, 1.0f);
blue = create_diffuse_material(device, 0.0f, 0.0f, 1.0f, 1.0f);
viewport = create_viewport(device, 0, 0, 640, 480);
viewport_set_background(device, viewport, white);
hr = IDirect3DViewport_Clear(viewport, 1, &clear_rect, D3DCLEAR_TARGET);
ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
viewport_set_background(device, viewport, red);
hr = IDirect3DViewport_Clear(viewport, 0, &clear_rect, D3DCLEAR_TARGET);
ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
viewport_set_background(device, viewport, green);
hr = IDirect3DViewport_Clear(viewport, 0, NULL, D3DCLEAR_TARGET);
ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
viewport_set_background(device, viewport, blue);
hr = IDirect3DViewport_Clear(viewport, 1, NULL, D3DCLEAR_TARGET);
ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
color = get_surface_color(rt, 320, 240);
ok(compare_color(color, 0x00ffffff, 1), "Got unexpected color 0x%08x.\n", color);
IDirectDrawSurface_Release(rt);
destroy_viewport(device, viewport);
destroy_material(white);
destroy_material(red);
destroy_material(green);
destroy_material(blue);
IDirect3DDevice_Release(device);
IDirectDraw_Release(ddraw);
DestroyWindow(window);
}
START_TEST(ddraw1) START_TEST(ddraw1)
{ {
test_coop_level_create_device_window(); test_coop_level_create_device_window();
@ -2680,4 +2745,5 @@ START_TEST(ddraw1)
test_initialize(); test_initialize();
test_coop_level_surf_create(); test_coop_level_surf_create();
test_coop_level_multi_window(); test_coop_level_multi_window();
test_clear_rect_count();
} }

View File

@ -1,5 +1,6 @@
/* /*
* Copyright 2011-2012 Henri Verbeet for CodeWeavers * Copyright 2011-2012 Henri Verbeet for CodeWeavers
* Copyright 2012-2013 Stefan Dösinger for CodeWeavers
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -2778,6 +2779,73 @@ static void test_coop_level_multi_window(void)
DestroyWindow(window1); DestroyWindow(window1);
} }
static void test_clear_rect_count(void)
{
static D3DRECT clear_rect = {{0}, {0}, {640}, {480}};
IDirect3DMaterial2 *white, *red, *green, *blue;
IDirect3DViewport2 *viewport;
IDirect3DDevice2 *device;
IDirectDrawSurface *rt;
IDirectDraw2 *ddraw;
D3DCOLOR color;
HWND window;
HRESULT hr;
window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
0, 0, 640, 480, 0, 0, 0, 0);
if (!(ddraw = create_ddraw()))
{
skip("Failed to create ddraw object, skipping test.\n");
DestroyWindow(window);
return;
}
if (!(device = create_device(ddraw, window, DDSCL_NORMAL)))
{
skip("Failed to create D3D device, skipping test.\n");
IDirectDraw2_Release(ddraw);
DestroyWindow(window);
return;
}
hr = IDirect3DDevice2_GetRenderTarget(device, &rt);
ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
white = create_diffuse_material(device, 1.0f, 1.0f, 1.0f, 1.0f);
red = create_diffuse_material(device, 1.0f, 0.0f, 0.0f, 1.0f);
green = create_diffuse_material(device, 0.0f, 1.0f, 0.0f, 1.0f);
blue = create_diffuse_material(device, 0.0f, 0.0f, 1.0f, 1.0f);
viewport = create_viewport(device, 0, 0, 640, 480);
hr = IDirect3DDevice2_SetCurrentViewport(device, viewport);
ok(SUCCEEDED(hr), "Failed to set current viewport, hr %#x.\n", hr);
viewport_set_background(device, viewport, white);
hr = IDirect3DViewport2_Clear(viewport, 1, &clear_rect, D3DCLEAR_TARGET);
ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
viewport_set_background(device, viewport, red);
hr = IDirect3DViewport2_Clear(viewport, 0, &clear_rect, D3DCLEAR_TARGET);
ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
viewport_set_background(device, viewport, green);
hr = IDirect3DViewport2_Clear(viewport, 0, NULL, D3DCLEAR_TARGET);
ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
viewport_set_background(device, viewport, blue);
hr = IDirect3DViewport2_Clear(viewport, 0, &clear_rect, D3DCLEAR_TARGET);
ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
color = get_surface_color(rt, 320, 240);
ok(compare_color(color, 0x00ffffff, 1), "Got unexpected color 0x%08x.\n", color);
IDirectDrawSurface_Release(rt);
destroy_viewport(device, viewport);
destroy_material(white);
destroy_material(red);
destroy_material(green);
destroy_material(blue);
IDirect3DDevice2_Release(device);
IDirectDraw2_Release(ddraw);
DestroyWindow(window);
}
START_TEST(ddraw2) START_TEST(ddraw2)
{ {
test_coop_level_create_device_window(); test_coop_level_create_device_window();
@ -2801,4 +2869,5 @@ START_TEST(ddraw2)
test_initialize(); test_initialize();
test_coop_level_surf_create(); test_coop_level_surf_create();
test_coop_level_multi_window(); test_coop_level_multi_window();
test_clear_rect_count();
} }

View File

@ -3037,6 +3037,49 @@ static void test_draw_strided(void)
DestroyWindow(window); DestroyWindow(window);
} }
static void test_clear_rect_count(void)
{
IDirectDrawSurface4 *rt;
IDirect3DDevice3 *device;
D3DCOLOR color;
HWND window;
HRESULT hr;
IDirect3DViewport3 *viewport;
static D3DRECT clear_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 = IDirect3DDevice3_GetRenderTarget(device, &rt);
ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
viewport = create_viewport(device, 0, 0, 640, 480);
hr = IDirect3DDevice3_SetCurrentViewport(device, viewport);
ok(SUCCEEDED(hr), "Failed to activate the viewport, hr %#x.\n", hr);
hr = IDirect3DViewport3_Clear2(viewport, 1, &clear_rect, D3DCLEAR_TARGET, 0x00ffffff, 0.0f, 0);
ok(SUCCEEDED(hr), "Failed to clear the viewport, hr %#x.\n", hr);
hr = IDirect3DViewport3_Clear2(viewport, 0, &clear_rect, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
ok(SUCCEEDED(hr), "Failed to clear the viewport, hr %#x.\n", hr);
hr = IDirect3DViewport3_Clear2(viewport, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0f, 0);
ok(SUCCEEDED(hr), "Failed to clear the viewport, hr %#x.\n", hr);
hr = IDirect3DViewport3_Clear2(viewport, 1, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
ok(SUCCEEDED(hr), "Failed to clear the viewport, hr %#x.\n", hr);
color = get_surface_color(rt, 320, 240);
ok(compare_color(color, 0x00ffffff, 1), "Got unexpected color 0x%08x.\n", color);
IDirect3DViewport3_Release(viewport);
IDirectDrawSurface4_Release(rt);
IDirect3DDevice3_Release(device);
DestroyWindow(window);
}
START_TEST(ddraw4) START_TEST(ddraw4)
{ {
test_process_vertices(); test_process_vertices();
@ -3063,4 +3106,5 @@ START_TEST(ddraw4)
test_vb_discard(); test_vb_discard();
test_coop_level_multi_window(); test_coop_level_multi_window();
test_draw_strided(); test_draw_strided();
test_clear_rect_count();
} }

View File

@ -2839,6 +2839,50 @@ static void test_draw_strided(void)
DestroyWindow(window); 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),
"Clear with count = 0, rect != NULL has color %#08x.\n", color);
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, 1, NULL, D3DCLEAR_TARGET, 0x0000ff00, 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, 0x0000ff00, 1),
"Clear with count = 1, rect = NULL has color %#08x.\n", color);
IDirectDrawSurface7_Release(rt);
IDirect3DDevice7_Release(device);
DestroyWindow(window);
}
START_TEST(ddraw7) START_TEST(ddraw7)
{ {
HMODULE module = GetModuleHandleA("ddraw.dll"); HMODULE module = GetModuleHandleA("ddraw.dll");
@ -2872,4 +2916,5 @@ START_TEST(ddraw7)
test_vb_discard(); test_vb_discard();
test_coop_level_multi_window(); test_coop_level_multi_window();
test_draw_strided(); test_draw_strided();
test_clear_rect_count();
} }

View File

@ -670,6 +670,12 @@ static HRESULT WINAPI d3d_viewport_Clear(IDirect3DViewport3 *iface,
TRACE("iface %p, rect_count %u, rects %p, flags %#x.\n", iface, rect_count, rects, flags); TRACE("iface %p, rect_count %u, rects %p, flags %#x.\n", iface, rect_count, rects, flags);
if (!rects || !rect_count)
{
WARN("rect_count = %u, rects = %p, ignoring clear\n", rect_count, rects);
return D3D_OK;
}
if (This->active_device == NULL) { if (This->active_device == NULL) {
ERR(" Trying to clear a viewport not attached to a device !\n"); ERR(" Trying to clear a viewport not attached to a device !\n");
return D3DERR_VIEWPORTHASNODEVICE; return D3DERR_VIEWPORTHASNODEVICE;
@ -1060,6 +1066,12 @@ static HRESULT WINAPI d3d_viewport_Clear2(IDirect3DViewport3 *iface, DWORD rect_
TRACE("iface %p, rect_count %u, rects %p, flags %#x, color 0x%08x, depth %.8e, stencil %u.\n", TRACE("iface %p, rect_count %u, rects %p, flags %#x, color 0x%08x, depth %.8e, stencil %u.\n",
iface, rect_count, rects, flags, color, depth, stencil); iface, rect_count, rects, flags, color, depth, stencil);
if (!rects || !rect_count)
{
WARN("rect_count = %u, rects = %p, ignoring clear\n", rect_count, rects);
return D3D_OK;
}
wined3d_mutex_lock(); wined3d_mutex_lock();
if (!viewport->active_device) if (!viewport->active_device)

View File

@ -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", 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); 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", rects);
return WINED3D_OK;
}
if (flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL)) if (flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL))
{ {
struct wined3d_surface *ds = device->fb.depth_stencil; struct wined3d_surface *ds = device->fb.depth_stencil;