[PATCH 5/5] wined3d: Don't use the builtin FFP uniforms for fog parameters.

Matteo Bruni mbruni at codeweavers.com
Thu Jun 4 17:37:33 CDT 2015


---
 dlls/wined3d/glsl_shader.c     | 81 ++++++++++++++++++++++++++++++++++++------
 dlls/wined3d/wined3d_private.h | 19 +++++-----
 2 files changed, 81 insertions(+), 19 deletions(-)

diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index a32e91d..fd4e697 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -171,6 +171,10 @@ struct glsl_ps_program
     GLint tss_constant_location[MAX_TEXTURES];
     GLint tex_factor_location;
     GLint specular_enable_location;
+    GLint fog_color_location;
+    GLint fog_density_location;
+    GLint fog_end_location;
+    GLint fog_scale_location;
     GLint ycorrection_location;
     GLint np2_fixup_location;
     GLint color_key_location;
@@ -1229,6 +1233,29 @@ static void shader_glsl_pointsize_uniform(const struct wined3d_context *context,
     checkGLcall("glUniform1f");
 }
 
+static void shader_glsl_load_fog_uniform(const struct wined3d_context *context,
+        const struct wined3d_state *state, struct glsl_shader_prog_link *prog)
+{
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+    float start, end, scale;
+    union
+    {
+        DWORD d;
+        float f;
+    } tmpvalue;
+    float col[4];
+
+    D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_FOGCOLOR], col);
+    GL_EXTCALL(glUniform4fv(prog->ps.fog_color_location, 1, col));
+    tmpvalue.d = state->render_states[WINED3D_RS_FOGDENSITY];
+    GL_EXTCALL(glUniform1f(prog->ps.fog_density_location, tmpvalue.f));
+    get_fog_start_end(context, state, &start, &end);
+    scale = 1.0f / (end - start);
+    GL_EXTCALL(glUniform1f(prog->ps.fog_end_location, end));
+    GL_EXTCALL(glUniform1f(prog->ps.fog_scale_location, scale));
+    checkGLcall("fog emulation uniforms");
+}
+
 /* Context activation is done by the caller (state handler). */
 static void shader_glsl_load_color_key_constant(const struct glsl_ps_program *ps,
         const struct wined3d_gl_info *gl_info, const struct wined3d_state *state)
@@ -1402,6 +1429,9 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context
         checkGLcall("fixed function uniforms");
     }
 
