[PATCH 5/5] wined3d: Enable or disable the fragment pipe in shader_select().

Henri Verbeet hverbeet at codeweavers.com
Sun Nov 4 12:51:33 CST 2012


---
 dlls/wined3d/arb_program_shader.c |   49 +++++++++++++++++++-----------------
 dlls/wined3d/context.c            |   33 +++++++------------------
 dlls/wined3d/glsl_shader.c        |   17 ++++--------
 dlls/wined3d/shader.c             |   20 +++++++-------
 dlls/wined3d/wined3d_private.h    |   11 +++++++-
 5 files changed, 60 insertions(+), 70 deletions(-)

diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c
index e2faaac..aa89d59 100644
--- a/dlls/wined3d/arb_program_shader.c
+++ b/dlls/wined3d/arb_program_shader.c
@@ -637,7 +637,8 @@ static void shader_arb_vs_local_constants(const struct arb_vs_compiled_shader *g
     checkGLcall("Load vs int consts");
 }
 
-static void shader_arb_select(const struct wined3d_context *context, BOOL usePS, BOOL useVS);
+static void shader_arb_select(const struct wined3d_context *context, enum wined3d_shader_mode vertex_mode,
+        enum wined3d_shader_mode fragment_mode);
 
 /**
  * Loads the app-supplied constants into the currently set ARB_[vertex/fragment]_programs.
@@ -665,7 +666,9 @@ static void shader_arb_load_constants_internal(const struct wined3d_context *con
                 & vshader->reg_maps.integer_constants & ~vshader->reg_maps.local_int_consts))))
         {
             TRACE("bool/integer vertex shader constants potentially modified, forcing shader reselection.\n");
-            shader_arb_select(context, usePixelShader, useVertexShader);
+            shader_arb_select(context,
+                    useVertexShader ? WINED3D_SHADER_MODE_SHADER : WINED3D_SHADER_MODE_FFP,
+                    usePixelShader ? WINED3D_SHADER_MODE_SHADER : WINED3D_SHADER_MODE_FFP);
         }
         else if (pshader
                 && (stateblock->changed.pixelShaderConstantsB & pshader->reg_maps.boolean_constants
@@ -674,7 +677,9 @@ static void shader_arb_load_constants_internal(const struct wined3d_context *con
                 & pshader->reg_maps.integer_constants & ~pshader->reg_maps.local_int_consts))))
         {
             TRACE("bool/integer pixel shader constants potentially modified, forcing shader reselection.\n");
-            shader_arb_select(context, usePixelShader, useVertexShader);
+            shader_arb_select(context,
+                    useVertexShader ? WINED3D_SHADER_MODE_SHADER : WINED3D_SHADER_MODE_FFP,
+                    usePixelShader ? WINED3D_SHADER_MODE_SHADER : WINED3D_SHADER_MODE_FFP);
         }
     }
 
@@ -4644,7 +4649,8 @@ static void find_arb_vs_compile_args(const struct wined3d_state *state,
 }
 
 /* GL locking is done by the caller */
