[PATCH] WineD3D: Make pixelshaders disable fog properly=0A=

Stefan Doesinger stefan at codeweavers.com
Mon Dec 15 19:35:40 CST 2008


=0A=
This is a first step towards cleaning up the fog mess. The fog parameter =
is=0A=
added to the pixelshader compile args structure. That way multiple =
pshaders=0A=
are compiled for different fog settings, and the pixel shader can remove =
the=0A=
fog line if fog is not enabled. That way we don't need special fog start =
and=0A=
end settings, and this allows us to implement EXP and EXP2 fog in the =
future=0A=
too.=0A=
---=0A=
 dlls/wined3d/arb_program_shader.c |   42 =
+++++++++++++++++++++++++-----------=0A=
 dlls/wined3d/glsl_shader.c        |   18 ++++++++++++---=0A=
 dlls/wined3d/pixelshader.c        |   26 ++++++++++++++++++++++-=0A=
 dlls/wined3d/state.c              |   22 -------------------=0A=
 dlls/wined3d/wined3d_private.h    |   15 ++++++++-----=0A=
 5 files changed, 77 insertions(+), 46 deletions(-)=0A=
=0A=
diff --git a/dlls/wined3d/arb_program_shader.c =
b/dlls/wined3d/arb_program_shader.c=0A=
index 612093f..93ae641 100644=0A=
--- a/dlls/wined3d/arb_program_shader.c=0A=
+++ b/dlls/wined3d/arb_program_shader.c=0A=
@@ -1890,27 +1890,43 @@ static GLuint =
shader_arb_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUF=0A=
     shader_generate_arb_declarations( (IWineD3DBaseShader*) This, =
reg_maps, buffer, &GLINFO_LOCATION);=0A=
 =0A=
     /* We need two variables for fog blending */=0A=
