[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