[PATCH] WineD3D: Get rid of last_was_foggy_shader & friends=0A=

Stefan Doesinger stefan at codeweavers.com
Fri Jan 9 12:44:24 CST 2009


=0A=
The fog settings do not depend on wether the shader writes to oFog or =
not,=0A=
instead they depend on the FOGVERTEXMODE and FOGTABLEMODE settings, and =
if a=0A=
vertex shader is bound at all.=0A=
=0A=
It works the same way as with the fixed function, and having a vertex =
shader=0A=
is the same as using pretransformed vertices, just that the fog coord =
comes=0A=
from the shader instead of the specular color:=0A=
=0A=
FOGTABLEMODE !=3D NONE: The Z coord is used, oFog is ignored=0A=
FOGTABLEMODE =3D=3D NONE, with VS: oFog is used=0A=
FOGTABLEMODE =3D=3D NONE, no VS, XYZ: Z is used=0A=
FOGTABLEMODE =3D=3D NONE, no VS, XYZRHW: diffuse color is used=0A=
=0A=
This patch "breaks" a set of fog tests, so they're marked as todo. The =
tests=0A=
aren't really working correctly right now anyway, they depend on =
undefined=0A=
default values in opengl. A later patch will make the vertex shader =
select=0A=
the result.fogcoord(and glsl equivalent) depending on the fog settings, =
thus=0A=
really fixing this test.=0A=
---=0A=
 dlls/d3d9/tests/visual.c          |   12 +++-=0A=
 dlls/wined3d/arb_program_shader.c |   21 +++----=0A=
 dlls/wined3d/state.c              |  122 =
+++++++++++++++++--------------------=0A=
 dlls/wined3d/utils.c              |   26 +++++---=0A=
 dlls/wined3d/wined3d_private.h    |    3 +-=0A=
 5 files changed, 90 insertions(+), 94 deletions(-)=0A=
=0A=
diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c=0A=
index 5574313..22035b8 100644=0A=
--- a/dlls/d3d9/tests/visual.c=0A=
+++ b/dlls/d3d9/tests/visual.c=0A=
@@ -1536,9 +1536,15 @@ static void fog_with_shader_test(IDirect3DDevice9 =
*device)=0A=
 =0A=
             /* As the red and green component are the result of =
blending use 5% tolerance on the expected value */=0A=
             color =3D getPixelColor(device, 128, 240);=0A=
-            ok(color_match(color, test_data[i].color[j], 13),=0A=
-               "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected =
%08x +-5%%\n",=0A=
-               test_data[i].vshader, test_data[i].pshader, =
test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);=0A=
+            if(test_data[i].vshader =3D=3D 1 && test_data[i].tfog =
=3D=3D 0) {=0A=
+                todo_wine ok(color_match(color, test_data[i].color[j], =
13),=0A=
+                             "fog vs%i ps%i fvm%i ftm%i %d: got color =
%08x, expected %08x +-5%%(todo)\n",=0A=
+                             test_data[i].vshader, =
test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, =
test_data[i].color[j]);=0A=
+            } else {=0A=
+                ok(color_match(color, test_data[i].color[j], 13),=0A=
+                   "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, =
expected %08x +-5%%\n",=0A=
+                   test_data[i].vshader, test_data[i].pshader, =
test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);=0A=
+            }=0A=
         }=0A=
     }=0A=
 =0A=
