mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-31 11:43:31 +00:00
wined3d: More Clear fixes.
Test for rectangles with x1 > x2 and y1 > y2. Empire earth passes such rects.
This commit is contained in:
parent
8b70b91cba
commit
4a16dbbbec
4 changed files with 175 additions and 21 deletions
|
@ -259,6 +259,54 @@ static void lighting_test(IDirect3DDevice8 *device)
|
|||
ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %s\n", DXGetErrorString8(hr));
|
||||
}
|
||||
|
||||
static void clear_test(IDirect3DDevice8 *device)
|
||||
{
|
||||
/* Tests the correctness of clearing parameters */
|
||||
HRESULT hr;
|
||||
D3DRECT rect[2];
|
||||
D3DRECT rect_negneg;
|
||||
DWORD color;
|
||||
|
||||
hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
|
||||
ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %s\n", DXGetErrorString8(hr));
|
||||
|
||||
/* Positive x, negative y */
|
||||
rect[0].x1 = 0;
|
||||
rect[0].y1 = 480;
|
||||
rect[0].x2 = 320;
|
||||
rect[0].y2 = 240;
|
||||
|
||||
/* Positive x, positive y */
|
||||
rect[1].x1 = 0;
|
||||
rect[1].y1 = 0;
|
||||
rect[1].x2 = 320;
|
||||
rect[1].y2 = 240;
|
||||
/* Clear 2 rectangles with one call. Shows that a positive value is returned, but the negative rectangle
|
||||
* is ignored, the positive is still cleared afterwards
|
||||
*/
|
||||
hr = IDirect3DDevice8_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
|
||||
ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %s\n", DXGetErrorString8(hr));
|
||||
|
||||
/* negative x, negative y */
|
||||
rect_negneg.x1 = 640;
|
||||
rect_negneg.x1 = 240;
|
||||
rect_negneg.x2 = 320;
|
||||
rect_negneg.y2 = 0;
|
||||
hr = IDirect3DDevice8_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
|
||||
ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %s\n", DXGetErrorString8(hr));
|
||||
|
||||
IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
|
||||
|
||||
color = getPixelColor(device, 160, 360); /* lower left quad */
|
||||
ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
|
||||
color = getPixelColor(device, 160, 120); /* upper left quad */
|
||||
ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
|
||||
color = getPixelColor(device, 480, 360); /* lower right quad */
|
||||
ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
|
||||
color = getPixelColor(device, 480, 120); /* upper right quad */
|
||||
ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
|
||||
}
|
||||
|
||||
START_TEST(visual)
|
||||
{
|
||||
IDirect3DDevice8 *device_ptr;
|
||||
|
@ -308,6 +356,7 @@ START_TEST(visual)
|
|||
|
||||
/* Now run the real test */
|
||||
lighting_test(device_ptr);
|
||||
clear_test(device_ptr);
|
||||
|
||||
cleanup:
|
||||
if(device_ptr) IDirect3DDevice8_Release(device_ptr);
|
||||
|
|
|
@ -266,6 +266,54 @@ static void lighting_test(IDirect3DDevice9 *device)
|
|||
IDirect3DDevice9_SetVertexDeclaration(device, NULL);
|
||||
}
|
||||
|
||||
static void clear_test(IDirect3DDevice9 *device)
|
||||
{
|
||||
/* Tests the correctness of clearing parameters */
|
||||
HRESULT hr;
|
||||
D3DRECT rect[2];
|
||||
D3DRECT rect_negneg;
|
||||
DWORD color;
|
||||
|
||||
hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
|
||||
ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
|
||||
|
||||
/* Positive x, negative y */
|
||||
rect[0].x1 = 0;
|
||||
rect[0].y1 = 480;
|
||||
rect[0].x2 = 320;
|
||||
rect[0].y2 = 240;
|
||||
|
||||
/* Positive x, positive y */
|
||||
rect[1].x1 = 0;
|
||||
rect[1].y1 = 0;
|
||||
rect[1].x2 = 320;
|
||||
rect[1].y2 = 240;
|
||||
/* Clear 2 rectangles with one call. Shows that a positive value is returned, but the negative rectangle
|
||||
* is ignored, the positive is still cleared afterwards
|
||||
*/
|
||||
hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
|
||||
ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
|
||||
|
||||
/* negative x, negative y */
|
||||
rect_negneg.x1 = 640;
|
||||
rect_negneg.x1 = 240;
|
||||
rect_negneg.x2 = 320;
|
||||
rect_negneg.y2 = 0;
|
||||
hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
|
||||
ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
|
||||
|
||||
IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
|
||||
|
||||
color = getPixelColor(device, 160, 360); /* lower left quad */
|
||||
ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
|
||||
color = getPixelColor(device, 160, 120); /* upper left quad */
|
||||
ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
|
||||
color = getPixelColor(device, 480, 360); /* lower right quad */
|
||||
ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
|
||||
color = getPixelColor(device, 480, 120); /* upper right quad */
|
||||
ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
|
||||
}
|
||||
|
||||
START_TEST(visual)
|
||||
{
|
||||
IDirect3DDevice9 *device_ptr;
|
||||
|
@ -315,6 +363,7 @@ START_TEST(visual)
|
|||
|
||||
/* Now execute the real tests */
|
||||
lighting_test(device_ptr);
|
||||
clear_test(device_ptr);
|
||||
|
||||
cleanup:
|
||||
if(device_ptr) IDirect3DDevice9_Release(device_ptr);
|
||||
|
|
|
@ -301,6 +301,52 @@ static void lighting_test(IDirect3DDevice7 *device)
|
|||
ok(hr == D3D_OK, "IDirect3DDevice7_SetRenderState returned %08x\n", hr);
|
||||
}
|
||||
|
||||
static void clear_test(IDirect3DDevice7 *device)
|
||||
{
|
||||
/* Tests the correctness of clearing parameters */
|
||||
HRESULT hr;
|
||||
D3DRECT rect[2];
|
||||
D3DRECT rect_negneg;
|
||||
DWORD color;
|
||||
|
||||
hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
|
||||
ok(hr == D3D_OK, "IDirect3DDevice7_Clear failed with %08x\n", hr);
|
||||
|
||||
/* Positive x, negative y */
|
||||
rect[0].x1 = 0;
|
||||
rect[0].y1 = 480;
|
||||
rect[0].x2 = 320;
|
||||
rect[0].y2 = 240;
|
||||
|
||||
/* Positive x, positive y */
|
||||
rect[1].x1 = 0;
|
||||
rect[1].y1 = 0;
|
||||
rect[1].x2 = 320;
|
||||
rect[1].y2 = 240;
|
||||
/* Clear 2 rectangles with one call. Shows that a positive value is returned, but the negative rectangle
|
||||
* is ignored, the positive is still cleared afterwards
|
||||
*/
|
||||
hr = IDirect3DDevice7_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
|
||||
ok(hr == D3D_OK, "IDirect3DDevice7_Clear failed with %08x\n", hr);
|
||||
|
||||
/* negative x, negative y */
|
||||
rect_negneg.x1 = 640;
|
||||
rect_negneg.x1 = 240;
|
||||
rect_negneg.x2 = 320;
|
||||
rect_negneg.y2 = 0;
|
||||
hr = IDirect3DDevice7_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
|
||||
ok(hr == D3D_OK, "IDirect3DDevice7_Clear failed with %08x\n", hr);
|
||||
|
||||
color = getPixelColor(device, 160, 360); /* lower left quad */
|
||||
ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
|
||||
color = getPixelColor(device, 160, 120); /* upper left quad */
|
||||
ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
|
||||
color = getPixelColor(device, 480, 360); /* lower right quad */
|
||||
ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
|
||||
color = getPixelColor(device, 480, 120); /* upper right quad */
|
||||
ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
|
||||
}
|
||||
|
||||
START_TEST(visual)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
@ -342,6 +388,7 @@ START_TEST(visual)
|
|||
|
||||
/* Now run the tests */
|
||||
lighting_test(Direct3DDevice);
|
||||
clear_test(Direct3DDevice);
|
||||
|
||||
cleanup:
|
||||
releaseObjects();
|
||||
|
|
|
@ -4226,26 +4226,34 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Clear(IWineD3DDevice *iface, DWORD Coun
|
|||
glMask = glMask | GL_COLOR_BUFFER_BIT;
|
||||
}
|
||||
|
||||
/* Now process each rect in turn */
|
||||
for (i = 0; i < Count || i == 0; i++) {
|
||||
|
||||
if (curRect) {
|
||||
/* Note gl uses lower left, width/height */
|
||||
TRACE("(%p) %p Rect=(%d,%d)->(%d,%d) glRect=(%d,%d), len=%d, hei=%d\n", This, curRect,
|
||||
curRect->x1, curRect->y1, curRect->x2, curRect->y2,
|
||||
curRect->x1, (((IWineD3DSurfaceImpl *)This->render_targets[0])->currentDesc.Height - curRect->y2),
|
||||
curRect->x2 - curRect->x1, curRect->y2 - curRect->y1);
|
||||
glScissor(curRect->x1, (((IWineD3DSurfaceImpl *)This->render_targets[0])->currentDesc.Height - curRect->y2),
|
||||
curRect->x2 - curRect->x1, curRect->y2 - curRect->y1);
|
||||
checkGLcall("glScissor");
|
||||
}
|
||||
|
||||
/* Clear the selected rectangle (or full screen) */
|
||||
if (!curRect) {
|
||||
glClear(glMask);
|
||||
checkGLcall("glClear");
|
||||
} else {
|
||||
/* Now process each rect in turn */
|
||||
for (i = 0; i < Count; i++) {
|
||||
/* Note gl uses lower left, width/height */
|
||||
TRACE("(%p) %p Rect=(%d,%d)->(%d,%d) glRect=(%d,%d), len=%d, hei=%d\n", This, curRect,
|
||||
curRect[i].x1, curRect[i].y1, curRect[i].x2, curRect[i].y2,
|
||||
curRect[i].x1, (((IWineD3DSurfaceImpl *)This->render_targets[0])->currentDesc.Height - curRect[i].y2),
|
||||
curRect[i].x2 - curRect[i].x1, curRect[i].y2 - curRect[i].y1);
|
||||
|
||||
/* Step to the next rectangle */
|
||||
if (curRect) curRect = curRect + sizeof(WINED3DRECT);
|
||||
/* Tests show that rectangles where x1 > x2 or y1 > y2 are ignored silently.
|
||||
* The rectangle is not cleared, no error is returned, but further rectanlges are
|
||||
* still cleared if they are valid
|
||||
*/
|
||||
if(curRect[i].x1 > curRect[i].x2 || curRect[i].y1 > curRect[i].y2) {
|
||||
TRACE("Rectangle with negative dimensions, ignoring\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
glScissor(curRect[i].x1, ((IWineD3DSurfaceImpl *)This->render_targets[0])->currentDesc.Height - curRect[i].y2,
|
||||
curRect[i].x2 - curRect[i].x1, curRect[i].y2 - curRect[i].y1);
|
||||
checkGLcall("glScissor");
|
||||
|
||||
glClear(glMask);
|
||||
checkGLcall("glClear");
|
||||
}
|
||||
}
|
||||
|
||||
/* Restore the old values (why..?) */
|
||||
|
@ -4253,10 +4261,11 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Clear(IWineD3DDevice *iface, DWORD Coun
|
|||
glStencilMask(This->stateBlock->renderState[WINED3DRS_STENCILWRITEMASK]);
|
||||
}
|
||||
if (Flags & WINED3DCLEAR_TARGET) {
|
||||
glColorMask(This->stateBlock->renderState[WINED3DRS_COLORWRITEENABLE] & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE,
|
||||
This->stateBlock->renderState[WINED3DRS_COLORWRITEENABLE] & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE,
|
||||
This->stateBlock->renderState[WINED3DRS_COLORWRITEENABLE] & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE,
|
||||
This->stateBlock->renderState[WINED3DRS_COLORWRITEENABLE] & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE);
|
||||
DWORD mask = This->stateBlock->renderState[WINED3DRS_COLORWRITEENABLE];
|
||||
glColorMask(mask & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE,
|
||||
mask & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE,
|
||||
mask & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE,
|
||||
mask & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE);
|
||||
}
|
||||
|
||||
LEAVE_GL();
|
||||
|
|
Loading…
Reference in a new issue