[PATCH 3/3] wined3d: Introduce wined3d fence objects.

Józef Kucia jkucia at codeweavers.com
Sun Jul 9 06:25:49 CDT 2017


Use fences for the APPLESYNC codepath, and implement event queries
on top of fences.

Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---

The patch is quite big but it is mostly a lot of renaming.

---
 dlls/wined3d/buffer.c          |  54 +++++-------
 dlls/wined3d/context.c         |  92 ++++++++++----------
 dlls/wined3d/drawprim.c        |  12 +--
 dlls/wined3d/query.c           | 185 ++++++++++++++++++++++++++---------------
 dlls/wined3d/wined3d_private.h |  70 +++++++++-------
 5 files changed, 235 insertions(+), 178 deletions(-)

diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
index 26f3dea806..f9cb251ad5 100644
--- a/dlls/wined3d/buffer.c
+++ b/dlls/wined3d/buffer.c
@@ -185,11 +185,10 @@ static void buffer_destroy_buffer_object(struct wined3d_buffer *buffer, struct w
     checkGLcall("glDeleteBuffers");
     buffer->buffer_object = 0;
 
-    if (buffer->query)
+    if (buffer->fence)
     {
-        struct wined3d_query *query = &buffer->query->query;
-        query->query_ops->query_destroy(query);
-        buffer->query = NULL;
+        wined3d_fence_destroy(buffer->fence);
+        buffer->fence = NULL;
     }
     buffer->flags &= ~WINED3D_BUFFER_APPLESYNC;
 }
@@ -814,8 +813,7 @@ void * CDECL wined3d_buffer_get_parent(const struct wined3d_buffer *buffer)
 /* The caller provides a context and binds the buffer */
 static void buffer_sync_apple(struct wined3d_buffer *buffer, DWORD flags, const struct wined3d_gl_info *gl_info)
 {
-    enum wined3d_event_query_result ret;
-    struct wined3d_query *query;
+    enum wined3d_fence_result ret;
     HRESULT hr;
 
     /* No fencing needs to be done if the app promises not to overwrite
@@ -830,23 +828,18 @@ static void buffer_sync_apple(struct wined3d_buffer *buffer, DWORD flags, const
         return;
     }
 
-    if (!buffer->query)
+    if (!buffer->fence)
     {
-        TRACE("Creating event query for buffer %p.\n", buffer);
+        TRACE("Creating fence for buffer %p.\n", buffer);
 
-        hr = wined3d_query_create(buffer->resource.device, WINED3D_QUERY_TYPE_EVENT,
-                NULL, &wined3d_null_parent_ops, &query);
-        if (hr == WINED3DERR_NOTAVAILABLE)
+        if (FAILED(hr = wined3d_fence_create(buffer->resource.device, &buffer->fence)))
         {
-            FIXME("Event queries not supported, dropping async buffer locks.\n");
-            goto drop_query;
-        }
-        if (FAILED(hr))
-        {
-            ERR("Failed to create event query, hr %#x.\n", hr);
-            goto drop_query;
+            if (hr == WINED3DERR_NOTAVAILABLE)
+                FIXME("Fences not supported, dropping async buffer locks.\n");
+            else
+                ERR("Failed to create fence, hr %#x.\n", hr);
+            goto drop_fence;
         }
-        buffer->query = CONTAINING_RECORD(query, struct wined3d_event_query, query);
 
         /* Since we don't know about old draws a glFinish is needed once */
         gl_info->gl_ops.gl.p_glFinish();
@@ -854,29 +847,28 @@ static void buffer_sync_apple(struct wined3d_buffer *buffer, DWORD flags, const
     }
 
     TRACE("Synchronizing buffer %p.\n", buffer);
-    ret = wined3d_event_query_finish(buffer->query, buffer->resource.device);
+    ret = wined3d_fence_wait(buffer->fence, buffer->resource.device);
     switch (ret)
     {
-        case WINED3D_EVENT_QUERY_NOT_STARTED:
-        case WINED3D_EVENT_QUERY_OK:
+        case WINED3D_FENCE_NOT_STARTED:
+        case WINED3D_FENCE_OK:
             /* All done */
             return;
 
-        case WINED3D_EVENT_QUERY_WRONG_THREAD:
+        case WINED3D_FENCE_WRONG_THREAD:
             WARN("Cannot synchronize buffer lock due to a thread conflict.\n");
-            goto drop_query;
+            goto drop_fence;
 
         default:
-            ERR("wined3d_event_query_finish returned %u, dropping async buffer locks.\n", ret);
-            goto drop_query;
+            ERR("wined3d_fence_wait() returned %u, dropping async buffer locks.\n", ret);
+            goto drop_fence;
     }
 
-drop_query:
-    if (buffer->query)
+drop_fence:
+    if (buffer->fence)
     {
-        struct wined3d_query *query = &buffer->query->query;
-        query->query_ops->query_destroy(query);
-        buffer->query = NULL;
+        wined3d_fence_destroy(buffer->fence);
+        buffer->fence = NULL;
     }
 
     gl_info->gl_ops.gl.p_glFinish();
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index fbc73ca9a1..b5b788f2fd 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -794,63 +794,63 @@ void context_free_occlusion_query(struct wined3d_occlusion_query *query)
 }
 
 /* Context activation is done by the caller. */