+    if (update_mask & WINED3D_SHADER_CONST_PS_FOG)
+        shader_glsl_load_fog_uniform(context, state, prog);
+
     if (priv->next_constant_version == UINT_MAX)
     {
         TRACE("Max constant version reached, resetting to 0.\n");
@@ -1747,6 +1777,16 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
     }
     else if (version->type == WINED3D_SHADER_TYPE_PIXEL)
     {
+        if (version->major < 3 || ps_args->vp_mode != vertexshader)
+        {
+            shader_addline(buffer, "uniform struct\n{\n");
+            shader_addline(buffer, "    vec4 color;\n");
+            shader_addline(buffer, "    float density;\n");
+            shader_addline(buffer, "    float end;\n");
+            shader_addline(buffer, "    float scale;\n");
+            shader_addline(buffer, "} ffp_fog;\n");
+        }
+
         if (version->major >= 3)
         {
             UINT in_count = min(vec4_varyings(version->major, gl_info), shader->limits->packed_input);
@@ -5069,17 +5109,16 @@ static void shader_glsl_generate_fog_code(struct wined3d_string_buffer *buffer,
             return;
 
         case WINED3D_FFP_PS_FOG_LINEAR:
-            shader_addline(buffer, "float Fog = (gl_Fog.end - gl_FogFragCoord) * gl_Fog.scale;\n");
+            shader_addline(buffer, "float fog = (ffp_fog.end - gl_FogFragCoord) * ffp_fog.scale;\n");
             break;
 
         case WINED3D_FFP_PS_FOG_EXP:
-            /* Fog = e^-(gl_Fog.density * gl_FogFragCoord) */
-            shader_addline(buffer, "float Fog = exp(-gl_Fog.density * gl_FogFragCoord);\n");
+            shader_addline(buffer, "float fog = exp(-ffp_fog.density * gl_FogFragCoord);\n");
             break;
 
         case WINED3D_FFP_PS_FOG_EXP2:
-            /* Fog = e^-((gl_Fog.density * gl_FogFragCoord)^2) */
-            shader_addline(buffer, "float Fog = exp(-gl_Fog.density * gl_Fog.density * gl_FogFragCoord * gl_FogFragCoord);\n");
+            shader_addline(buffer, "float fog = exp(-ffp_fog.density * ffp_fog.density"
+                    " * gl_FogFragCoord * gl_FogFragCoord);\n");
             break;
 
         default:
@@ -5087,7 +5126,8 @@ static void shader_glsl_generate_fog_code(struct wined3d_string_buffer *buffer,
             return;
     }
 
-    shader_addline(buffer, "gl_FragData[0].xyz = mix(gl_Fog.color.xyz, gl_FragData[0].xyz, clamp(Fog, 0.0, 1.0));\n");
+    shader_addline(buffer, "gl_FragData[0].xyz = mix(ffp_fog.color.xyz, gl_FragData[0].xyz,"
+            " clamp(fog, 0.0, 1.0));\n");
 }
 
 /* Context activation is done by the caller. */
@@ -6187,6 +6227,13 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv *
         shader_addline(buffer, ";\n");
     }
 
+    shader_addline(buffer, "uniform struct\n{\n");
+    shader_addline(buffer, "    vec4 color;\n");
+    shader_addline(buffer, "    float density;\n");
+    shader_addline(buffer, "    float end;\n");
+    shader_addline(buffer, "    float scale;\n");
+    shader_addline(buffer, "} ffp_fog;\n");
+
     shader_addline(buffer, "void main()\n{\n");
 
     if (lowest_disabled_stage < 7 && settings->emul_clipplanes)
@@ -6569,6 +6616,12 @@ static void shader_glsl_init_ps_uniform_locations(const struct wined3d_gl_info *
 
     ps->tex_factor_location = GL_EXTCALL(glGetUniformLocation(program_id, "tex_factor"));
     ps->specular_enable_location = GL_EXTCALL(glGetUniformLocation(program_id, "specular_enable"));
+
+    ps->fog_color_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_fog.color"));
+    ps->fog_density_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_fog.density"));
+    ps->fog_end_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_fog.end"));
+    ps->fog_scale_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_fog.scale"));
+
     ps->np2_fixup_location = GL_EXTCALL(glGetUniformLocation(program_id, "ps_samplerNP2Fixup"));
     ps->ycorrection_location = GL_EXTCALL(glGetUniformLocation(program_id, "ycorrection"));
     ps->color_key_location = GL_EXTCALL(glGetUniformLocation(program_id, "color_key"));
@@ -6890,6 +6943,8 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
             }
         }
 
+        if (entry->ps.fog_color_location != -1)
+            entry->constant_update_mask |= WINED3D_SHADER_CONST_PS_FOG;
         if (entry->ps.np2_fixup_location != -1)
             entry->constant_update_mask |= WINED3D_SHADER_CONST_PS_NP2_FIXUP;
         if (entry->ps.color_key_location != -1)
@@ -8163,6 +8218,12 @@ static void glsl_fragment_pipe_shader(struct wined3d_context *context,
     context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_PIXEL;
 }
 
+static void glsl_fragment_pipe_fogparams(struct wined3d_context *context,
+        const struct wined3d_state *state, DWORD state_id)
+{
+    context->constant_update_mask |= WINED3D_SHADER_CONST_PS_FOG;
+}
+
 static void glsl_fragment_pipe_fog(struct wined3d_context *context,
         const struct wined3d_state *state, DWORD state_id)
 {
@@ -8193,7 +8254,7 @@ static void glsl_fragment_pipe_fog(struct wined3d_context *context,
     if (new_source != context->fog_source || fogstart == fogend)
     {
         context->fog_source = new_source;
-        state_fogstartend(context, state, STATE_RENDER(WINED3D_RS_FOGSTART));
+        context->constant_update_mask |= WINED3D_SHADER_CONST_PS_FOG;
     }
 }
 
@@ -8338,12 +8399,12 @@ static const struct StateEntryTemplate glsl_fragment_pipe_state_template[] =
     {STATE_RENDER(WINED3D_RS_FOGENABLE),                        {STATE_RENDER(WINED3D_RS_FOGENABLE),                         glsl_fragment_pipe_fog                 }, WINED3D_GL_EXT_NONE },
     {STATE_RENDER(WINED3D_RS_FOGTABLEMODE),                     {STATE_RENDER(WINED3D_RS_FOGENABLE),                         NULL                                   }, WINED3D_GL_EXT_NONE },
     {STATE_RENDER(WINED3D_RS_FOGVERTEXMODE),                    {STATE_RENDER(WINED3D_RS_FOGENABLE),                         NULL                                   }, WINED3D_GL_EXT_NONE },
-    {STATE_RENDER(WINED3D_RS_FOGSTART),                         {STATE_RENDER(WINED3D_RS_FOGSTART),                          state_fogstartend                      }, WINED3D_GL_EXT_NONE },
+    {STATE_RENDER(WINED3D_RS_FOGSTART),                         {STATE_RENDER(WINED3D_RS_FOGSTART),                          glsl_fragment_pipe_fogparams           }, WINED3D_GL_EXT_NONE },
     {STATE_RENDER(WINED3D_RS_FOGEND),                           {STATE_RENDER(WINED3D_RS_FOGSTART),                          NULL                                   }, WINED3D_GL_EXT_NONE },
     {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE),                  {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE),                   state_srgbwrite                        }, ARB_FRAMEBUFFER_SRGB},
     {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE),                  {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL),                    NULL                                   }, WINED3D_GL_EXT_NONE },
