[PATCH 6/7] wined3d: Pause transform feedback between draw calls.

Józef Kucia jkucia at codeweavers.com
Thu Mar 30 07:09:23 CDT 2017


In order to avoid recording vertices generated by other operations, e.g.
blits.

Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---
 dlls/wined3d/buffer.c          |  4 +---
 dlls/wined3d/context.c         | 12 ++++++++++++
 dlls/wined3d/drawprim.c        | 37 ++++++++++++++++++++++++++++---------
 dlls/wined3d/state.c           |  7 +------
 dlls/wined3d/wined3d_private.h |  4 +++-
 5 files changed, 45 insertions(+), 19 deletions(-)

diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
index b29534d..7ebecfa 100644
--- a/dlls/wined3d/buffer.c
+++ b/dlls/wined3d/buffer.c
@@ -181,9 +181,7 @@ static void buffer_destroy_buffer_object(struct wined3d_buffer *buffer, struct w
                  * when deleting a potentially bound transform feedback buffer.
                  * This may happen when the device is being destroyed. */
                 WARN("Deleting buffer object for buffer %p, disabling transform feedback.\n", buffer);
-                GL_EXTCALL(glEndTransformFeedback());
-                checkGLcall("glEndTransformFeedback");
-                context->transform_feedback_active = 0;
+                context_end_transform_feedback(context);
             }
         }
     }
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index 3c297df..8427eb7 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -3687,6 +3687,18 @@ void context_apply_compute_state(struct wined3d_context *context,
     context->last_was_blit = FALSE;
 }
 
+void context_end_transform_feedback(struct wined3d_context *context)
+{
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+    if (context->transform_feedback_active)
+    {
+        GL_EXTCALL(glEndTransformFeedback());
+        checkGLcall("glEndTransformFeedback");
+        context->transform_feedback_active = 0;
+        context->transform_feedback_paused = 0;
+    }
+}
+
 static void context_setup_target(struct wined3d_context *context,
         struct wined3d_texture *texture, unsigned int sub_resource_idx)
 {
diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c
index b5537a8..3611bf5 100644
--- a/dlls/wined3d/drawprim.c
+++ b/dlls/wined3d/drawprim.c
@@ -448,11 +448,7 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s
     gl_info = context->gl_info;
 
     if (context->transform_feedback_active && !use_transform_feedback(state))
-    {
-        GL_EXTCALL(glEndTransformFeedback());
-        checkGLcall("glEndTransformFeedback");
-        context->transform_feedback_active = 0;
-    }
+        context_end_transform_feedback(context);
 
     for (i = 0; i < gl_info->limits.buffers; ++i)
     {
@@ -564,7 +560,7 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s
         }
     }
 
-    if (use_transform_feedback(state) && !context->transform_feedback_active)
+    if (use_transform_feedback(state))
     {
         const struct wined3d_shader *shader = state->shader[WINED3D_SHADER_TYPE_GEOMETRY];
         GLenum primitive_mode = gl_primitive_type_from_d3d(shader->u.gs.output_type);
@@ -576,9 +572,18 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s
             rasterizer_discard = TRUE;
         }
 
-        GL_EXTCALL(glBeginTransformFeedback(primitive_mode));
-        checkGLcall("glBeginTransformFeedback");
-        context->transform_feedback_active = 1;
+        if (context->transform_feedback_paused)
+        {
+            GL_EXTCALL(glResumeTransformFeedback());
+            checkGLcall("glResumeTransformFeedback");
+            context->transform_feedback_paused = 0;
+        }
+        else if (!context->transform_feedback_active)
+        {
+            GL_EXTCALL(glBeginTransformFeedback(primitive_mode));
+            checkGLcall("glBeginTransformFeedback");
+            context->transform_feedback_active = 1;
+        }
     }
 
     if (context->use_immediate_mode_draw || emulation)
@@ -594,6 +599,20 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s
         checkGLcall("glMemoryBarrier");
     }
 
+    if (context->transform_feedback_active)
+    {
+        if (gl_info->supported[ARB_TRANSFORM_FEEDBACK2])
+        {
+            GL_EXTCALL(glPauseTransformFeedback());
+            checkGLcall("glPauseTransformFeedback");
+            context->transform_feedback_paused = 1;
+        }
+        else
+        {
+            WARN("Cannot pause transform feedback operations.\n");
+        }
+    }
+
     if (rasterizer_discard)
     {
         glDisable(GL_RASTERIZER_DISCARD);
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index dedde1e..e138936 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -4982,12 +4982,7 @@ static void state_so(struct wined3d_context *context, const struct wined3d_state
 
     TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
 
-    if (context->transform_feedback_active)
-    {
-        GL_EXTCALL(glEndTransformFeedback());
-        checkGLcall("glEndTransformFeedback");
-        context->transform_feedback_active = 0;
-    }
+    context_end_transform_feedback(context);
 
     for (i = 0; i < ARRAY_SIZE(state->stream_output); ++i)
     {
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 3a99738..c6194c2 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1690,7 +1690,8 @@ struct wined3d_context
     DWORD uses_uavs : 1;
     DWORD destroy_delayed : 1;
     DWORD transform_feedback_active : 1;
-    DWORD padding : 8;
+    DWORD transform_feedback_paused : 1;
+    DWORD padding : 7;
     DWORD last_swizzle_map; /* MAX_ATTRIBS, 16 */
     DWORD shader_update_mask;
     DWORD constant_update_mask;
@@ -1920,6 +1921,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_end_transform_feedback(struct wined3d_context *context) DECLSPEC_HIDDEN;
 void context_free_event_query(struct wined3d_event_query *query) DECLSPEC_HIDDEN;
 void context_free_occlusion_query(struct wined3d_occlusion_query *query) DECLSPEC_HIDDEN;
 struct wined3d_context *context_get_current(void) DECLSPEC_HIDDEN;
-- 
2.10.2




More information about the wine-patches mailing list