Matteo Bruni : wined3d: Use a separate STATE_VDECL state handler in the GLSL pipeline.

Alexandre Julliard julliard at wine.codeweavers.com
Thu Mar 19 09:59:02 CDT 2015


Module: wine
Branch: master
Commit: 99f3e835ac0c3fd873b127e8c227b9e44fa98ae2
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=99f3e835ac0c3fd873b127e8c227b9e44fa98ae2

Author: Matteo Bruni <mbruni at codeweavers.com>
Date:   Wed Mar 18 21:07:36 2015 +0100

wined3d: Use a separate STATE_VDECL state handler in the GLSL pipeline.

It's mostly a copy of vertexdeclaration() from state.c, with a few
differences due to the new function being private to the GLSL backend
(e.g. d3d_info.vs_clipping is known to be TRUE) and the fragment fog
update part being split out.

---

 dlls/wined3d/glsl_shader.c     | 89 ++++++++++++++++++++++++++++++++++++++++--
 dlls/wined3d/state.c           |  6 +--
 dlls/wined3d/wined3d_private.h |  6 ++-
 3 files changed, 93 insertions(+), 8 deletions(-)

diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index b6d3156..00c7318 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -6951,6 +6951,81 @@ static void glsl_vertex_pipe_shader(struct wined3d_context *context,
     context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_VERTEX;
 }
 
+static void glsl_vertex_pipe_vdecl(struct wined3d_context *context,
+        const struct wined3d_state *state, DWORD state_id)
+{
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+    BOOL transformed = context->stream_info.position_transformed;
+    BOOL wasrhw = context->last_was_rhw;
+    unsigned int i;
+
+    context->last_was_rhw = transformed;
+
+    if (!use_vs(state))
+    {
+        if (context->last_was_vshader)
+        {
+            for (i = 0; i < gl_info->limits.clipplanes; ++i)
+                clipplane(context, state, STATE_CLIPPLANE(i));
+        }
+
+        if (transformed != wasrhw)
+        {
+            if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)))
+                    && !isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_VIEW)))
+                transform_world(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)));
+            if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION))
+                    && !isStateDirty(context, STATE_VIEWPORT))
+                transform_projection(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
+        }
+
+        for (i = 0; i < MAX_TEXTURES; ++i)
+        {
+            if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + i)))
+                transform_texture(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS));
+        }
+
+        if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_LIGHTING)))
+            state_lighting(context, state, STATE_RENDER(WINED3D_RS_LIGHTING));
+        if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_NORMALIZENORMALS)))
+            state_normalize(context, state, STATE_RENDER(WINED3D_RS_NORMALIZENORMALS));
+
+        /* Because of settings->texcoords, we have to always regenerate the
+         * vertex shader on a vdecl change.
+         * TODO: Just always output all the texcoords when there are enough
+         * varyings available to drop the dependency. */
+        context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_VERTEX;
+
+        if (use_ps(state)
+                && state->shader[WINED3D_SHADER_TYPE_PIXEL]->reg_maps.shader_version.major == 1
+                && state->shader[WINED3D_SHADER_TYPE_PIXEL]->reg_maps.shader_version.minor <= 3)
+            context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_PIXEL;
+    }
+    else
+    {
+        if (!context->last_was_vshader)
+        {
+            /* Vertex shader clipping ignores the view matrix. Update all clipplanes. */
+            for (i = 0; i < gl_info->limits.clipplanes; ++i)
+                clipplane(context, state, STATE_CLIPPLANE(i));
+        }
+    }
+
+    if (transformed != wasrhw && !isStateDirty(context, STATE_RENDER(WINED3D_RS_ZENABLE)))
+        context_apply_state(context, state, STATE_RENDER(WINED3D_RS_ZENABLE));
+
+    context->last_was_vshader = use_vs(state);
+}
+
+static void glsl_vertex_pipe_vs(struct wined3d_context *context,
+        const struct wined3d_state *state, DWORD state_id)
+{
+    context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_VERTEX;
+    /* Different vertex shaders potentially require a different vertex attributes setup. */
+    if (!isStateDirty(context, STATE_VDECL))
+        context_apply_state(context, state, STATE_VDECL);
+}
+
 static void glsl_vertex_pipe_projection(struct wined3d_context *context,
         const struct wined3d_state *state, DWORD state_id)
 {
@@ -6963,8 +7038,8 @@ static void glsl_vertex_pipe_projection(struct wined3d_context *context,
 
 static const struct StateEntryTemplate glsl_vertex_pipe_vp_states[] =
 {
-    {STATE_VDECL,                                                {STATE_VDECL,                                                vertexdeclaration      }, WINED3D_GL_EXT_NONE          },
-    {STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX),                   {STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX),                   vertexdeclaration      }, WINED3D_GL_EXT_NONE          },
+    {STATE_VDECL,                                                {STATE_VDECL,                                                glsl_vertex_pipe_vdecl }, WINED3D_GL_EXT_NONE          },
+    {STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX),                   {STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX),                   glsl_vertex_pipe_vs    }, WINED3D_GL_EXT_NONE          },
     {STATE_MATERIAL,                                             {STATE_RENDER(WINED3D_RS_SPECULARENABLE),                    NULL                   }, WINED3D_GL_EXT_NONE          },
     {STATE_RENDER(WINED3D_RS_SPECULARENABLE),                    {STATE_RENDER(WINED3D_RS_SPECULARENABLE),                    state_specularenable   }, WINED3D_GL_EXT_NONE          },
     /* Clip planes */
