From f88dffa1468c640f9f75e6083d91430fba242692 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stefan=20D=C3=B6singer?= <stefan@codeweavers.com>
Date: Fri, 5 Feb 2010 13:14:05 +0100
Subject: [PATCH 01/12] WineD3D: introduce wined3d_event_query_test

---
 dlls/wined3d/query.c           |  146 +++++++++++++++++++++++++---------------
 dlls/wined3d/wined3d_private.h |   12 +++
 2 files changed, 104 insertions(+), 54 deletions(-)

diff --git a/dlls/wined3d/query.c b/dlls/wined3d/query.c
index 85d5311..fea4a98 100644
--- a/dlls/wined3d/query.c
+++ b/dlls/wined3d/query.c
@@ -179,78 +179,43 @@ static HRESULT  WINAPI IWineD3DOcclusionQueryImpl_GetData(IWineD3DQuery* iface,
 static HRESULT  WINAPI IWineD3DEventQueryImpl_GetData(IWineD3DQuery* iface, void* pData, DWORD dwSize, DWORD dwGetDataFlags) {
     IWineD3DQueryImpl *This = (IWineD3DQueryImpl *) iface;
     struct wined3d_event_query *query = This->extendedData;
-    const struct wined3d_gl_info *gl_info;
-    struct wined3d_context *context;
     BOOL *data = pData;
 
     TRACE("(%p) : type D3DQUERY_EVENT, pData %p, dwSize %#x, dwGetDataFlags %#x\n", This, pData, dwSize, dwGetDataFlags);
 
     if (!pData || !dwSize) return S_OK;
 
-    if (!query->context)
-    {
-        TRACE("Query not started, returning TRUE.\n");
-        *data = TRUE;
-
-        return S_OK;
-    }
-
-    if (!query->context->gl_info->supported[ARB_SYNC] && query->context->tid != GetCurrentThreadId())
-    {
-        /* See comment in IWineD3DQuery::Issue, event query codeblock */
-        FIXME("Wrong thread, reporting GPU idle.\n");
-        *data = TRUE;
-
-        return S_OK;
-    }
-
-    context = context_acquire(This->device, query->context->current_rt, CTXUSAGE_RESOURCELOAD);
-    gl_info = context->gl_info;
-
-    ENTER_GL();
-
-    if (gl_info->supported[ARB_SYNC])
+    if (data)
     {
-        GLenum ret = GL_EXTCALL(glClientWaitSync(query->object.sync, 0, 0));
-        checkGLcall("glClientWaitSync");
+        enum wined3d_event_query_result ret;
 
-        switch (ret)
+        ret = wined3d_event_query_test(query, This->device);
+        switch(ret)
         {
-            case GL_ALREADY_SIGNALED:
-            case GL_CONDITION_SATISFIED:
+            case WINED3D_EVENT_QUERY_OK:
+            case WINED3D_EVENT_QUERY_NOT_STARTED:
                 *data = TRUE;
                 break;
 
-            case GL_TIMEOUT_EXPIRED:
+            case WINED3D_EVENT_QUERY_WAITING:
                 *data = FALSE;
                 break;
 
-            case GL_WAIT_FAILED:
-            default:
-                ERR("glClientWaitSync returned %#x.\n", ret);
-                *data = FALSE;
+            case WINED3D_EVENT_QUERY_WRONG_THREAD:
+                FIXME("(%p) Wrong thread, reporting GPU idle.\n", This);
+                *data = TRUE;
                 break;
-        }
-    }
-    else if (gl_info->supported[APPLE_FENCE])
-    {
-        *data = GL_EXTCALL(glTestFenceAPPLE(query->object.id));
-        checkGLcall("glTestFenceAPPLE");
-    }
-    else if (gl_info->supported[NV_FENCE])
-    {
-        *data = GL_EXTCALL(glTestFenceNV(query->object.id));
-        checkGLcall("glTestFenceNV");
-    }
-    else
-    {
-        WARN("(%p): reporting GPU idle\n", This);
-        *data = TRUE;
-    }
 
-    LEAVE_GL();
+            case WINED3D_EVENT_QUERY_UNSUPPORTED:
+                WARN("(%p): Event query not supported by GL, reporting GPU idle\n", This);
+                *data = TRUE;
+                break;
 
-    context_release(context);
+            case WINED3D_EVENT_QUERY_ERROR:
+                ERR("The GL event query failed, returning D3DERR_INVALIDCALL\n");
+                return WINED3DERR_INVALIDCALL;
+        }
+    }
 
     return S_OK;
 }