-void context_alloc_event_query(struct wined3d_context *context, struct wined3d_event_query *query)
+void context_alloc_fence(struct wined3d_context *context, struct wined3d_fence *fence)
 {
     const struct wined3d_gl_info *gl_info = context->gl_info;
 
-    if (context->free_event_query_count)
+    if (context->free_fence_count)
     {
-        query->object = context->free_event_queries[--context->free_event_query_count];
+        fence->object = context->free_fences[--context->free_fence_count];
     }
     else
     {
         if (gl_info->supported[ARB_SYNC])
         {
             /* Using ARB_sync, not much to do here. */
-            query->object.sync = NULL;
-            TRACE("Allocated event query %p in context %p.\n", query->object.sync, context);
+            fence->object.sync = NULL;
+            TRACE("Allocated sync object in context %p.\n", context);
         }
         else if (gl_info->supported[APPLE_FENCE])
         {
-            GL_EXTCALL(glGenFencesAPPLE(1, &query->object.id));
+            GL_EXTCALL(glGenFencesAPPLE(1, &fence->object.id));
             checkGLcall("glGenFencesAPPLE");
 
-            TRACE("Allocated event query %u in context %p.\n", query->object.id, context);
+            TRACE("Allocated fence %u in context %p.\n", fence->object.id, context);
         }
         else if(gl_info->supported[NV_FENCE])
         {
-            GL_EXTCALL(glGenFencesNV(1, &query->object.id));
+            GL_EXTCALL(glGenFencesNV(1, &fence->object.id));
             checkGLcall("glGenFencesNV");
 
-            TRACE("Allocated event query %u in context %p.\n", query->object.id, context);
+            TRACE("Allocated fence %u in context %p.\n", fence->object.id, context);
         }
         else
         {
-            WARN("Event queries not supported, not allocating query id.\n");
-            query->object.id = 0;
+            WARN("Fences not supported, not allocating fence.\n");
+            fence->object.id = 0;
         }
     }
 
-    query->context = context;
-    list_add_head(&context->event_queries, &query->entry);
+    fence->context = context;
+    list_add_head(&context->fences, &fence->entry);
 }
 
-void context_free_event_query(struct wined3d_event_query *query)
+void context_free_fence(struct wined3d_fence *fence)
 {
-    struct wined3d_context *context = query->context;
+    struct wined3d_context *context = fence->context;
 
-    list_remove(&query->entry);
-    query->context = NULL;
+    list_remove(&fence->entry);
+    fence->context = NULL;
 
-    if (!wined3d_array_reserve((void **)&context->free_event_queries,
-            &context->free_event_query_size, context->free_event_query_count + 1,
-            sizeof(*context->free_event_queries)))
+    if (!wined3d_array_reserve((void **)&context->free_fences,
+            &context->free_fence_size, context->free_fence_count + 1,
+            sizeof(*context->free_fences)))
     {
-        ERR("Failed to grow free list, leaking query %u in context %p.\n", query->object.id, context);
+        ERR("Failed to grow free list, leaking fence %u in context %p.\n", fence->object.id, context);
         return;
     }
 
-    context->free_event_queries[context->free_event_query_count++] = query->object;
+    context->free_fences[context->free_fence_count++] = fence->object;
 }
 
 /* Context activation is done by the caller. */
@@ -1265,8 +1265,8 @@ static void context_destroy_gl_resources(struct wined3d_context *context)
     struct wined3d_so_statistics_query *so_statistics_query;
     struct wined3d_timestamp_query *timestamp_query;
     struct wined3d_occlusion_query *occlusion_query;
-    struct wined3d_event_query *event_query;
     struct fbo_entry *entry, *entry2;
+    struct wined3d_fence *fence;
     HGLRC restore_ctx;
     HDC restore_dc;
     unsigned int i;
@@ -1309,18 +1309,25 @@ static void context_destroy_gl_resources(struct wined3d_context *context)
         occlusion_query->context = NULL;
     }
 