@@ -7242,7 +7317,7 @@ static void glsl_fragment_pipe_fog(struct wined3d_context *context,
     {
         if (use_vshader)
             new_source = FOGSOURCE_VS;
-        else if (state->render_states[WINED3D_RS_FOGVERTEXMODE] == WINED3D_FOG_NONE || context->last_was_rhw)
+        else if (state->render_states[WINED3D_RS_FOGVERTEXMODE] == WINED3D_FOG_NONE || context->stream_info.position_transformed)
             new_source = FOGSOURCE_COORD;
         else
             new_source = FOGSOURCE_FFP;
@@ -7259,6 +7334,13 @@ static void glsl_fragment_pipe_fog(struct wined3d_context *context,
     }
 }
 
+static void glsl_fragment_pipe_vdecl(struct wined3d_context *context,
+        const struct wined3d_state *state, DWORD state_id)
+{
+    if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_FOGENABLE)))
+        glsl_fragment_pipe_fog(context, state, state_id);
+}
+
 static void glsl_fragment_pipe_tex_transform(struct wined3d_context *context,
         const struct wined3d_state *state, DWORD state_id)
 {
@@ -7273,6 +7355,7 @@ static void glsl_fragment_pipe_invalidate_constants(struct wined3d_context *cont
 
 static const struct StateEntryTemplate glsl_fragment_pipe_state_template[] =
 {
+    {STATE_VDECL,                                               {STATE_VDECL,                                                glsl_fragment_pipe_vdecl               }, WINED3D_GL_EXT_NONE },
     {STATE_RENDER(WINED3D_RS_TEXTUREFACTOR),                    {STATE_RENDER(WINED3D_RS_TEXTUREFACTOR),                     glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE },
     {STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP),               {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL),                    NULL                                   }, WINED3D_GL_EXT_NONE },
     {STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG1),             {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL),                    NULL                                   }, WINED3D_GL_EXT_NONE },
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index f434a99..e5d6ca9 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -74,7 +74,7 @@ static void state_fillmode(struct wined3d_context *context, const struct wined3d
     }
 }
 
-static void state_lighting(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+void state_lighting(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
 {
     const struct wined3d_gl_info *gl_info = context->gl_info;
 
@@ -1392,7 +1392,7 @@ static void state_linepattern(struct wined3d_context *context, const struct wine
     }
 }
 
-static void state_normalize(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+void state_normalize(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
 {
     const struct wined3d_gl_info *gl_info = context->gl_info;
 
@@ -4627,7 +4627,7 @@ static void vdecl_miscpart(struct wined3d_context *context, const struct wined3d
     streamsrc(context, state, STATE_STREAMSRC);
 }
 
-void vertexdeclaration(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+static void vertexdeclaration(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
 {
     const struct wined3d_gl_info *gl_info = context->gl_info;
     BOOL useVertexShaderFunction = use_vs(state);
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 8d000e8..f6c83a5 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2823,8 +2823,6 @@ void state_clipping(struct wined3d_context *context,
         const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
 void light(struct wined3d_context *context,
         const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
-void vertexdeclaration(struct wined3d_context *context,
-        const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
 void clipplane(struct wined3d_context *context,
         const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
 void state_psizemin_w(struct wined3d_context *context,
@@ -2839,6 +2837,10 @@ void state_pointsprite(struct wined3d_context *context,
         const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
 void state_pscale(struct wined3d_context *context,
         const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void state_lighting(struct wined3d_context *context,
+        const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void state_normalize(struct wined3d_context *context,
+        const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
 
 BOOL getColorBits(const struct wined3d_format *format,
         BYTE *redSize, BYTE *greenSize, BYTE *blueSize, BYTE *alphaSize, BYTE *totalSize) DECLSPEC_HIDDEN;




More information about the wine-cvs mailing list