From 8e01eb01c272eab21e90771ff624ebc0aa554013 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stefan=20D=C3=B6singer?= <stefan@codeweavers.com>
Date: Fri, 12 Feb 2010 21:02:23 +0100
Subject: [PATCH 04/12] WineD3D: Introduce wined3d_event_query_finish

---
 dlls/wined3d/query.c           |   68 ++++++++++++++++++++++++++++++++++++++++
 dlls/wined3d/wined3d_private.h |    1 +
 2 files changed, 69 insertions(+), 0 deletions(-)

diff --git a/dlls/wined3d/query.c b/dlls/wined3d/query.c
index f813819..12cb5e4 100644
--- a/dlls/wined3d/query.c
+++ b/dlls/wined3d/query.c
@@ -593,3 +593,71 @@ void wined3d_event_query_issue(struct wined3d_event_query *query, IWineD3DDevice
 
     context_release(context);
 }
+
+enum wined3d_event_query_result wined3d_event_query_finish(struct wined3d_event_query *query, IWineD3DDeviceImpl *device)
+{
+    struct wined3d_context *context;
+    const struct wined3d_gl_info *gl_info;
+    enum wined3d_event_query_result ret;
+
+    TRACE("(%p)\n", query);
+
+    if (!query->context)
+    {
+        TRACE("Query not started\n");
+        return WINED3D_EVENT_QUERY_NOT_STARTED;
+    }
+    gl_info = query->context->gl_info;
+
+    if (query->context->tid != GetCurrentThreadId() && !gl_info->supported[ARB_SYNC])
+    {
+        /* 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
+         */
+        WARN("Event query finished from wrong thread\n");
+        return WINED3D_EVENT_QUERY_WRONG_THREAD;
+    }
+
+    context = context_acquire(device, query->context->current_rt, CTXUSAGE_RESOURCELOAD);
+
+    ENTER_GL();
+    if (gl_info->supported[ARB_SYNC])
+    {
+        GLenum gl_ret = GL_EXTCALL(glClientWaitSync(query->object.sync, GL_SYNC_FLUSH_COMMANDS_BIT, ~0U));
+        checkGLcall("glClientWaitSync");
+
+        switch (gl_ret)
+        {
+            case GL_ALREADY_SIGNALED:
+            case GL_CONDITION_SATISFIED:
+                ret = WINED3D_EVENT_QUERY_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;
+        }
+    }
+    else if (context->gl_info->supported[APPLE_FENCE])
+    {
+        GL_EXTCALL(glFinishFenceAPPLE(query->object.id));
+        checkGLcall("glFinishFenceAPPLE");
+        ret = WINED3D_EVENT_QUERY_OK;
+    }
+    else if (context->gl_info->supported[NV_FENCE])
+    {
+        GL_EXTCALL(glFinishFenceNV(query->object.id));
+        checkGLcall("glFinishFenceNV");
+        ret = WINED3D_EVENT_QUERY_OK;
+    }
+    else
+    {
+        ERR("Event query created without GL support\n");
+        ret = WINED3D_EVENT_QUERY_ERROR;
+    }
+    LEAVE_GL();
+
+    context_release(context);
+    return ret;
+}
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index f6a28a9..55b8cee 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1039,6 +1039,7 @@ enum wined3d_event_query_result
 };
 
 enum wined3d_event_query_result wined3d_event_query_test(struct wined3d_event_query *query, IWineD3DDeviceImpl *device) DECLSPEC_HIDDEN;
+enum wined3d_event_query_result wined3d_event_query_finish(struct wined3d_event_query *query, IWineD3DDeviceImpl *device) DECLSPEC_HIDDEN;
 void wined3d_event_query_issue(struct wined3d_event_query *query, IWineD3DDeviceImpl *device) DECLSPEC_HIDDEN;
 HRESULT wined3d_event_query_init(const struct wined3d_gl_info *gl_info, struct wined3d_event_query **query) DECLSPEC_HIDDEN;
 void wined3d_event_query_destroy(struct wined3d_event_query *query) DECLSPEC_HIDDEN;
-- 
1.6.4.4