-    LIST_FOR_EACH_ENTRY(event_query, &context->event_queries, struct wined3d_event_query, entry)
+    LIST_FOR_EACH_ENTRY(fence, &context->fences, struct wined3d_fence, entry)
     {
         if (context->valid)
         {
             if (gl_info->supported[ARB_SYNC])
             {
-                if (event_query->object.sync) GL_EXTCALL(glDeleteSync(event_query->object.sync));
+                if (fence->object.sync)
+                    GL_EXTCALL(glDeleteSync(fence->object.sync));
+            }
+            else if (gl_info->supported[APPLE_FENCE])
+            {
+                GL_EXTCALL(glDeleteFencesAPPLE(1, &fence->object.id));
+            }
+            else if (gl_info->supported[NV_FENCE])
+            {
+                GL_EXTCALL(glDeleteFencesNV(1, &fence->object.id));
             }
-            else if (gl_info->supported[APPLE_FENCE]) GL_EXTCALL(glDeleteFencesAPPLE(1, &event_query->object.id));
-            else if (gl_info->supported[NV_FENCE]) GL_EXTCALL(glDeleteFencesNV(1, &event_query->object.id));
         }
-        event_query->context = NULL;
+        fence->context = NULL;
     }
 
     LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &context->fbo_destroy_list, struct fbo_entry, entry)
@@ -1368,23 +1375,23 @@ static void context_destroy_gl_resources(struct wined3d_context *context)
 
         if (gl_info->supported[ARB_SYNC])
         {
-            for (i = 0; i < context->free_event_query_count; ++i)
+            for (i = 0; i < context->free_fence_count; ++i)
             {
-                GL_EXTCALL(glDeleteSync(context->free_event_queries[i].sync));
+                GL_EXTCALL(glDeleteSync(context->free_fences[i].sync));
             }
         }
         else if (gl_info->supported[APPLE_FENCE])
         {
-            for (i = 0; i < context->free_event_query_count; ++i)
+            for (i = 0; i < context->free_fence_count; ++i)
             {
-                GL_EXTCALL(glDeleteFencesAPPLE(1, &context->free_event_queries[i].id));
+                GL_EXTCALL(glDeleteFencesAPPLE(1, &context->free_fences[i].id));
             }
         }
         else if (gl_info->supported[NV_FENCE])
         {
-            for (i = 0; i < context->free_event_query_count; ++i)
+            for (i = 0; i < context->free_fence_count; ++i)
             {
-                GL_EXTCALL(glDeleteFencesNV(1, &context->free_event_queries[i].id));
+                GL_EXTCALL(glDeleteFencesNV(1, &context->free_fences[i].id));
             }
         }
 
@@ -1395,7 +1402,7 @@ static void context_destroy_gl_resources(struct wined3d_context *context)
     HeapFree(GetProcessHeap(), 0, context->free_pipeline_statistics_queries);
     HeapFree(GetProcessHeap(), 0, context->free_timestamp_queries);
     HeapFree(GetProcessHeap(), 0, context->free_occlusion_queries);
-    HeapFree(GetProcessHeap(), 0, context->free_event_queries);
+    HeapFree(GetProcessHeap(), 0, context->free_fences);
 
     context_restore_pixel_format(context);
     if (restore_ctx)
@@ -1849,11 +1856,10 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain,
         goto out;
     list_init(&ret->occlusion_queries);
 
-    ret->free_event_query_size = 4;
-    if (!(ret->free_event_queries = wined3d_calloc(ret->free_event_query_size,
-            sizeof(*ret->free_event_queries))))
+    ret->free_fence_size = 4;
+    if (!(ret->free_fences = wined3d_calloc(ret->free_fence_size, sizeof(*ret->free_fences))))
         goto out;
-    list_init(&ret->event_queries);
+    list_init(&ret->fences);
 
     list_init(&ret->so_statistics_queries);
 
@@ -2211,7 +2217,7 @@ out:
     device->shader_backend->shader_free_context_data(ret);
     device->adapter->fragment_pipe->free_context_data(ret);
     HeapFree(GetProcessHeap(), 0, ret->texture_type);
-    HeapFree(GetProcessHeap(), 0, ret->free_event_queries);
+    HeapFree(GetProcessHeap(), 0, ret->free_fences);
     HeapFree(GetProcessHeap(), 0, ret->free_occlusion_queries);
     HeapFree(GetProcessHeap(), 0, ret->free_timestamp_queries);
     HeapFree(GetProcessHeap(), 0, ret->fbo_key);