diff --git a/dlls/wined3d/arb_program_shader.c =
b/dlls/wined3d/arb_program_shader.c=0A=
index 7ff3cd4..4ffa45f 100644=0A=
--- a/dlls/wined3d/arb_program_shader.c=0A=
+++ b/dlls/wined3d/arb_program_shader.c=0A=
@@ -3051,22 +3051,17 @@ static void state_arbfp_fog(DWORD state, =
IWineD3DStateBlockImpl *stateblock, Win=0A=
 =0A=
     if(!stateblock->renderState[WINED3DRS_FOGENABLE]) return;=0A=
 =0A=
-    if(use_vs(stateblock)=0A=
-       && ((IWineD3DVertexShaderImpl =
*)stateblock->vertexShader)->baseShader.reg_maps.fog) {=0A=
-        if( stateblock->renderState[WINED3DRS_FOGTABLEMODE] !=3D =
WINED3DFOG_NONE ) {=0A=
-            FIXME("vertex shader with table fog used\n");=0A=
-        }=0A=
-        context->last_was_foggy_shader =3D TRUE;=0A=
-        new_source =3D FOGSOURCE_VS;=0A=
-    } else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] =3D=3D =
WINED3DFOG_NONE) {=0A=
-        context->last_was_foggy_shader =3D FALSE;=0A=
-        if(stateblock->renderState[WINED3DRS_FOGVERTEXMODE] =3D=3D =
WINED3DFOG_NONE || context->last_was_rhw) {=0A=
-            new_source =3D FOGSOURCE_COORD;=0A=
+    if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] =3D=3D =
WINED3DFOG_NONE) {=0A=
+        if(use_vs(stateblock)) {=0A=
+            new_source =3D FOGSOURCE_VS;=0A=
         } else {=0A=
-            new_source =3D FOGSOURCE_FFP;=0A=
+            if(stateblock->renderState[WINED3DRS_FOGVERTEXMODE] =3D=3D =
WINED3DFOG_NONE || context->last_was_rhw) {=0A=
+                new_source =3D FOGSOURCE_COORD;=0A=
+            } else {=0A=
+                new_source =3D FOGSOURCE_FFP;=0A=
+            }=0A=
         }=0A=
     } else {=0A=
-        context->last_was_foggy_shader =3D FALSE;=0A=
         new_source =3D FOGSOURCE_FFP;=0A=
     }=0A=
     if(new_source !=3D context->fog_source) {=0A=
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c=0A=
index 0c84a50..3720060 100644=0A=
--- a/dlls/wined3d/state.c=0A=
+++ b/dlls/wined3d/state.c=0A=
@@ -1019,75 +1019,72 @@ void state_fog_fragpart(DWORD state, =
IWineD3DStateBlockImpl *stateblock, WineD3D=0A=
      * and 2) disables the fog computation (in either the fixed =
function or programmable=0A=
      * rasterizer) if using a vertex program.=0A=
      *=0A=
+     * D3D shaders can provide an explicit fog coordinate. This fog =
coordinate is used with=0A=
+     * D3DRS_FOGTABLEMODE=3D=3DD3DFOG_NONE. The FOGVERTEXMODE is =
ignored, d3d always uses linear=0A=
+     * fog with start=3D1.0 and end=3D0.0 in this case. This is similar =
to fog coordinates in=0A=
+     * the specular color, a vertex shader counts as pretransformed =
geometry in this case.=0A=
+     * There are some GL differences between specular fog coords and =
vertex shaders though.=0A=
+     *=0A=
+     * With table fog the vertex shader fog coordinate is ignored.=0A=
      *=0A=
      * If a fogtablemode and a fogvertexmode are specified, table fog =
is applied (with or=0A=
      * without shaders).=0A=
      */=0A=
 =0A=
-    if (use_vs(stateblock) && ((IWineD3DVertexShaderImpl =
*)stateblock->vertexShader)->baseShader.reg_maps.fog) {=0A=
-        if( stateblock->renderState[WINED3DRS_FOGTABLEMODE] !=3D =
WINED3DFOG_NONE ) {=0A=
-            FIXME("vertex shader with table fog used\n");=0A=
-        } else {=0A=
-            /* Set fog computation in the rasterizer to pass through =
the value (just blend it) */=0A=
-            glFogi(GL_FOG_MODE, GL_LINEAR);=0A=
-            checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");=0A=
-        }=0A=
-        context->last_was_foggy_shader =3D TRUE;=0A=
-        new_source =3D FOGSOURCE_VS;=0A=
-    }=0A=
     /* DX 7 sdk: "If both render states(vertex and table fog) are set =
to valid modes,=0A=
      * the system will apply only pixel(=3Dtable) fog effects."=0A=
      */=0A=
-    else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] =3D=3D =
WINED3DFOG_NONE) {=0A=
-        context->last_was_foggy_shader =3D FALSE;=0A=
-=0A=
-        switch (stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {=0A=
-            /* If processed vertices are used, fall through to the NONE =
case */=0A=
-            case WINED3DFOG_EXP:=0A=
-                if(!context->last_was_rhw) {=0A=
-                    glFogi(GL_FOG_MODE, GL_EXP);=0A=
-                    checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)");=0A=
-                    new_source =3D FOGSOURCE_FFP;=0A=
-                    break;=0A=
-                }=0A=
-                /* drop through */=0A=
-=0A=
-            case WINED3DFOG_EXP2:=0A=
-                if(!context->last_was_rhw) {=0A=
-                    glFogi(GL_FOG_MODE, GL_EXP2);=0A=
-                    checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)");=0A=
-                    new_source =3D FOGSOURCE_FFP;=0A=
-                    break;=0A=
-                }=0A=
-                /* drop through */=0A=
+    if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] =3D=3D =
WINED3DFOG_NONE) {=0A=
+        if(use_vs(stateblock)) {=0A=
+            glFogi(GL_FOG_MODE, GL_LINEAR);=0A=
+            checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");=0A=
+            new_source =3D FOGSOURCE_VS;=0A=
+        } else {=0A=
+            switch (stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {=0A=
+                /* If processed vertices are used, fall through to the =
NONE case */=0A=
+                case WINED3DFOG_EXP:=0A=
+                    if(!context->last_was_rhw) {=0A=
+                        glFogi(GL_FOG_MODE, GL_EXP);=0A=
+                        checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)");=0A=
+                        new_source =3D FOGSOURCE_FFP;=0A=
+                        break;=0A=
+                    }=0A=
+                    /* drop through */=0A=
+=0A=
+                case WINED3DFOG_EXP2:=0A=
+                    if(!context->last_was_rhw) {=0A=
+                        glFogi(GL_FOG_MODE, GL_EXP2);=0A=
+                        checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)");=0A=
+                        new_source =3D FOGSOURCE_FFP;=0A=
+                        break;=0A=
+                    }=0A=
+                    /* drop through */=0A=
+=0A=
+                case WINED3DFOG_LINEAR:=0A=
+                    if(!context->last_was_rhw) {=0A=
+                        glFogi(GL_FOG_MODE, GL_LINEAR);=0A=
+                        checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");=0A=
+                        new_source =3D FOGSOURCE_FFP;=0A=
+                        break;=0A=
+                    }=0A=
+                    /* drop through */=0A=
 =0A=
-            case WINED3DFOG_LINEAR:=0A=
-                if(!context->last_was_rhw) {=0A=
+                case WINED3DFOG_NONE:=0A=
+                    /* Both are none? According to msdn the alpha =
channel of the specular=0A=
+                     * color contains a fog factor. Set it in =
drawStridedSlow.=0A=
+                     * Same happens with Vertexfog on transformed =
vertices=0A=
+                     */=0A=
+                    new_source =3D FOGSOURCE_COORD;=0A=
                     glFogi(GL_FOG_MODE, GL_LINEAR);=0A=
                     checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");=0A=
-                    new_source =3D FOGSOURCE_FFP;=0A=
                     break;=0A=
-                }=0A=
-                /* drop through */=0A=
-=0A=
-            case WINED3DFOG_NONE:=0A=
-                /* Both are none? According to msdn the alpha channel =
of the specular=0A=
-                 * color contains a fog factor. Set it in =
drawStridedSlow.=0A=
-                 * Same happens with Vertexfog on transformed vertices=0A=
-                 */=0A=
-                new_source =3D FOGSOURCE_COORD;=0A=
-                glFogi(GL_FOG_MODE, GL_LINEAR);=0A=
-                checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");=0A=
-                break;=0A=
 =0A=
-            default:=0A=
-                FIXME("Unexpected WINED3DRS_FOGVERTEXMODE %d\n", =
stateblock->renderState[WINED3DRS_FOGVERTEXMODE]);=0A=
-                new_source =3D FOGSOURCE_FFP; /* Make the compiler =
happy */=0A=
+                default:=0A=
+                    FIXME("Unexpected WINED3DRS_FOGVERTEXMODE %d\n", =
stateblock->renderState[WINED3DRS_FOGVERTEXMODE]);=0A=
+                    new_source =3D FOGSOURCE_FFP; /* Make the compiler =
happy */=0A=
+            }=0A=
         }=0A=
     } else {=0A=
-        glHint(GL_FOG_HINT, GL_NICEST);=0A=
-        checkGLcall("glHint(GL_FOG_HINT, GL_NICEST)");=0A=
-        context->last_was_foggy_shader =3D FALSE;=0A=
         new_source =3D FOGSOURCE_FFP;=0A=
 =0A=
         switch (stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {=0A=
@@ -4337,15 +4334,6 @@ static void vertexdeclaration(DWORD state, =
IWineD3DStateBlockImpl *stateblock, W=0A=
     IWineD3DDeviceImpl *device =3D stateblock->wineD3DDevice;=0A=
     BOOL wasrhw =3D context->last_was_rhw;=0A=
 =0A=
-    if (useVertexShaderFunction)=0A=
-    {=0A=
-        if(((IWineD3DVertexShaderImpl =
*)stateblock->vertexShader)->baseShader.reg_maps.fog !=3D =
context->last_was_foggy_shader) {=0A=
-            updateFog =3D TRUE;=0A=
-        }=0A=
-    } else if(context->last_was_foggy_shader) {=0A=
-        updateFog =3D TRUE;=0A=
-    }=0A=
-=0A=
     transformed =3D device->strided_streams.position_transformed;=0A=
     if(transformed !=3D context->last_was_rhw && =
!useVertexShaderFunction) {=0A=
         updateFog =3D TRUE;=0A=
@@ -4411,8 +4399,11 @@ static void vertexdeclaration(DWORD state, =
IWineD3DStateBlockImpl *stateblock, W=0A=
             state_colormat(STATE_RENDER(WINED3DRS_COLORVERTEX), =
stateblock, context);=0A=
         }=0A=
 =0A=
-        if(context->last_was_vshader && !isStateDirty(context, =
STATE_RENDER(WINED3DRS_CLIPPLANEENABLE))) {=0A=
-            state_clipping(STATE_RENDER(WINED3DRS_CLIPPLANEENABLE), =
stateblock, context);=0A=
+        if(context->last_was_vshader) {=0A=
+            updateFog =3D TRUE;=0A=
+            if(!isStateDirty(context, =
STATE_RENDER(WINED3DRS_CLIPPLANEENABLE))) {=0A=
+                state_clipping(STATE_RENDER(WINED3DRS_CLIPPLANEENABLE), =
stateblock, context);=0A=
+            }=0A=
         }=0A=
         if(!isStateDirty(context, =
STATE_RENDER(WINED3DRS_NORMALIZENORMALS))) {=0A=
             state_normalize(STATE_RENDER(WINED3DRS_NORMALIZENORMALS), =
stateblock, context);=0A=
@@ -4446,6 +4437,7 @@ static void vertexdeclaration(DWORD state, =
IWineD3DStateBlockImpl *stateblock, W=0A=
                     =
transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock, =
context);=0A=
                 }=0A=
             }=0A=
+            updateFog =3D TRUE;=0A=
         }=0A=
     }=0A=
 =0A=
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c=0A=
index cc09584..3b6b63b 100644=0A=
--- a/dlls/wined3d/utils.c=0A=
+++ b/dlls/wined3d/utils.c=0A=
@@ -2096,17 +2096,21 @@ void gen_ffp_frag_op(IWineD3DStateBlockImpl =
*stateblock, struct ffp_frag_setting=0A=
     if(stateblock->renderState[WINED3DRS_FOGENABLE] =3D=3D FALSE) {=0A=
         settings->fog =3D FOG_OFF;=0A=
     } else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] =3D=3D =
WINED3DFOG_NONE) {=0A=
-        switch(stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {=0A=
-            case WINED3DFOG_NONE:=0A=
-            case WINED3DFOG_LINEAR:=0A=
-                settings->fog =3D FOG_LINEAR;=0A=
-                break;=0A=
-            case WINED3DFOG_EXP:=0A=
-                settings->fog =3D FOG_EXP;=0A=
-                break;=0A=
-            case WINED3DFOG_EXP2:=0A=
-                settings->fog =3D FOG_EXP2;=0A=
-                break;=0A=
+        if(use_vs(stateblock) || ((IWineD3DVertexDeclarationImpl *) =
stateblock->vertexDecl)->position_transformed) {=0A=
+            settings->fog =3D FOG_LINEAR;=0A=
+        } else {=0A=
+            switch(stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {=0A=
+                case WINED3DFOG_NONE:=0A=
+                case WINED3DFOG_LINEAR:=0A=
+                    settings->fog =3D FOG_LINEAR;=0A=
+                    break;=0A=
+                case WINED3DFOG_EXP:=0A=
+                    settings->fog =3D FOG_EXP;=0A=
+                    break;=0A=
+                case WINED3DFOG_EXP2:=0A=
+                    settings->fog =3D FOG_EXP2;=0A=
+                    break;=0A=
+            }=0A=
         }=0A=
     } else {=0A=
         switch(stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {=0A=
diff --git a/dlls/wined3d/wined3d_private.h =
b/dlls/wined3d/wined3d_private.h=0A=
index 0b5029f..ded6d48 100644=0A=
--- a/dlls/wined3d/wined3d_private.h=0A=
+++ b/dlls/wined3d/wined3d_private.h=0A=
@@ -802,7 +802,6 @@ struct WineD3DContext {=0A=
     WORD last_was_rhw : 1;              /* true iff last draw_primitive =
was in xyzrhw mode */=0A=
     WORD last_was_pshader : 1;=0A=
     WORD last_was_vshader : 1;=0A=
-    WORD last_was_foggy_shader : 1;=0A=
     WORD namedArraysLoaded : 1;=0A=
     WORD numberedArraysLoaded : 1;=0A=
     WORD last_was_blit : 1;=0A=
@@ -811,7 +810,7 @@ struct WineD3DContext {=0A=
     WORD isPBuffer : 1;=0A=
     WORD fog_enabled : 1;=0A=
     WORD num_untracked_materials : 2;   /* Max value 2 */=0A=
-    WORD padding : 2;=0A=
+    WORD padding : 3;=0A=
     BYTE texShaderBumpMap;              /* MAX_TEXTURES, 8 */=0A=
     BYTE lastWasPow2Texture;            /* MAX_TEXTURES, 8 */=0A=
     DWORD                   numbered_array_mask;=0A=
-- =0A=
1.6.0.6=0A=
=0A=

------=_NextPart_000_0008_01C97515.B93AA0C0--




More information about the wine-patches mailing list