@@ -524,3 +489,76 @@ HRESULT query_init(IWineD3DQueryImpl *query, IWineD3DDeviceImpl *device,
 
     return WINED3D_OK;
 }
+
+enum wined3d_event_query_result wined3d_event_query_test(struct wined3d_event_query *query, IWineD3DDeviceImpl *device)
+{
+    struct wined3d_context *context;
+    const struct wined3d_gl_info *gl_info;
+    enum wined3d_event_query_result ret;
+    BOOL fence_result;
+
+    TRACE("(%p) : device %p\n", query, device);
+
+    if (query->context == NULL)
+    {
+        TRACE("Query not started\n");
+        return WINED3D_EVENT_QUERY_NOT_STARTED;
+    }
+
+    if (!query->context->gl_info->supported[ARB_SYNC] && query->context->tid != GetCurrentThreadId())
+    {
+        WARN("Event query tested from wrong thread\n");
+        return WINED3D_EVENT_QUERY_WRONG_THREAD;
+    }
+
+    context = context_acquire(device, query->context->current_rt, CTXUSAGE_RESOURCELOAD);
+    gl_info = context->gl_info;
+
+    ENTER_GL();
+
+    if (gl_info->supported[ARB_SYNC])
+    {
+        GLenum gl_ret = GL_EXTCALL(glClientWaitSync(query->object.sync, 0, 0));
+        checkGLcall("glClientWaitSync");
+
+        switch (gl_ret)
+        {
+            case GL_ALREADY_SIGNALED:
+            case GL_CONDITION_SATISFIED:
+                ret = WINED3D_EVENT_QUERY_OK;
+                break;
+
+            case GL_TIMEOUT_EXPIRED:
+                ret = WINED3D_EVENT_QUERY_WAITING;
+                break;
+
+            case GL_WAIT_FAILED:
+            default:
+                ERR("glClientWaitSync returned %#x.\n", gl_ret);
+                ret = WINED3D_EVENT_QUERY_ERROR;
+        }
+    }
+    else if (gl_info->supported[APPLE_FENCE])
+    {
+        fence_result = GL_EXTCALL(glTestFenceAPPLE(query->object.id));
+        checkGLcall("glTestFenceAPPLE");
+        if (fence_result) ret = WINED3D_EVENT_QUERY_OK;
+        else ret = WINED3D_EVENT_QUERY_WAITING;
+    }
+    else if (gl_info->supported[NV_FENCE])
+    {
+        fence_result = GL_EXTCALL(glTestFenceNV(query->object.id));
+        checkGLcall("glTestFenceNV");
+        if (fence_result) ret = WINED3D_EVENT_QUERY_OK;
+        else ret = WINED3D_EVENT_QUERY_WAITING;
+    }
+    else
+    {
+        ret = WINED3D_EVENT_QUERY_UNSUPPORTED;
+    }
+
+    LEAVE_GL();
+
+    context_release(context);
+    return ret;
+}
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 5dcc521..c33a303 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1029,6 +1029,18 @@ struct wined3d_event_query
     struct wined3d_context *context;
 };
 
+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,
+    WINED3D_EVENT_QUERY_UNSUPPORTED
+};
+
+enum wined3d_event_query_result wined3d_event_query_test(struct wined3d_event_query *query, IWineD3DDeviceImpl *device) DECLSPEC_HIDDEN;
+
 struct wined3d_context
 {
     const struct wined3d_gl_info *gl_info;
-- 
1.6.4.4