-static void shader_arb_select(const struct wined3d_context *context, BOOL usePS, BOOL useVS)
+static void shader_arb_select(const struct wined3d_context *context, enum wined3d_shader_mode vertex_mode,
+        enum wined3d_shader_mode fragment_mode)
 {
     struct wined3d_device *device = context->swapchain->device;
     struct shader_arb_priv *priv = device->shader_priv;
@@ -4653,7 +4659,7 @@ static void shader_arb_select(const struct wined3d_context *context, BOOL usePS,
     int i;
 
     /* Deal with pixel shaders first so the vertex shader arg function has the input signature ready */
-    if (usePS)
+    if (fragment_mode == WINED3D_SHADER_MODE_SHADER)
     {
         struct wined3d_shader *ps = state->pixel_shader;
         struct arb_ps_compile_args compile_args;
@@ -4671,6 +4677,8 @@ static void shader_arb_select(const struct wined3d_context *context, BOOL usePS,
 
         if (!priv->use_arbfp_fixed_func)
         {
+            priv->fragment_pipe->enable_extension(gl_info, FALSE);
+
             /* Enable OpenGL fragment programs. */
             gl_info->gl_ops.gl.p_glEnable(GL_FRAGMENT_PROGRAM_ARB);
             checkGLcall("glEnable(GL_FRAGMENT_PROGRAM_ARB);");
@@ -4702,18 +4710,22 @@ static void shader_arb_select(const struct wined3d_context *context, BOOL usePS,
         if (compiled->np2fixup_info.super.active)
             shader_arb_load_np2fixup_constants(priv, gl_info, state);
     }
-    else if (gl_info->supported[ARB_FRAGMENT_PROGRAM] && !priv->use_arbfp_fixed_func)
+    else
     {
-        /* Disable only if we're not using arbfp fixed function fragment processing. If this is used,
-        * keep GL_FRAGMENT_PROGRAM_ARB enabled, and the fixed function pipeline will bind the fixed function
-        * replacement shader
-        */
-        gl_info->gl_ops.gl.p_glDisable(GL_FRAGMENT_PROGRAM_ARB);
-        checkGLcall("glDisable(GL_FRAGMENT_PROGRAM_ARB)");
-        priv->current_fprogram_id = 0;
+        if (gl_info->supported[ARB_FRAGMENT_PROGRAM] && !priv->use_arbfp_fixed_func)
+        {
+            /* Disable only if we're not using arbfp fixed function fragment
+             * processing. If this is used, keep GL_FRAGMENT_PROGRAM_ARB
+             * enabled, and the fixed function pipeline will bind the fixed
+             * function replacement shader. */
+            gl_info->gl_ops.gl.p_glDisable(GL_FRAGMENT_PROGRAM_ARB);
+            checkGLcall("glDisable(GL_FRAGMENT_PROGRAM_ARB)");
+            priv->current_fprogram_id = 0;
+        }
+        priv->fragment_pipe->enable_extension(gl_info, fragment_mode == WINED3D_SHADER_MODE_FFP);
     }
 
-    if (useVS)
+    if (vertex_mode == WINED3D_SHADER_MODE_SHADER)
     {
         struct wined3d_shader *vs = state->vertex_shader;
         struct arb_vs_compile_args compile_args;
@@ -5603,14 +5615,6 @@ static void shader_arb_handle_instruction(const struct wined3d_shader_instructio
     shader_arb_add_instruction_modifiers(ins);
 }
 
-static void shader_arb_enable_fragment_pipe(void *shader_priv,
-        const struct wined3d_gl_info *gl_info, BOOL enable)
-{
-    struct shader_arb_priv *priv = shader_priv;
-
-    priv->fragment_pipe->enable_extension(gl_info, enable);
-}
-
 static BOOL shader_arb_has_ffp_proj_control(void *shader_priv)
 {
     struct shader_arb_priv *priv = shader_priv;
@@ -5634,7 +5638,6 @@ const struct wined3d_shader_backend_ops arb_program_shader_backend =
     shader_arb_context_destroyed,
     shader_arb_get_caps,
     shader_arb_color_fixup_supported,
-    shader_arb_enable_fragment_pipe,
     shader_arb_has_ffp_proj_control,
 };
 
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index 999adee..3087c2c 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -1569,7 +1569,7 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain,
     {
         GL_EXTCALL(glProvokingVertexEXT(GL_FIRST_VERTEX_CONVENTION_EXT));
     }
-    device->shader_backend->shader_enable_fragment_pipe(device->shader_priv, gl_info, TRUE);
+    ret->select_shader = 1;
 
     /* If this happens to be the first context for the device, dummy textures
      * are not created yet. In that case, they will be created (and bound) by
@@ -1708,13 +1708,6 @@ static void SetupForBlit(const struct wined3d_device *device, struct wined3d_con
 
     /* TODO: Use a display list */
 
-    /* Disable shaders */
-    ENTER_GL();
-    device->shader_backend->shader_select(context, FALSE, FALSE);
-    context->select_shader = 1;
-    context->load_constants = 1;
-    LEAVE_GL();
-
     /* Call ENTER_GL() once for all gl calls below. In theory we should not call
      * helper functions in between gl calls. This function is full of context_invalidate_state
      * which can safely be called from here, we only lock once instead locking/unlocking
@@ -1864,7 +1857,11 @@ static void SetupForBlit(const struct wined3d_device *device, struct wined3d_con
     context_invalidate_state(context, STATE_RENDER(WINED3D_RS_CLIPPING));
 
     set_blit_dimension(gl_info, rt_size.cx, rt_size.cy);
-    device->shader_backend->shader_enable_fragment_pipe(device->shader_priv, gl_info, FALSE);
+
+    /* Disable shaders */
+    device->shader_backend->shader_select(context, WINED3D_SHADER_MODE_NONE, WINED3D_SHADER_MODE_NONE);
+    context->select_shader = 1;
+    context->load_constants = 1;
 
     LEAVE_GL();
 
@@ -2223,10 +2220,7 @@ BOOL context_apply_clear_state(struct wined3d_context *context, const struct win
     }
 
     if (context->last_was_blit)
-    {
-        device->shader_backend->shader_enable_fragment_pipe(device->shader_priv, gl_info, TRUE);
         context->last_was_blit = FALSE;
-    }
 
     /* Blending and clearing should be orthogonal, but tests on the nvidia
      * driver show that disabling blending when clearing improves the clearing
@@ -2352,8 +2346,6 @@ BOOL context_apply_draw_state(struct wined3d_context *context, struct wined3d_de
     }
 
     ENTER_GL();
-    if (context->last_was_blit)
-        device->shader_backend->shader_enable_fragment_pipe(device->shader_priv, context->gl_info, TRUE);
 
     for (i = 0; i < context->numDirtyEntries; ++i)
     {
@@ -2366,7 +2358,9 @@ BOOL context_apply_draw_state(struct wined3d_context *context, struct wined3d_de
 
     if (context->select_shader)
     {
-        device->shader_backend->shader_select(context, use_ps(state), use_vs(state));
+        device->shader_backend->shader_select(context,
+                use_vs(state) ? WINED3D_SHADER_MODE_SHADER : WINED3D_SHADER_MODE_FFP,
+                use_ps(state) ? WINED3D_SHADER_MODE_SHADER : WINED3D_SHADER_MODE_FFP);
         context->select_shader = 0;
     }
 
@@ -2499,16 +2493,7 @@ struct wined3d_context *context_acquire(const struct wined3d_device *device, str
     if (context != current_context)
     {
         if (!context_set_current(context))
-        {
             ERR("Failed to activate the new context.\n");
-        }
-        else
-        {
-            ENTER_GL();
-            device->shader_backend->shader_enable_fragment_pipe(device->shader_priv,
-                    context->gl_info, !context->last_was_blit);
-            LEAVE_GL();
-        }
     }
     else if (context->restore_ctx)
     {
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index d7d7e3c..2bbeda4 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -4998,16 +4998,20 @@ static GLhandleARB create_glsl_blt_shader(const struct wined3d_gl_info *gl_info,
 }
 
 /* GL locking is done by the caller */
-static void shader_glsl_select(const struct wined3d_context *context, BOOL usePS, BOOL useVS)
+static void shader_glsl_select(const struct wined3d_context *context, enum wined3d_shader_mode vertex_mode,
+        enum wined3d_shader_mode fragment_mode)
 {
     const struct wined3d_gl_info *gl_info = context->gl_info;
     struct wined3d_device *device = context->swapchain->device;
     struct shader_glsl_priv *priv = device->shader_priv;
     GLhandleARB program_id = 0;
     GLenum old_vertex_color_clamp, current_vertex_color_clamp;
+    BOOL useVS = vertex_mode == WINED3D_SHADER_MODE_SHADER;
+    BOOL usePS = fragment_mode == WINED3D_SHADER_MODE_SHADER;
 
     old_vertex_color_clamp = priv->glsl_program ? priv->glsl_program->vertex_color_clamp : GL_FIXED_ONLY_ARB;
 
+    priv->fragment_pipe->enable_extension(gl_info, fragment_mode == WINED3D_SHADER_MODE_FFP);
     if (useVS || usePS) set_glsl_shader_program(context, device, usePS, useVS);
     else priv->glsl_program = NULL;
 
@@ -5105,7 +5109,7 @@ static void shader_glsl_destroy(struct wined3d_shader *shader)
             || priv->glsl_program->pshader == shader))
     {
         ENTER_GL();
-        shader_glsl_select(context, FALSE, FALSE);
+        shader_glsl_select(context, WINED3D_SHADER_MODE_NONE, WINED3D_SHADER_MODE_NONE);
         LEAVE_GL();
     }
 
@@ -5514,14 +5518,6 @@ static void shader_glsl_handle_instruction(const struct wined3d_shader_instructi
     shader_glsl_add_instruction_modifiers(ins);
 }
 
-static void shader_glsl_enable_fragment_pipe(void *shader_priv,
-        const struct wined3d_gl_info *gl_info, BOOL enable)
-{
-    struct shader_glsl_priv *priv = shader_priv;
-
-    priv->fragment_pipe->enable_extension(gl_info, enable);
-}
-
 static BOOL shader_glsl_has_ffp_proj_control(void *shader_priv)
 {
     struct shader_glsl_priv *priv = shader_priv;
@@ -5545,6 +5541,5 @@ const struct wined3d_shader_backend_ops glsl_shader_backend =
     shader_glsl_context_destroyed,
     shader_glsl_get_caps,
     shader_glsl_color_fixup_supported,
-    shader_glsl_enable_fragment_pipe,
     shader_glsl_has_ffp_proj_control,
 };
diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c
index 6143ac5..a6481b0 100644
--- a/dlls/wined3d/shader.c
+++ b/dlls/wined3d/shader.c
@@ -1458,7 +1458,6 @@ struct shader_none_priv
 };
 
 static void shader_none_handle_instruction(const struct wined3d_shader_instruction *ins) {}
-static void shader_none_select(const struct wined3d_context *context, BOOL usePS, BOOL useVS) {}
 static void shader_none_select_depth_blt(void *shader_priv, const struct wined3d_gl_info *gl_info,
         enum tex_types tex_type, const SIZE *ds_mask_size) {}
 static void shader_none_deselect_depth_blt(void *shader_priv, const struct wined3d_gl_info *gl_info) {}
@@ -1470,6 +1469,16 @@ static void shader_none_load_np2fixup_constants(void *shader_priv,
 static void shader_none_destroy(struct wined3d_shader *shader) {}
 static void shader_none_context_destroyed(void *shader_priv, const struct wined3d_context *context) {}
 
+static void shader_none_select(const struct wined3d_context *context, enum wined3d_shader_mode vertex_mode,
+        enum wined3d_shader_mode fragment_mode)
+{
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+    struct wined3d_device *device = context->swapchain->device;
+    struct shader_none_priv *priv = device->shader_priv;
+
+    priv->fragment_pipe->enable_extension(gl_info, fragment_mode == WINED3D_SHADER_MODE_FFP);
+}
+
 static HRESULT shader_none_alloc(struct wined3d_device *device, const struct fragment_pipeline *fragment_pipe)
 {
     struct shader_none_priv *priv;
@@ -1534,14 +1543,6 @@ static BOOL shader_none_color_fixup_supported(struct color_fixup_desc fixup)
     return FALSE;
 }
 
-static void shader_none_enable_fragment_pipe(void *shader_priv,
-        const struct wined3d_gl_info *gl_info, BOOL enable)
-{
-    struct shader_none_priv *priv = shader_priv;
-
-    priv->fragment_pipe->enable_extension(gl_info, enable);
-}
-
 static BOOL shader_none_has_ffp_proj_control(void *shader_priv)
 {
     struct shader_none_priv *priv = shader_priv;
@@ -1565,7 +1566,6 @@ const struct wined3d_shader_backend_ops none_shader_backend =
     shader_none_context_destroyed,
     shader_none_get_caps,
     shader_none_color_fixup_supported,
-    shader_none_enable_fragment_pipe,
     shader_none_has_ffp_proj_control,
 };
 
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index e9fd80f..3f67e88 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -782,6 +782,13 @@ struct vs_compile_args {
     WORD                        swizzle_map;   /* MAX_ATTRIBS, 16 */
 };
 
+enum wined3d_shader_mode
+{
+    WINED3D_SHADER_MODE_NONE,
+    WINED3D_SHADER_MODE_FFP,
+    WINED3D_SHADER_MODE_SHADER,
+};
+
 struct wined3d_context;
 struct wined3d_state;
 struct fragment_pipeline;
@@ -789,7 +796,8 @@ struct fragment_pipeline;
 struct wined3d_shader_backend_ops
 {
     void (*shader_handle_instruction)(const struct wined3d_shader_instruction *);
-    void (*shader_select)(const struct wined3d_context *context, BOOL usePS, BOOL useVS);
+    void (*shader_select)(const struct wined3d_context *context, enum wined3d_shader_mode vertex_mode,
+            enum wined3d_shader_mode fragment_mode);
     void (*shader_select_depth_blt)(void *shader_priv, const struct wined3d_gl_info *gl_info,
             enum tex_types tex_type, const SIZE *ds_mask_size);
     void (*shader_deselect_depth_blt)(void *shader_priv, const struct wined3d_gl_info *gl_info);
@@ -804,7 +812,6 @@ struct wined3d_shader_backend_ops
     void (*shader_context_destroyed)(void *shader_priv, const struct wined3d_context *context);
     void (*shader_get_caps)(const struct wined3d_gl_info *gl_info, struct shader_caps *caps);
     BOOL (*shader_color_fixup_supported)(struct color_fixup_desc fixup);
-    void (*shader_enable_fragment_pipe)(void *shader_priv, const struct wined3d_gl_info *gl_info, BOOL enable);
     BOOL (*shader_has_ffp_proj_control)(void *shader_priv);
 };
 
-- 
1.7.8.6




More information about the wine-patches mailing list