@@ -3483,7 +3489,7 @@ static void context_update_stream_info(struct wined3d_context *context, const st
     wined3d_stream_info_from_declaration(stream_info, state, gl_info, d3d_info);
 
     stream_info->all_vbo = 1;
-    context->num_buffer_queries = 0;
+    context->buffer_fence_count = 0;
     for (i = 0, map = stream_info->use_map; map; map >>= 1, ++i)
     {
         struct wined3d_stream_info_element *element;
@@ -3524,8 +3530,8 @@ static void context_update_stream_info(struct wined3d_context *context, const st
         if (!element->data.buffer_object)
             stream_info->all_vbo = 0;
 
-        if (buffer->query)
-            context->buffer_queries[context->num_buffer_queries++] = buffer->query;
+        if (buffer->fence)
+            context->buffer_fences[context->buffer_fence_count++] = buffer->fence;
 
         TRACE("Load array %u {%#x:%p}.\n", i, element->data.buffer_object, element->data.addr);
     }
diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c
index f844b25b69..e9bce44a42 100644
--- a/dlls/wined3d/drawprim.c
+++ b/dlls/wined3d/drawprim.c
@@ -469,9 +469,9 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s
     BOOL emulation = FALSE, rasterizer_discard = FALSE;
     const struct wined3d_fb_state *fb = state->fb;
     const struct wined3d_stream_info *stream_info;
-    struct wined3d_event_query *ib_query = NULL;
     struct wined3d_rendertarget_view *dsv, *rtv;
     struct wined3d_stream_info si_emulated;
+    struct wined3d_fence *ib_fence = NULL;
     const struct wined3d_gl_info *gl_info;
     struct wined3d_context *context;
     unsigned int i, idx_size = 0;
@@ -556,7 +556,7 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s
         }
         else
         {
-            ib_query = index_buffer->query;
+            ib_fence = index_buffer->fence;
             idx_data = NULL;
         }
         idx_data = (const BYTE *)idx_data + state->index_offset;
@@ -655,10 +655,10 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s
         checkGLcall("disable rasterizer discard");
     }
 
-    if (ib_query)
-        wined3d_event_query_issue(ib_query, device);
-    for (i = 0; i < context->num_buffer_queries; ++i)
-        wined3d_event_query_issue(context->buffer_queries[i], device);
+    if (ib_fence)
+        wined3d_fence_issue(ib_fence, device);
+    for (i = 0; i < context->buffer_fence_count; ++i)
+        wined3d_fence_issue(context->buffer_fences[i], device);
 
     if (wined3d_settings.strict_draw_ordering)
         gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */
diff --git a/dlls/wined3d/query.c b/dlls/wined3d/query.c
index e76011ce2c..7d726d0883 100644
--- a/dlls/wined3d/query.c
+++ b/dlls/wined3d/query.c
@@ -83,33 +83,33 @@ static struct wined3d_pipeline_statistics_query *wined3d_pipeline_statistics_que
     return CONTAINING_RECORD(query, struct wined3d_pipeline_statistics_query, query);
 }
 
-static BOOL wined3d_event_query_supported(const struct wined3d_gl_info *gl_info)
+static BOOL wined3d_fence_supported(const struct wined3d_gl_info *gl_info)
 {
     return gl_info->supported[ARB_SYNC] || gl_info->supported[NV_FENCE] || gl_info->supported[APPLE_FENCE];
 }
 
