[PATCH 10/11] wined3d: Keep track of enabled clip distances.

Józef Kucia jkucia at codeweavers.com
Sat Dec 2 03:24:43 CST 2017


Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---
 dlls/wined3d/context.c         | 31 +++++++++++++++++++++++++---
 dlls/wined3d/state.c           | 47 ++++++++----------------------------------
 dlls/wined3d/wined3d_private.h |  4 +++-
 3 files changed, 40 insertions(+), 42 deletions(-)

diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index 3dc6ca7c0249..8af9e4bb8264 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -2352,6 +2352,33 @@ static void context_get_rt_size(const struct wined3d_context *context, SIZE *siz
     size->cy = wined3d_texture_get_level_height(rt, level);
 }
 
+void context_enable_clip_distances(struct wined3d_context *context, unsigned int enable_mask)
+{
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+    unsigned int clip_distance_count = gl_info->limits.user_clip_distances;
+    unsigned int i, disable_mask, current_mask;
+
+    disable_mask = ~enable_mask;
+    enable_mask &= (1u << clip_distance_count) - 1;
+    disable_mask &= (1u << clip_distance_count) - 1;
+    current_mask = context->clip_distance_mask;
+    context->clip_distance_mask = enable_mask;
+
+    enable_mask &= ~current_mask;
+    for (i = 0; enable_mask; enable_mask >>= 1, ++i)
+    {
+        if (enable_mask & 1)
+            gl_info->gl_ops.gl.p_glEnable(GL_CLIP_DISTANCE0 + i);
+    }
+    disable_mask &= current_mask;
+    for (i = 0; disable_mask; disable_mask >>= 1, ++i)
+    {
+        if (disable_mask & 1)
+            gl_info->gl_ops.gl.p_glDisable(GL_CLIP_DISTANCE0 + i);
+    }
+    checkGLcall("toggle clip distances");
+}
+
 /*****************************************************************************
  * SetupForBlit
  *
@@ -2530,9 +2557,7 @@ static void SetupForBlit(const struct wined3d_device *device, struct wined3d_con
     context->last_was_rhw = TRUE;
     context_invalidate_state(context, STATE_VDECL); /* because of last_was_rhw = TRUE */
 
