Module: wine Branch: master Commit: b294e43206dab65687dd9358f4a1c8ae396ab7fe URL: http://source.winehq.org/git/wine.git/?a=commit;h=b294e43206dab65687dd9358f4...
Author: Stefan Dösinger stefan@codeweavers.com Date: Tue Aug 26 14:11:47 2008 -0500
wined3d: D3DTOP_DOTPRODUCT3 colorop overrides the alphaop.
Note that the fix is only implemented in the arbfp and atifs fragment pipeline. Unfortunately nvrc doesn't support dot3 as alpha operation.
---
dlls/d3d9/tests/visual.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++ dlls/wined3d/utils.c | 16 ++++++++-- 2 files changed, 91 insertions(+), 3 deletions(-)
diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c index d36411f..c889e7e 100644 --- a/dlls/d3d9/tests/visual.c +++ b/dlls/d3d9/tests/visual.c @@ -9576,6 +9576,82 @@ static void alphareplicate_test(IDirect3DDevice9 *device) {
}
+static void dp3_alpha_test(IDirect3DDevice9 *device) { + HRESULT hr; + D3DCAPS9 caps; + DWORD color; + struct vertex quad[] = { + { -1.0, -1.0, 0.1, 0x408080c0 }, + { 1.0, -1.0, 0.1, 0x408080c0 }, + { -1.0, 1.0, 0.1, 0x408080c0 }, + { 1.0, 1.0, 0.1, 0x408080c0 }, + }; + + memset(&caps, 0, sizeof(caps)); + hr = IDirect3DDevice9_GetDeviceCaps(device, &caps); + ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr); + if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) { + skip("D3DTOP_DOTPRODUCT3 not supported\n"); + return; + } + + hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0); + ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr); + + hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE); + ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr); + + /* dp3_x4 r0, diffuse_bias, tfactor_bias + * mov r0.a, diffuse.a + * mov r0, r0.a + * + * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead + * thus with input vec4(0.5, 0.5, 0.75, 0.25) and vec4(1.0, 1.0, 1.0, 1.0) the result is + * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision. + */ + hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3); + ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr); + hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE); + ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr); + hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR); + ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr); + hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr); + hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE); + ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr); + hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr); + hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE); + ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr); + hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr); + hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff); + ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr); + + hr = IDirect3DDevice9_BeginScene(device); + ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr); + if(SUCCEEDED(hr)) { + hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad)); + ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr); + hr = IDirect3DDevice9_EndScene(device); + ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr); + } + + hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL); + ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr); + + color = getPixelColor(device, 320, 240); + ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n", + color); + + hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE); + ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr); + hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr); + hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE); + ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr); +} + START_TEST(visual) { IDirect3DDevice9 *device_ptr; @@ -9732,9 +9808,11 @@ START_TEST(visual) } } else skip("No ps_1_1 support\n"); + texop_test(device_ptr); texop_range_test(device_ptr); alphareplicate_test(device_ptr); + dp3_alpha_test(device_ptr);
cleanup: if(device_ptr) { diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 8501544..3cce302 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -1871,9 +1871,19 @@ void gen_ffp_op(IWineD3DStateBlockImpl *stateblock, struct ffp_settings *setting cop = WINED3DTOP_SELECTARG1; }
- aarg1 = (args[aop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG1] : 0xffffffff; - aarg2 = (args[aop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG2] : 0xffffffff; - aarg0 = (args[aop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG0] : 0xffffffff; + if(cop == WINED3DTOP_DOTPRODUCT3) { + /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates + * the color result to the alpha component of the destination + */ + aop = cop; + aarg1 = carg1; + aarg2 = carg2; + aarg0 = carg0; + } else { + aarg1 = (args[aop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG1] : 0xffffffff; + aarg2 = (args[aop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG2] : 0xffffffff; + aarg0 = (args[aop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG0] : 0xffffffff; + }
if(i == 0 && stateblock->textures[0] && stateblock->renderState[WINED3DRS_COLORKEYENABLE] &&