-static enum wined3d_event_query_result wined3d_event_query_test(const struct wined3d_event_query *query,
+static enum wined3d_fence_result wined3d_fence_test(const struct wined3d_fence *fence,
         const struct wined3d_device *device, DWORD flags)
 {
     const struct wined3d_gl_info *gl_info;
-    enum wined3d_event_query_result ret;
     struct wined3d_context *context;
+    enum wined3d_fence_result ret;
     BOOL fence_result;
 
-    TRACE("query %p, device %p, flags %#x.\n", query, device, flags);
+    TRACE("fence %p, device %p, flags %#x.\n", fence, device, flags);
 
-    if (!query->context)
+    if (!fence->context)
     {
-        TRACE("Query not started.\n");
-        return WINED3D_EVENT_QUERY_NOT_STARTED;
+        TRACE("Fence not issued.\n");
+        return WINED3D_FENCE_NOT_STARTED;
     }
 
-    if (!(context = context_reacquire(device, query->context)))
+    if (!(context = context_reacquire(device, fence->context)))
     {
-        if (!query->context->gl_info->supported[ARB_SYNC])
+        if (!fence->context->gl_info->supported[ARB_SYNC])
         {
-            WARN("Event query tested from wrong thread.\n");
-            return WINED3D_EVENT_QUERY_WRONG_THREAD;
+            WARN("Fence tested from wrong thread.\n");
+            return WINED3D_FENCE_WRONG_THREAD;
         }
         context = context_acquire(device, NULL, 0);
     }
@@ -117,7 +117,7 @@ static enum wined3d_event_query_result wined3d_event_query_test(const struct win
 
     if (gl_info->supported[ARB_SYNC])
     {
-        GLenum gl_ret = GL_EXTCALL(glClientWaitSync(query->object.sync,
+        GLenum gl_ret = GL_EXTCALL(glClientWaitSync(fence->object.sync,
                 (flags & WINED3DGETDATA_FLUSH) ? GL_SYNC_FLUSH_COMMANDS_BIT : 0, 0));
         checkGLcall("glClientWaitSync");
 
@@ -125,68 +125,72 @@ static enum wined3d_event_query_result wined3d_event_query_test(const struct win
         {
             case GL_ALREADY_SIGNALED:
             case GL_CONDITION_SATISFIED:
-                ret = WINED3D_EVENT_QUERY_OK;
+                ret = WINED3D_FENCE_OK;
                 break;
 
             case GL_TIMEOUT_EXPIRED:
-                ret = WINED3D_EVENT_QUERY_WAITING;
+                ret = WINED3D_FENCE_WAITING;
                 break;
 
             case GL_WAIT_FAILED:
             default:
                 ERR("glClientWaitSync returned %#x.\n", gl_ret);
-                ret = WINED3D_EVENT_QUERY_ERROR;
+                ret = WINED3D_FENCE_ERROR;
         }
     }
     else if (gl_info->supported[APPLE_FENCE])
     {
-        fence_result = GL_EXTCALL(glTestFenceAPPLE(query->object.id));
+        fence_result = GL_EXTCALL(glTestFenceAPPLE(fence->object.id));
         checkGLcall("glTestFenceAPPLE");
-        if (fence_result) ret = WINED3D_EVENT_QUERY_OK;
-        else ret = WINED3D_EVENT_QUERY_WAITING;
+        if (fence_result)
+            ret = WINED3D_FENCE_OK;
+        else
+            ret = WINED3D_FENCE_WAITING;
     }
     else if (gl_info->supported[NV_FENCE])
     {
-        fence_result = GL_EXTCALL(glTestFenceNV(query->object.id));
+        fence_result = GL_EXTCALL(glTestFenceNV(fence->object.id));
         checkGLcall("glTestFenceNV");
-        if (fence_result) ret = WINED3D_EVENT_QUERY_OK;
-        else ret = WINED3D_EVENT_QUERY_WAITING;
+        if (fence_result)
+            ret = WINED3D_FENCE_OK;
+        else
+            ret = WINED3D_FENCE_WAITING;
     }
     else
     {
-        ERR("Event query created despite lack of GL support\n");
-        ret = WINED3D_EVENT_QUERY_ERROR;
+        ERR("Fence created despite lack of GL support.\n");
+        ret = WINED3D_FENCE_ERROR;
     }
 
     context_release(context);
     return ret;
 }
 
-enum wined3d_event_query_result wined3d_event_query_finish(const struct wined3d_event_query *query,
+enum wined3d_fence_result wined3d_fence_wait(const struct wined3d_fence *fence,
         const struct wined3d_device *device)
 {
     const struct wined3d_gl_info *gl_info;
-    enum wined3d_event_query_result ret;
     struct wined3d_context *context;
+    enum wined3d_fence_result ret;
 
-    TRACE("query %p, device %p.\n", query, device);
+    TRACE("fence %p, device %p.\n", fence, device);
 
-    if (!query->context)
+    if (!fence->context)
     {
-        TRACE("Query not started.\n");
-        return WINED3D_EVENT_QUERY_NOT_STARTED;
+        TRACE("Fence not issued.\n");
+        return WINED3D_FENCE_NOT_STARTED;
     }
-    gl_info = query->context->gl_info;
+    gl_info = fence->context->gl_info;
 
-    if (!(context = context_reacquire(device, query->context)))
+    if (!(context = context_reacquire(device, fence->context)))
     {
         /* A glFinish does not reliably wait for draws in other contexts. The caller has
          * to find its own way to cope with the thread switch
          */
         if (!gl_info->supported[ARB_SYNC])
         {
-            WARN("Event query finished from wrong thread.\n");
-            return WINED3D_EVENT_QUERY_WRONG_THREAD;
+            WARN("Fence finished from wrong thread.\n");
+            return WINED3D_FENCE_WRONG_THREAD;
         }
         context = context_acquire(device, NULL, 0);
     }
@@ -197,79 +201,127 @@ enum wined3d_event_query_result wined3d_event_query_finish(const struct wined3d_
         /* Apple seems to be into arbitrary limits, and timeouts larger than
          * 0xfffffffffffffbff immediately return GL_TIMEOUT_EXPIRED. We don't
          * really care and can live with waiting a few μs less. (OS X 10.7.4). */
-        GLenum gl_ret = GL_EXTCALL(glClientWaitSync(query->object.sync, GL_SYNC_FLUSH_COMMANDS_BIT, ~(GLuint64)0xffff));
+        GLenum gl_ret = GL_EXTCALL(glClientWaitSync(fence->object.sync,
+                GL_SYNC_FLUSH_COMMANDS_BIT, ~(GLuint64)0xffff));
         checkGLcall("glClientWaitSync");
 
         switch (gl_ret)
         {
             case GL_ALREADY_SIGNALED:
             case GL_CONDITION_SATISFIED:
-                ret = WINED3D_EVENT_QUERY_OK;
+                ret = WINED3D_FENCE_OK;
                 break;
 
                 /* We don't expect a timeout for a ~584 year wait */
             default:
                 ERR("glClientWaitSync returned %#x.\n", gl_ret);
-                ret = WINED3D_EVENT_QUERY_ERROR;
+                ret = WINED3D_FENCE_ERROR;
         }
     }
     else if (context->gl_info->supported[APPLE_FENCE])
     {
-        GL_EXTCALL(glFinishFenceAPPLE(query->object.id));
+        GL_EXTCALL(glFinishFenceAPPLE(fence->object.id));
         checkGLcall("glFinishFenceAPPLE");
-        ret = WINED3D_EVENT_QUERY_OK;
+        ret = WINED3D_FENCE_OK;
     }
     else if (context->gl_info->supported[NV_FENCE])
     {
-        GL_EXTCALL(glFinishFenceNV(query->object.id));
+        GL_EXTCALL(glFinishFenceNV(fence->object.id));
         checkGLcall("glFinishFenceNV");
-        ret = WINED3D_EVENT_QUERY_OK;
+        ret = WINED3D_FENCE_OK;
     }
     else
     {
-        ERR("Event query created without GL support\n");
-        ret = WINED3D_EVENT_QUERY_ERROR;
+        ERR("Fence created without GL support.\n");
+        ret = WINED3D_FENCE_ERROR;
     }
 
     context_release(context);
     return ret;
 }
 
-void wined3d_event_query_issue(struct wined3d_event_query *query, const struct wined3d_device *device)
+void wined3d_fence_issue(struct wined3d_fence *fence, const struct wined3d_device *device)
 {
     struct wined3d_context *context = NULL;
     const struct wined3d_gl_info *gl_info;
 
-    if (query->context && !(context = context_reacquire(device, query->context))
-            && !query->context->gl_info->supported[ARB_SYNC])
-        context_free_event_query(query);
+    if (fence->context && !(context = context_reacquire(device, fence->context))
+            && !fence->context->gl_info->supported[ARB_SYNC])
+        context_free_fence(fence);
     if (!context)
         context = context_acquire(device, NULL, 0);
     gl_info = context->gl_info;
-    if (!query->context)
-        context_alloc_event_query(context, query);
+    if (!fence->context)
+        context_alloc_fence(context, fence);
 
     if (gl_info->supported[ARB_SYNC])
     {
-        if (query->object.sync) GL_EXTCALL(glDeleteSync(query->object.sync));
+        if (fence->object.sync)
+            GL_EXTCALL(glDeleteSync(fence->object.sync));
         checkGLcall("glDeleteSync");
-        query->object.sync = GL_EXTCALL(glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0));
+        fence->object.sync = GL_EXTCALL(glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0));
         checkGLcall("glFenceSync");
     }
     else if (gl_info->supported[APPLE_FENCE])
     {
-        GL_EXTCALL(glSetFenceAPPLE(query->object.id));
+        GL_EXTCALL(glSetFenceAPPLE(fence->object.id));
         checkGLcall("glSetFenceAPPLE");
     }
     else if (gl_info->supported[NV_FENCE])
     {
-        GL_EXTCALL(glSetFenceNV(query->object.id, GL_ALL_COMPLETED_NV));
+        GL_EXTCALL(glSetFenceNV(fence->object.id, GL_ALL_COMPLETED_NV));
         checkGLcall("glSetFenceNV");
     }
 
     context_release(context);
 }
 
+static void wined3d_fence_free(struct wined3d_fence *fence)
+{
+    if (fence->context)
+        context_free_fence(fence);
+}
+
+void wined3d_fence_destroy(struct wined3d_fence *fence)
+{
+    wined3d_fence_free(fence);
+    HeapFree(GetProcessHeap(), 0, fence);
+}
+
+static HRESULT wined3d_fence_init(struct wined3d_fence *fence, const struct wined3d_gl_info *gl_info)
+{
+    if (!wined3d_fence_supported(gl_info))
+    {
+        WARN("Fences not supported.\n");
+        return WINED3DERR_NOTAVAILABLE;
+    }
+
+    return WINED3D_OK;
+}
+
+HRESULT wined3d_fence_create(struct wined3d_device *device, struct wined3d_fence **fence)
+{
+    const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+    struct wined3d_fence *object;
+    HRESULT hr;
+
+    TRACE("device %p, fence %p.\n", device, fence);
+
+    if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
+        return E_OUTOFMEMORY;
+
+    if (FAILED(hr = wined3d_fence_init(object, gl_info)))
+    {
+        HeapFree(GetProcessHeap(), 0, object);
+        return hr;
+    }
+
+    TRACE("Created fence %p.\n", object);
+    *fence = object;
+
+    return WINED3D_OK;
+}
+
 ULONG CDECL wined3d_query_incref(struct wined3d_query *query)
 {
     ULONG refcount = InterlockedIncrement(&query->ref);
@@ -407,25 +459,25 @@ static BOOL wined3d_occlusion_query_ops_poll(struct wined3d_query *query, DWORD
 static BOOL wined3d_event_query_ops_poll(struct wined3d_query *query, DWORD flags)
 {
     struct wined3d_event_query *event_query = wined3d_event_query_from_query(query);
-    enum wined3d_event_query_result ret;
+    enum wined3d_fence_result ret;
 
     TRACE("query %p, flags %#x.\n", query, flags);
 
-    ret = wined3d_event_query_test(event_query, query->device, flags);
+    ret = wined3d_fence_test(&event_query->fence, query->device, flags);
     switch (ret)
     {
-        case WINED3D_EVENT_QUERY_OK:
-        case WINED3D_EVENT_QUERY_NOT_STARTED:
+        case WINED3D_FENCE_OK:
+        case WINED3D_FENCE_NOT_STARTED:
             return event_query->signalled = TRUE;
 
-        case WINED3D_EVENT_QUERY_WAITING:
+        case WINED3D_FENCE_WAITING:
             return event_query->signalled = FALSE;
 
-        case WINED3D_EVENT_QUERY_WRONG_THREAD:
+        case WINED3D_FENCE_WRONG_THREAD:
             FIXME("(%p) Wrong thread, reporting GPU idle.\n", query);
             return event_query->signalled = TRUE;
 
-        case WINED3D_EVENT_QUERY_ERROR:
+        case WINED3D_FENCE_ERROR:
             ERR("The GL event query failed.\n");
             return event_query->signalled = TRUE;
 
@@ -457,7 +509,7 @@ static BOOL wined3d_event_query_ops_issue(struct wined3d_query *query, DWORD fla
     {
         struct wined3d_event_query *event_query = wined3d_event_query_from_query(query);
 
-        wined3d_event_query_issue(event_query, query->device);
+        wined3d_fence_issue(&event_query->fence, query->device);
         return TRUE;
     }
     else if (flags & WINED3DISSUE_BEGIN)
@@ -864,8 +916,7 @@ static void wined3d_event_query_ops_destroy(struct wined3d_query *query)
 {
     struct wined3d_event_query *event_query = wined3d_event_query_from_query(query);
 
-    if (event_query->context)
-        context_free_event_query(event_query);
+    wined3d_fence_free(&event_query->fence);
     HeapFree(GetProcessHeap(), 0, event_query);
 }
 
@@ -882,19 +933,21 @@ static HRESULT wined3d_event_query_create(struct wined3d_device *device,
 {
     const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
     struct wined3d_event_query *object;
+    HRESULT hr;
 
     TRACE("device %p, type %#x, parent %p, parent_ops %p, query %p.\n",
             device, type, parent, parent_ops, query);
 
-    if (!wined3d_event_query_supported(gl_info))
+    if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
+        return E_OUTOFMEMORY;
+
+    if (FAILED(hr = wined3d_fence_init(&object->fence, gl_info)))
     {
         WARN("Event queries not supported.\n");
+        HeapFree(GetProcessHeap(), 0, object);
         return WINED3DERR_NOTAVAILABLE;
     }
 
-    if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
-        return E_OUTOFMEMORY;
-
     wined3d_query_init(&object->query, device, type, &object->signalled,
             sizeof(object->signalled), &event_query_ops, parent, parent_ops);
 
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index d687e780ea..ccf05635f0 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1607,6 +1607,34 @@ enum fogsource {
     FOGSOURCE_COORD,
 };
 
+union wined3d_gl_fence_object
+{
+    GLuint id;
+    GLsync sync;
+};
+
+enum wined3d_fence_result
+{
+    WINED3D_FENCE_OK,
+    WINED3D_FENCE_WAITING,
+    WINED3D_FENCE_NOT_STARTED,
+    WINED3D_FENCE_WRONG_THREAD,
+    WINED3D_FENCE_ERROR,
+};
+
+struct wined3d_fence
+{
+    struct list entry;
+    union wined3d_gl_fence_object object;
+    struct wined3d_context *context;
+};
+
+HRESULT wined3d_fence_create(struct wined3d_device *device, struct wined3d_fence **fence) DECLSPEC_HIDDEN;
+void wined3d_fence_destroy(struct wined3d_fence *fence) DECLSPEC_HIDDEN;
+void wined3d_fence_issue(struct wined3d_fence *fence, const struct wined3d_device *device) DECLSPEC_HIDDEN;
+enum wined3d_fence_result wined3d_fence_wait(const struct wined3d_fence *fence,
+        const struct wined3d_device *device) DECLSPEC_HIDDEN;
+
 /* Direct3D terminology with little modifications. We do not have an issued
  * state because only the driver knows about it, but we have a created state
  * because D3D allows GetData() on a created query, but OpenGL doesn't. */
@@ -1641,35 +1669,14 @@ struct wined3d_query
     struct list poll_list_entry;
 };
 
-union wined3d_gl_query_object
-{
-    GLuint id;
-    GLsync sync;
-};
-
 struct wined3d_event_query
 {
     struct wined3d_query query;
 
-    struct list entry;
-    union wined3d_gl_query_object object;
-    struct wined3d_context *context;
+    struct wined3d_fence fence;
     BOOL signalled;
 };
 
-enum wined3d_event_query_result
-{
-    WINED3D_EVENT_QUERY_OK,
-    WINED3D_EVENT_QUERY_WAITING,
-    WINED3D_EVENT_QUERY_NOT_STARTED,
-    WINED3D_EVENT_QUERY_WRONG_THREAD,
-    WINED3D_EVENT_QUERY_ERROR
-};
-
-enum wined3d_event_query_result wined3d_event_query_finish(const struct wined3d_event_query *query,
-        const struct wined3d_device *device) DECLSPEC_HIDDEN;
-void wined3d_event_query_issue(struct wined3d_event_query *query, const struct wined3d_device *device) DECLSPEC_HIDDEN;
-
 struct wined3d_occlusion_query
 {
     struct wined3d_query query;
@@ -1875,10 +1882,10 @@ struct wined3d_context
     unsigned int free_occlusion_query_count;
     struct list occlusion_queries;
 
-    union wined3d_gl_query_object *free_event_queries;
-    SIZE_T free_event_query_size;
-    unsigned int free_event_query_count;
-    struct list event_queries;
+    union wined3d_gl_fence_object *free_fences;
+    SIZE_T free_fence_size;
+    unsigned int free_fence_count;
+    struct list fences;
 
     GLuint *free_timestamp_queries;
     SIZE_T free_timestamp_query_size;
@@ -1898,8 +1905,8 @@ struct wined3d_context
     struct wined3d_stream_info stream_info;
 
     /* Fences for GL_APPLE_flush_buffer_range */
-    struct wined3d_event_query *buffer_queries[MAX_ATTRIBS];
-    unsigned int num_buffer_queries;
+    struct wined3d_fence *buffer_fences[MAX_ATTRIBS];
+    unsigned int buffer_fence_count;
 
     DWORD tex_unit_map[MAX_COMBINED_SAMPLERS];
     DWORD rev_tex_unit_map[MAX_GL_FRAGMENT_SAMPLERS + MAX_VERTEX_SAMPLERS];
@@ -2046,8 +2053,7 @@ BOOL wined3d_clip_blit(const RECT *clip_rect, RECT *clipped, RECT *other) DECLSP
 
 struct wined3d_context *context_acquire(const struct wined3d_device *device,
         struct wined3d_texture *texture, unsigned int sub_resource_idx) DECLSPEC_HIDDEN;
-void context_alloc_event_query(struct wined3d_context *context,
-        struct wined3d_event_query *query) DECLSPEC_HIDDEN;
+void context_alloc_fence(struct wined3d_context *context, struct wined3d_fence *fence) DECLSPEC_HIDDEN;
 void context_alloc_occlusion_query(struct wined3d_context *context,
         struct wined3d_occlusion_query *query) DECLSPEC_HIDDEN;
 void context_apply_blit_state(struct wined3d_context *context, const struct wined3d_device *device) DECLSPEC_HIDDEN;
@@ -2071,7 +2077,7 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, stru
 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_fence(struct wined3d_fence *fence) DECLSPEC_HIDDEN;
 void context_free_occlusion_query(struct wined3d_occlusion_query *query) DECLSPEC_HIDDEN;
 struct wined3d_context *context_get_current(void) DECLSPEC_HIDDEN;
 GLenum context_get_offscreen_gl_buffer(const struct wined3d_context *context) DECLSPEC_HIDDEN;
@@ -3532,7 +3538,7 @@ struct wined3d_buffer
 
     struct wined3d_map_range *maps;
     SIZE_T maps_size, modified_areas;
-    struct wined3d_event_query *query;
+    struct wined3d_fence *fence;
 
     /* conversion stuff */
     UINT decl_change_count, full_conversion_count;
-- 
2.13.0




More information about the wine-patches mailing list