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