Module: wine Branch: master Commit: fb7b878e065da9f279c619ea92a27501131ecd75 URL: https://source.winehq.org/git/wine.git/?a=commit;h=fb7b878e065da9f279c619ea9...
Author: Paul Gofman gofmanp@gmail.com Date: Tue Jun 18 20:52:25 2019 +0300
ddraw: Turn off legacy texture blending in d3d_device3_SetTextureStageState().
Signed-off-by: Paul Gofman gofmanp@gmail.com Signed-off-by: Henri Verbeet hverbeet@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/ddraw/device.c | 16 +++++++ dlls/ddraw/tests/ddraw4.c | 112 +++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 116 insertions(+), 12 deletions(-)
diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c index c1815d6..ef940d7 100644 --- a/dlls/ddraw/device.c +++ b/dlls/ddraw/device.c @@ -5166,10 +5166,26 @@ static HRESULT WINAPI d3d_device3_SetTextureStageState(IDirect3DDevice3 *iface, DWORD stage, D3DTEXTURESTAGESTATETYPE state, DWORD value) { struct d3d_device *device = impl_from_IDirect3DDevice3(iface); + DWORD old_value; + HRESULT hr;
TRACE("iface %p, stage %u, state %#x, value %#x.\n", iface, stage, state, value);
+ /* Tests show that legacy texture blending is not reset if the texture stage state + * value is unchanged. */ + if (FAILED(hr = IDirect3DDevice7_GetTextureStageState(&device->IDirect3DDevice7_iface, + stage, state, &old_value))) + return hr; + + if (old_value == value) + { + TRACE("Application is setting the same value over, nothing to do.\n"); + return D3D_OK; + } + + device->legacyTextureBlending = FALSE; + return IDirect3DDevice7_SetTextureStageState(&device->IDirect3DDevice7_iface, stage, state, value); }
diff --git a/dlls/ddraw/tests/ddraw4.c b/dlls/ddraw/tests/ddraw4.c index bd6de1e..3498ddb 100644 --- a/dlls/ddraw/tests/ddraw4.c +++ b/dlls/ddraw/tests/ddraw4.c @@ -9596,38 +9596,126 @@ static void test_texturemapblend(void) fx.dwSize = sizeof(fx); U5(fx).dwFillColor = 0xff0000ff; hr = IDirectDrawSurface4_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx); - ok(SUCCEEDED(hr), "Failed to clear texture, hr %#x.\n", hr); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); U5(fx).dwFillColor = 0x800000ff; hr = IDirectDrawSurface4_Blt(surface, &rect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx); - ok(SUCCEEDED(hr), "Failed to clear texture, hr %#x.\n", hr); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
/* Note that the ddraw1 version of this test runs tests 1-3 with * D3DRENDERSTATE_COLORKEYENABLE enabled, whereas this version only runs * test 4 with color keying on. Because no color key is set on the texture * this should not result in different behavior. */ hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_CULLMODE, D3DCULL_NONE); - ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_ZENABLE, D3DZB_FALSE); - ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA); - ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA); - ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, TRUE); - ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_TEXTUREMAPBLEND, D3DTBLEND_MODULATE); - ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + /* Texture stage state does not change so legacy texture blending stays enabled. */ + hr = IDirect3DDevice3_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DDevice3_BeginScene(device); - ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DDevice3_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1, &test1_quads[0], 4, 0); - ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DDevice3_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1, &test1_quads[4], 4, 0); - ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); hr = IDirect3DDevice3_EndScene(device); - ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + color = get_surface_color(rt, 5, 5); + ok(compare_color(color, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color); + color = get_surface_color(rt, 400, 5); + ok(compare_color(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color); + color = get_surface_color(rt, 5, 245); + ok(compare_color(color, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color); + color = get_surface_color(rt, 400, 245); + ok(compare_color(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color); + + /* Turn legacy texture blending off. */ + hr = IDirect3DDevice3_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DDevice3_SetTexture(device, 0, texture); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DViewport3_Clear(viewport, 1, &clear_rect, D3DCLEAR_TARGET); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DDevice3_BeginScene(device); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DDevice3_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, + D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1, &test1_quads[0], 4, 0); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DDevice3_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, + D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1, &test1_quads[4], 4, 0); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DDevice3_EndScene(device); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + color = get_surface_color(rt, 5, 5); + ok(compare_color(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color); + color = get_surface_color(rt, 400, 5); + ok(compare_color(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color); + color = get_surface_color(rt, 5, 245); + ok(compare_color(color, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color); + color = get_surface_color(rt, 400, 245); + ok(compare_color(color, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color); + + /* This doesn't turn legacy texture blending on again, as setting the same + * _TEXTUREMAPBLEND value. */ + hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_TEXTUREMAPBLEND, D3DTBLEND_MODULATE); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DDevice3_SetTexture(device, 0, texture); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DViewport3_Clear(viewport, 1, &clear_rect, D3DCLEAR_TARGET); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DDevice3_BeginScene(device); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DDevice3_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, + D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1, &test1_quads[0], 4, 0); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DDevice3_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, + D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1, &test1_quads[4], 4, 0); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DDevice3_EndScene(device); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + color = get_surface_color(rt, 5, 5); + todo_wine ok(compare_color(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color); + color = get_surface_color(rt, 400, 5); + ok(compare_color(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color); + color = get_surface_color(rt, 5, 245); + ok(compare_color(color, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color); + color = get_surface_color(rt, 400, 245); + todo_wine ok(compare_color(color, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color); + + /* Turn legacy texture blending on again. */ + hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_TEXTUREMAPBLEND, D3DTBLEND_ADD); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_TEXTUREMAPBLEND, D3DTBLEND_MODULATE); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DDevice3_SetTexture(device, 0, texture); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DViewport3_Clear(viewport, 1, &clear_rect, D3DCLEAR_TARGET); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DDevice3_BeginScene(device); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DDevice3_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, + D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1, &test1_quads[0], 4, 0); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DDevice3_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, + D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1, &test1_quads[4], 4, 0); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DDevice3_EndScene(device); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
color = get_surface_color(rt, 5, 5); ok(compare_color(color, 0x00000080, 2), "Got unexpected color 0x%08x.\n", color);