-    for (i = 0; i < gl_info->limits.user_clip_distances; ++i)
-        gl_info->gl_ops.gl.p_glDisable(GL_CLIP_DISTANCE0 + i);
-    checkGLcall("disable clip planes");
+    context_enable_clip_distances(context, 0);
     context_invalidate_state(context, STATE_RENDER(WINED3D_RS_CLIPPING));
 
     /* FIXME: Make draw_textured_quad() able to work with a upper left origin. */
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index ea497fabc6ad..f3ec7df1863a 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -611,9 +611,7 @@ void state_alpha_test(struct wined3d_context *context, const struct wined3d_stat
 
 void state_clipping(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
 {
-    const struct wined3d_gl_info *gl_info = context->gl_info;
-    unsigned int clipplane_count = gl_info->limits.user_clip_distances;
-    unsigned int i, enable_mask, disable_mask;
+    unsigned int enable_mask;
 
     if (use_vs(state) && !context->d3d_info->vs_clipping)
     {
@@ -626,7 +624,7 @@ void state_clipping(struct wined3d_context *context, const struct wined3d_state
          * disables all clip planes because of that - don't do anything here
          * and keep them disabled. */
         if (state->render_states[WINED3D_RS_CLIPPLANEENABLE] && !warned++)
-            FIXME("Clipping not supported with vertex shaders\n");
+            FIXME("Clipping not supported with vertex shaders.\n");
         return;
     }
 
@@ -636,36 +634,12 @@ void state_clipping(struct wined3d_context *context, const struct wined3d_state
      * need to update the clipping field from ffp_vertex_settings. */
     context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_VERTEX;
 
-    /* TODO: Keep track of previously enabled clipplanes to avoid unnecessary resetting
-     * of already set values
-     */
-
     /* If enabling / disabling all
      * TODO: Is this correct? Doesn't D3DRS_CLIPPING disable clipping on the viewport frustrum?
      */
-    if (state->render_states[WINED3D_RS_CLIPPING])
-    {
-        enable_mask = state->render_states[WINED3D_RS_CLIPPLANEENABLE];
-        disable_mask = ~state->render_states[WINED3D_RS_CLIPPLANEENABLE];
-    }
-    else
-    {
-        enable_mask = 0;
-        disable_mask = ~0u;
-    }
-
-    enable_mask &= (1u << clipplane_count) - 1;
-    disable_mask &= (1u << clipplane_count) - 1;
-
-    for (i = 0; enable_mask && i < clipplane_count; enable_mask >>= 1, ++i)
-        if (enable_mask & 1)
-            gl_info->gl_ops.gl.p_glEnable(GL_CLIP_DISTANCE0 + i);
-    checkGLcall("clip plane enable");
-
-    for (i = 0; disable_mask && i < clipplane_count; disable_mask >>= 1, ++i)
-        if (disable_mask & 1)
-            gl_info->gl_ops.gl.p_glDisable(GL_CLIP_DISTANCE0 + i);
-    checkGLcall("clip plane disable");
+    enable_mask = state->render_states[WINED3D_RS_CLIPPING] ?
+            state->render_states[WINED3D_RS_CLIPPLANEENABLE] : 0;
+    context_enable_clip_distances(context, enable_mask);
 }
 
 static void state_specularenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
@@ -4532,22 +4506,19 @@ static void vertexdeclaration(struct wined3d_context *context, const struct wine
     }
     else
     {
-        if(!context->last_was_vshader) {
+        if (!context->last_was_vshader)
+        {
             static BOOL warned = FALSE;
             if (!context->d3d_info->vs_clipping)
             {
                 /* Disable all clip planes to get defined results on all drivers. See comment in the
                  * state_clipping state handler
                  */
-                for (i = 0; i < gl_info->limits.user_clip_distances; ++i)
-                {
-                    gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE0 + i);
-                    checkGLcall("glDisable(GL_CLIP_PLANE0 + i)");
-                }
+                context_enable_clip_distances(context, 0);
 
                 if (!warned && state->render_states[WINED3D_RS_CLIPPLANEENABLE])
                 {
-                    FIXME("Clipping not supported with vertex shaders\n");
+                    FIXME("Clipping not supported with vertex shaders.\n");
                     warned = TRUE;
                 }
             }
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 9fe7fbcd72d9..da06ba159f79 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1901,7 +1901,8 @@ struct wined3d_context
     DWORD transform_feedback_active : 1;
     DWORD transform_feedback_paused : 1;
     DWORD shader_update_mask : 6; /* WINED3D_SHADER_TYPE_COUNT, 6 */
-    DWORD padding : 17;
+    DWORD clip_distance_mask : 8; /* MAX_CLIP_DISTANCES, 8 */
+    DWORD padding : 9;
     DWORD constant_update_mask;
     DWORD                   numbered_array_mask;
     GLenum                  tracking_parm;     /* Which source is tracking current colour         */
@@ -2146,6 +2147,7 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, stru
         const struct wined3d_format *ds_format) DECLSPEC_HIDDEN;
 HGLRC context_create_wgl_attribs(const struct wined3d_gl_info *gl_info, HDC hdc, HGLRC share_ctx) DECLSPEC_HIDDEN;
 void context_destroy(struct wined3d_device *device, struct wined3d_context *context) DECLSPEC_HIDDEN;
+void context_enable_clip_distances(struct wined3d_context *context, unsigned int mask) DECLSPEC_HIDDEN;
 void context_end_transform_feedback(struct wined3d_context *context) DECLSPEC_HIDDEN;
 void context_free_fence(struct wined3d_fence *fence) DECLSPEC_HIDDEN;
 void context_free_occlusion_query(struct wined3d_occlusion_query *query) DECLSPEC_HIDDEN;
-- 
2.13.6




More information about the wine-devel mailing list