Module: wine Branch: master Commit: 3ca84a348edc32d04778f3412e9c09cae32b3710 URL: http://source.winehq.org/git/wine.git/?a=commit;h=3ca84a348edc32d04778f3412e...
Author: Józef Kucia jkucia@codeweavers.com Date: Thu Mar 30 14:09:23 2017 +0200
wined3d: Pause transform feedback between draw calls.
In order to avoid recording vertices generated by other operations, e.g. blits.
Signed-off-by: Józef Kucia jkucia@codeweavers.com Signed-off-by: Henri Verbeet hverbeet@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
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 ba8b004..52cdc67 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 2f90efd..30625a3 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;