-    {STATE_RENDER(WINED3D_RS_FOGCOLOR),                         {STATE_RENDER(WINED3D_RS_FOGCOLOR),                          state_fogcolor                         }, WINED3D_GL_EXT_NONE },
-    {STATE_RENDER(WINED3D_RS_FOGDENSITY),                       {STATE_RENDER(WINED3D_RS_FOGDENSITY),                        state_fogdensity                       }, WINED3D_GL_EXT_NONE },
+    {STATE_RENDER(WINED3D_RS_FOGCOLOR),                         {STATE_RENDER(WINED3D_RS_FOGCOLOR),                          glsl_fragment_pipe_fogparams           }, WINED3D_GL_EXT_NONE },
+    {STATE_RENDER(WINED3D_RS_FOGDENSITY),                       {STATE_RENDER(WINED3D_RS_FOGDENSITY),                        glsl_fragment_pipe_fogparams           }, WINED3D_GL_EXT_NONE },
     {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE),                {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE),                 glsl_fragment_pipe_shader              }, ARB_POINT_SPRITE    },
     {STATE_TEXTURESTAGE(0,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_fragment_pipe_tex_transform       }, WINED3D_GL_EXT_NONE },
     {STATE_TEXTURESTAGE(1,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_fragment_pipe_tex_transform       }, WINED3D_GL_EXT_NONE },
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 93cfd9e..7438f7f 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -305,15 +305,16 @@ enum wined3d_shader_resource_type
 #define WINED3D_SHADER_CONST_PS_I           0x00000040
 #define WINED3D_SHADER_CONST_PS_B           0x00000080
 #define WINED3D_SHADER_CONST_PS_BUMP_ENV    0x00000100
-#define WINED3D_SHADER_CONST_PS_Y_CORR      0x00000200
-#define WINED3D_SHADER_CONST_PS_NP2_FIXUP   0x00000400
-#define WINED3D_SHADER_CONST_FFP_MODELVIEW  0x00000800
-#define WINED3D_SHADER_CONST_FFP_PROJ       0x00001000
-#define WINED3D_SHADER_CONST_FFP_TEXMATRIX  0x00002000
-#define WINED3D_SHADER_CONST_FFP_MATERIAL   0x00004000
-#define WINED3D_SHADER_CONST_FFP_LIGHTS     0x00008000
-#define WINED3D_SHADER_CONST_FFP_PS         0x00010000
-#define WINED3D_SHADER_CONST_FFP_COLOR_KEY  0x00020000
+#define WINED3D_SHADER_CONST_PS_FOG         0x00000200
+#define WINED3D_SHADER_CONST_PS_Y_CORR      0x00000400
+#define WINED3D_SHADER_CONST_PS_NP2_FIXUP   0x00000800
+#define WINED3D_SHADER_CONST_FFP_MODELVIEW  0x00001000
+#define WINED3D_SHADER_CONST_FFP_PROJ       0x00002000
+#define WINED3D_SHADER_CONST_FFP_TEXMATRIX  0x00004000
+#define WINED3D_SHADER_CONST_FFP_MATERIAL   0x00008000
+#define WINED3D_SHADER_CONST_FFP_LIGHTS     0x00010000
+#define WINED3D_SHADER_CONST_FFP_PS         0x00020000
+#define WINED3D_SHADER_CONST_FFP_COLOR_KEY  0x00040000
 
 enum wined3d_shader_register_type
 {
-- 
2.3.6




More information about the wine-patches mailing list