-    shader_addline(buffer, "TEMP TMP_FOG;\n");=0A=
+    if(args->fog !=3D FOG_OFF) shader_addline(buffer, "TEMP =
TMP_FOG;\n");=0A=
     if (shader_version >=3D WINED3DPS_VERSION(2,0)) =
shader_addline(buffer, "TEMP TMP_COLOR;\n");=0A=
 =0A=
     /* Base Shader Body */=0A=
     shader_generate_main( (IWineD3DBaseShader*) This, buffer, reg_maps, =
function);=0A=
 =0A=
-    /* calculate fog and blend it=0A=
-     * NOTE: state.fog.params.y and state.fog.params.z don't hold fog =
start s and end e but=0A=
-     * -1/(e-s) and e/(e-s) respectively.=0A=
-     */=0A=
-    shader_addline(buffer, "MAD_SAT TMP_FOG, fragment.fogcoord, =
state.fog.params.y, state.fog.params.z;\n");=0A=
-=0A=
-    fragcolor =3D (shader_version < WINED3DPS_VERSION(2,0)) ? "R0" : =
"TMP_COLOR";=0A=
-=0A=
+    if (shader_version < WINED3DPS_VERSION(2,0)) {=0A=
+        fragcolor =3D "R0";=0A=
+    } else {=0A=
+        fragcolor =3D "TMP_COLOR";=0A=
+    }=0A=
     if(args->srgb_correction) {=0A=
         arbfp_add_sRGB_correction(buffer, fragcolor, "TMP", "TMP2", =
"TA", "TB");=0A=
     }=0A=
-    if (shader_version < WINED3DPS_VERSION(3,0))=0A=
-    {=0A=
-        shader_addline(buffer, "LRP result.color.rgb, TMP_FOG.x, %s, =
state.fog.color;\n", fragcolor);=0A=
-        shader_addline(buffer, "MOV result.color.a, %s.a;\n", =
fragcolor);=0A=
+    if (shader_version < WINED3DPS_VERSION(3,0)) {=0A=
+        /* calculate fog and blend it=0A=
+         * NOTE: state.fog.params.y and state.fog.params.z don't hold =
fog start s and end e but=0A=
+         * -1/(e-s) and e/(e-s) respectively.=0A=
+         */=0A=
+        switch(args->fog) {=0A=
+            case FOG_OFF:=0A=
+                shader_addline(buffer, "MOV result.color, %s;\n", =
fragcolor);=0A=
+                break;=0A=
+            case FOG_LINEAR:=0A=
+                shader_addline(buffer, "MAD_SAT TMP_FOG, =
fragment.fogcoord, state.fog.params.y, state.fog.params.z;\n");=0A=
+                shader_addline(buffer, "LRP result.color.rgb, =
TMP_FOG.x, %s, state.fog.color;\n", fragcolor);=0A=
+                shader_addline(buffer, "MOV result.color.a, %s.a;\n", =
fragcolor);=0A=
+                break;=0A=
+            case FOG_EXP:=0A=
+                FIXME("Implement EXP fog in ARB\n");=0A=
+                shader_addline(buffer, "MOV result.color, %s;\n", =
fragcolor);=0A=
+                break;=0A=
+            case FOG_EXP2:=0A=
+                FIXME("Implement EXP2 fog in ARB\n");=0A=
+                shader_addline(buffer, "MOV result.color, %s;\n", =
fragcolor);=0A=
+                break;=0A=
+        }=0A=
     }=0A=
 =0A=
     shader_addline(buffer, "END\n");=0A=
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c=0A=
index 8dd7672..7edfa1c 100644=0A=
--- a/dlls/wined3d/glsl_shader.c=0A=
+++ b/dlls/wined3d/glsl_shader.c=0A=
@@ -3637,10 +3637,20 @@ static GLuint =
shader_glsl_generate_pshader(IWineD3DPixelShader *iface, SHADER_BU=0A=
      * NOTE: gl_Fog.start and gl_Fog.end don't hold fog start s and end =
e but=0A=
      * -1/(e-s) and e/(e-s) respectively.=0A=
      */=0A=
-    if (reg_maps->shader_version < WINED3DPS_VERSION(3,0))=0A=
-    {=0A=
-        shader_addline(buffer, "float Fog =3D clamp(gl_FogFragCoord * =
gl_Fog.start + gl_Fog.end, 0.0, 1.0);\n");=0A=
-        shader_addline(buffer, "%s.xyz =3D mix(gl_Fog.color.xyz, =
%s.xyz, Fog);\n", fragcolor, fragcolor);=0A=
+    if(reg_maps->shader_version < WINED3DPS_VERSION(3,0)) {=0A=
+        switch(args->fog) {=0A=
+            case FOG_OFF: break;=0A=
+            case FOG_LINEAR:=0A=
+                shader_addline(buffer, "float Fog =3D =
clamp(gl_FogFragCoord * gl_Fog.start + gl_Fog.end, 0.0, 1.0);\n");=0A=
+                shader_addline(buffer, "%s.xyz =3D =
mix(gl_Fog.color.xyz, %s.xyz, Fog);\n", fragcolor, fragcolor);=0A=
+                break;=0A=
+            case FOG_EXP:=0A=
+                FIXME("Implement EXP fog in glsl\n");=0A=
+                break;=0A=
+            case FOG_EXP2:=0A=
+                FIXME("Implement EXP2 fog in glsl\n");=0A=
+                break;=0A=
+        }=0A=
     }=0A=
 =0A=
     shader_addline(buffer, "}\n");=0A=
diff --git a/dlls/wined3d/pixelshader.c b/dlls/wined3d/pixelshader.c=0A=
index 94a45cf..15392d8 100644=0A=
--- a/dlls/wined3d/pixelshader.c=0A=
+++ b/dlls/wined3d/pixelshader.c=0A=
@@ -463,9 +463,9 @@ void find_ps_compile_args(IWineD3DPixelShaderImpl =
*shader, IWineD3DStateBlockImp=0A=
     UINT i, sampler;=0A=
     IWineD3DBaseTextureImpl *tex;=0A=
 =0A=
+    memset(args, 0, sizeof(*args)); /* FIXME: Make sure all bits are =
set */=0A=
     args->srgb_correction =3D =
stateblock->renderState[WINED3DRS_SRGBWRITEENABLE] ? 1 : 0;=0A=
 =0A=
-    memset(args->color_fixup, 0, sizeof(args->color_fixup));=0A=
     for(i =3D 0; i < shader->baseShader.num_sampled_samplers; i++) {=0A=
         sampler =3D shader->baseShader.sampled_samplers[i];=0A=
         tex =3D (IWineD3DBaseTextureImpl *) =
stateblock->textures[sampler];=0A=
@@ -484,8 +484,32 @@ void find_ps_compile_args(IWineD3DPixelShaderImpl =
*shader, IWineD3DStateBlockImp=0A=
         } else {=0A=
             args->vp_mode =3D fixedfunction;=0A=
         }=0A=
+        args->fog =3D FOG_OFF;=0A=
     } else {=0A=
         args->vp_mode =3D vertexshader;=0A=
+        if(stateblock->renderState[WINED3DRS_FOGENABLE]) {=0A=
+            switch(stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {=0A=
+                case WINED3DFOG_NONE:=0A=
+                    if(((IWineD3DDeviceImpl *) =
shader->baseShader.device)->strided_streams.u.s.position_transformed ||=0A=
+                         use_vs((IWineD3DDeviceImpl *) =
shader->baseShader.device)) {=0A=
+                        args->fog =3D FOG_LINEAR;=0A=
+                        break;=0A=
+                    }=0A=
+                    =
switch(stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {=0A=
+                        case WINED3DFOG_NONE: /* Drop through */=0A=
+                        case WINED3DFOG_LINEAR: args->fog =3D =
FOG_LINEAR; break;=0A=
+                        case WINED3DFOG_EXP:    args->fog =3D FOG_EXP;  =
  break;=0A=
+                        case WINED3DFOG_EXP2:   args->fog =3D FOG_EXP2; =
  break;=0A=
+                    }=0A=
+                    break;=0A=
+=0A=
+                case WINED3DFOG_LINEAR: args->fog =3D FOG_LINEAR; break;=0A=
+                case WINED3DFOG_EXP:    args->fog =3D FOG_EXP;    break;=0A=
+                case WINED3DFOG_EXP2:   args->fog =3D FOG_EXP2;   break;=0A=
+            }=0A=
+        } else {=0A=
+            args->fog =3D FOG_OFF;=0A=
+        }=0A=
     }=0A=
 }=0A=
 =0A=
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c=0A=
index 0bf357d..e4c819d 100644=0A=
--- a/dlls/wined3d/state.c=0A=
+++ b/dlls/wined3d/state.c=0A=
@@ -911,18 +911,6 @@ static void state_fog(DWORD state, =
IWineD3DStateBlockImpl *stateblock, WineD3DCo=0A=
         /* No fog? Disable it, and we're done :-) */=0A=
         glDisable(GL_FOG);=0A=
         checkGLcall("glDisable GL_FOG");=0A=
-        if (use_ps(stateblock->wineD3DDevice)=0A=
-                && ps_impl->baseShader.reg_maps.shader_version < =
WINED3DPS_VERSION(3,0))=0A=
-        {=0A=
-            /* disable fog in the pixel shader=0A=
-             * NOTE: For pixel shader, GL_FOG_START and GL_FOG_END =
don't hold fog start s and end e but=0A=
-             * -1/(e-s) and e/(e-s) respectively.=0A=
-             */=0A=
-            glFogf(GL_FOG_START, 0.0f);=0A=
-            checkGLcall("glFogf(GL_FOG_START, fogstart)");=0A=
-            glFogf(GL_FOG_END, 1.0f);=0A=
-            checkGLcall("glFogf(GL_FOG_END, fogend)");=0A=
-        }=0A=
         return;=0A=
     }=0A=
 =0A=
@@ -1168,16 +1156,6 @@ static void state_fog(DWORD state, =
IWineD3DStateBlockImpl *stateblock, WineD3DCo=0A=
     } else {=0A=
         glDisable(GL_FOG);=0A=
         checkGLcall("glDisable GL_FOG");=0A=
-        if( use_ps(stateblock->wineD3DDevice) ) {=0A=
-            /* disable fog in the pixel shader=0A=
-             * NOTE: For pixel shader, GL_FOG_START and GL_FOG_END =
don't hold fog start s and end e but=0A=
-             * -1/(e-s) and e/(e-s) respectively.=0A=
-             */=0A=
-            glFogf(GL_FOG_START, 0.0f);=0A=
-            checkGLcall("glFogf(GL_FOG_START, fogstart)");=0A=
-            glFogf(GL_FOG_END, 1.0f);=0A=
-            checkGLcall("glFogf(GL_FOG_END, fogend)");=0A=
-        }=0A=
     }=0A=
 }=0A=
 =0A=
diff --git a/dlls/wined3d/wined3d_private.h =
b/dlls/wined3d/wined3d_private.h=0A=
index f7e617e..9f75939 100644=0A=
--- a/dlls/wined3d/wined3d_private.h=0A=
+++ b/dlls/wined3d/wined3d_private.h=0A=
@@ -438,6 +438,13 @@ struct stb_const_desc {=0A=
     UINT                    const_num;=0A=
 };=0A=
 =0A=
+enum fogmode {=0A=
+    FOG_OFF,=0A=
+    FOG_LINEAR,=0A=
+    FOG_EXP,=0A=
+    FOG_EXP2=0A=
+};=0A=
+=0A=
 /* Stateblock dependent parameters which have to be hardcoded=0A=
  * into the shader code=0A=
  */=0A=
@@ -445,6 +452,7 @@ struct ps_compile_args {=0A=
     struct color_fixup_desc     color_fixup[MAX_FRAGMENT_SAMPLERS];=0A=
     BOOL                        srgb_correction;=0A=
     enum vertexprocessing_mode  vp_mode;=0A=
+    enum fogmode                fog;=0A=
     /* Projected textures(ps 1.0-1.3) */=0A=
     /* Texture types(2D, Cube, 3D) in ps 1.x */=0A=
 };=0A=
@@ -973,12 +981,7 @@ struct texture_stage_op=0A=
 =0A=
 struct ffp_frag_settings {=0A=
     struct texture_stage_op     op[MAX_TEXTURES];=0A=
-    enum {=0A=
-        FOG_OFF,=0A=
-        FOG_LINEAR,=0A=
-        FOG_EXP,=0A=
-        FOG_EXP2=0A=
-    } fog;=0A=
+    enum fogmode fog;=0A=
     /* Use an int instead of a char to get dword alignment */=0A=
     unsigned int sRGB_write;=0A=
 };=0A=
-- =0A=
1.5.6.4=0A=
=0A=

------=_NextPart_000_0039_01C9613A.B8A7C550--




More information about the wine-patches mailing list