From 86aec139822a253345585afde5729aff8aa56a2a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stefan=20D=C3=B6singer?= <stefan@codeweavers.com>
Date: Tue, 26 Jan 2010 16:00:46 +0100
Subject: [PATCH 02/18] d3d: Move event query faking to d3d9

d3d9 is the only client library that needs this feature. ddraw and d3d8 don't support queries, and all d3d10 drivers support either APPLE_fence or ARB_sync.

Once Mesa supports ARB_sync and is useable on r300-r500 cards we can remove the event query faking entirely.
---
 dlls/d3d9/query.c    |   60 +++++++++++++++++++++++++++++++++++++++++++++----
 dlls/wined3d/query.c |   12 +--------
 2 files changed, 57 insertions(+), 15 deletions(-)

diff --git a/dlls/d3d9/query.c b/dlls/d3d9/query.c
index a38dc9d..ccf0f2e 100644
--- a/dlls/d3d9/query.c
+++ b/dlls/d3d9/query.c
@@ -59,9 +59,12 @@ static ULONG WINAPI IDirect3DQuery9Impl_Release(LPDIRECT3DQUERY9 iface) {
     TRACE("%p decreasing refcount to %u.\n", iface, ref);
 
     if (ref == 0) {
-        wined3d_mutex_lock();
-        IWineD3DQuery_Release(This->wineD3DQuery);
-        wined3d_mutex_unlock();
+        if(This->wineD3DQuery)
+        {
+            wined3d_mutex_lock();
+            IWineD3DQuery_Release(This->wineD3DQuery);
+            wined3d_mutex_unlock();
+        }
 
         IDirect3DDevice9Ex_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
@@ -150,6 +153,42 @@ static const IDirect3DQuery9Vtbl Direct3DQuery9_Vtbl =
     IDirect3DQuery9Impl_GetData
 };
 
+/* Faked event query */
+static D3DQUERYTYPE WINAPI IDirect3DFakeEventQuery9Impl_GetType(LPDIRECT3DQUERY9 iface) {
+    TRACE("iface %p.\n", iface);
+    return D3DQUERYTYPE_EVENT;
+}
+
+static DWORD WINAPI IDirect3DFakeEventQuery9Impl_GetDataSize(LPDIRECT3DQUERY9 iface) {
+    TRACE("iface %p.\n", iface);
+    return sizeof(BOOL);
+}
+
+static HRESULT WINAPI IDirect3DFakeEventQuery9Impl_Issue(LPDIRECT3DQUERY9 iface, DWORD dwIssueFlags) {
+    TRACE("iface %p, flags %#x.\n", iface, dwIssueFlags);
+    return D3D_OK;
+}
+
+static HRESULT WINAPI IDirect3DFakeEventQuery9Impl_GetData(LPDIRECT3DQUERY9 iface, void* pData, DWORD dwSize, DWORD dwGetDataFlags) {
+    WARN("iface %p, data %p, size %u, flags %#x. Reporting GPU idle\n",
+          iface, pData, dwSize, dwGetDataFlags);
+
+    if(pData) *((BOOL *) pData) = TRUE;
+    return D3D_OK;
+}
+
+static const IDirect3DQuery9Vtbl Direct3DFakeEventQuery9_Vtbl =
+{
+    IDirect3DQuery9Impl_QueryInterface,
+    IDirect3DQuery9Impl_AddRef,
+    IDirect3DQuery9Impl_Release,
+    IDirect3DQuery9Impl_GetDevice,
+    IDirect3DFakeEventQuery9Impl_GetType,
+    IDirect3DFakeEventQuery9Impl_GetDataSize,
+    IDirect3DFakeEventQuery9Impl_Issue,
+    IDirect3DFakeEventQuery9Impl_GetData
+};
+
 HRESULT query_init(IDirect3DQuery9Impl *query, IDirect3DDevice9Impl *device, D3DQUERYTYPE type)
 {
     HRESULT hr;
@@ -162,8 +201,19 @@ HRESULT query_init(IDirect3DQuery9Impl *query, IDirect3DDevice9Impl *device, D3D
     wined3d_mutex_unlock();
     if (FAILED(hr))
     {
-        WARN("Failed to create wined3d query, hr %#x.\n", hr);
-        return hr;
+        if(type != D3DQUERYTYPE_EVENT)
+        {
+            WARN("Failed to create wined3d query, hr %#x.\n", hr);
+            return hr;
+        }
+        else
+        {
+            /* Half-Life 2 needs this query, but not all Linux GL drivers support it
+             * at this point(missing in Mesa and fglrx).
+             */
+            WARN("Event query not supported by WineD3D on this system, faking it\n");
+            query->lpVtbl = &Direct3DFakeEventQuery9_Vtbl;
+        }
     }
 
     query->parentDevice = (IDirect3DDevice9Ex *)device;
diff --git a/dlls/wined3d/query.c b/dlls/wined3d/query.c
index 3f1203a..220a316 100644
--- a/dlls/wined3d/query.c
+++ b/dlls/wined3d/query.c
@@ -235,11 +235,6 @@ static HRESULT  WINAPI IWineD3DEventQueryImpl_GetData(IWineD3DQuery* iface, void
         *data = GL_EXTCALL(glTestFenceNV(query->object.id));
         checkGLcall("glTestFenceNV");
     }
-    else
-    {
-        WARN("(%p): reporting GPU idle\n", This);
-        *data = TRUE;
-    }
 
     LEAVE_GL();
 
@@ -470,11 +465,8 @@ HRESULT query_init(IWineD3DQueryImpl *query, IWineD3DDeviceImpl *device,
             if (!gl_info->supported[ARB_SYNC] && !gl_info->supported[NV_FENCE]
                     && !gl_info->supported[APPLE_FENCE])
             {
-                /* Half-Life 2 needs this query. It does not render the main
-                 * menu correctly otherwise. Pretend to support it, faking
-                 * this query does not do much harm except potentially
-                 * lowering performance. */
-                FIXME("Event query: Unimplemented, but pretending to be supported.\n");
+                WARN("Unsupported in local OpenGL implementation: ARB_sync or APPLE/NV_fence.\n");
+                return WINED3DERR_NOTAVAILABLE;
             }
             query->lpVtbl = &IWineD3DEventQuery_Vtbl;
             query->extendedData = HeapAlloc(GetProcessHeap(), 0, sizeof(struct wined3d_event_query));
-- 
1.6.4.4

