[5/6] WineD3D: Support event queries using GL_NV_fence

Stefan Dösinger stefan at codeweavers.com
Wed Feb 28 18:53:46 CST 2007


The unsupported fixme is downgraded to a WARN because the faked event queries 
aren't much of a problem. Most likely printing the fixme will cause more 
performance loss than the missing query. And in any case we have the FIXME at 
the creation
-------------- next part --------------
From a08de5ec359792d89a9a01374248238ab092bdc2 Mon Sep 17 00:00:00 2001
From: Stefan Doesinger <stefan at codeweavers.com>
Date: Thu, 1 Mar 2007 00:34:33 +0100
Subject: [PATCH] WineD3D: Support event queries using GL_NV_fence

---
 dlls/wined3d/device.c          |   20 +++++++++++++++-----
 dlls/wined3d/query.c           |   28 ++++++++++++++++++++++++++--
 dlls/wined3d/wined3d_private.h |    3 +++
 3 files changed, 44 insertions(+), 7 deletions(-)

diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index bd37c51..3ab1279 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -1075,10 +1075,12 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateQuery(IWineD3DDevice *iface, WINE
         break;
 
     case WINED3DQUERYTYPE_EVENT:
-        /* 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("(%p) Event query: Unimplemented, but pretending to be supported\n", This);
+        if(!GL_SUPPORT(NV_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("(%p) Event query: Unimplemented, but pretending to be supported\n", This);
+        }
         hr = WINED3D_OK;
         break;
 
@@ -1112,10 +1114,18 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateQuery(IWineD3DDevice *iface, WINE
             GL_EXTCALL(glGenQueriesARB(1, &((WineQueryOcclusionData *)(object->extendedData))->queryId));
             break;
         }
+    case WINED3DQUERYTYPE_EVENT:
+        /* TODO: GL_APPLE_fence */
+        if(GL_SUPPORT(NV_FENCE)) {
+            object->extendedData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WineQueryEventData));
+            GL_EXTCALL(glGenFencesNV(1, &((WineQueryEventData *)(object->extendedData))->fenceId));
+            checkGLcall("glGenFencesNV");
+        }
+        break;
+
     case WINED3DQUERYTYPE_VCACHE:
     case WINED3DQUERYTYPE_RESOURCEMANAGER:
     case WINED3DQUERYTYPE_VERTEXSTATS:
-    case WINED3DQUERYTYPE_EVENT:
     case WINED3DQUERYTYPE_TIMESTAMP:
     case WINED3DQUERYTYPE_TIMESTAMPDISJOINT:
     case WINED3DQUERYTYPE_TIMESTAMPFREQ:
diff --git a/dlls/wined3d/query.c b/dlls/wined3d/query.c
index 41bebf6..10a43e3 100644
--- a/dlls/wined3d/query.c
+++ b/dlls/wined3d/query.c
@@ -65,6 +65,14 @@ static ULONG  WINAPI IWineD3DQueryImpl_Release(IWineD3DQuery *iface) {
     TRACE("(%p) : Releasing from %d\n", This, This->ref);
     ref = InterlockedDecrement(&This->ref);
     if (ref == 0) {
+        if(This->type == WINED3DQUERYTYPE_EVENT && GL_SUPPORT(NV_FENCE)) {
+            GL_EXTCALL(glDeleteFencesNV(1, &((WineQueryEventData *)(This->extendedData))->fenceId));
+            checkGLcall("glDeleteFencesNV");
+        } else if(This->type == WINED3DQUERYTYPE_OCCLUSION && GL_SUPPORT(ARB_OCCLUSION_QUERY)) {
+            GL_EXTCALL(glDeleteQueriesARB(1, &((WineQueryOcclusionData *)(This->extendedData))->queryId));
+            checkGLcall("glDeleteQueriesARB");
+        }
+
         HeapFree(GetProcessHeap(), 0, This->extendedData);
         HeapFree(GetProcessHeap(), 0, This);
     }
@@ -154,8 +162,13 @@ static HRESULT  WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa
     case WINED3DQUERYTYPE_EVENT:
     {
         BOOL* data = pData;
-        FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_EVENT\n", This);
-        *data = TRUE; /*Don't know what this is supposed to be*/
+        if(GL_SUPPORT(NV_FENCE)) {
+            *data = GL_EXTCALL(glTestFenceNV(((WineQueryEventData *)This->extendedData)->fenceId));
+            checkGLcall("glTestFenceNV");
+        } else {
+            WARN("(%p): reporting GPU idle\n", This);
+            *data = TRUE;
+        }
     }
     break;
     case WINED3DQUERYTYPE_OCCLUSION:
@@ -367,6 +380,17 @@ static HRESULT  WINAPI IWineD3DQueryImpl_Issue(IWineD3DQuery* iface,  DWORD dwIs
             }
             break;
 
+        case WINED3DQUERYTYPE_EVENT: {
+            if (GL_SUPPORT(GL_NV_fence)) {
+                if (dwIssueFlags & WINED3DISSUE_END) {
+                    GL_EXTCALL(glSetFenceNV(((WineQueryEventData *)This->extendedData)->fenceId, GL_ALL_COMPLETED_NV));
+                } else if(dwIssueFlags & WINED3DISSUE_BEGIN) {
+                    /* Started implicitly at device creation */
+                    ERR("Event query issued with START flag - what to do?\n");
+                }
+            }
+        }
+
         default:
             /* The fixme is printed when the app asks for the resulting data */
             WARN("(%p) : Unhandled query type %#x\n", This, This->type);
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 1a5d3eb..895a9c7 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1339,6 +1339,9 @@ typedef struct  WineQueryOcclusionData {
     GLuint  queryId;
 } WineQueryOcclusionData;
 
+typedef struct  WineQueryEventData {
+    GLuint  fenceId;
+} WineQueryEventData;
 
 /*****************************************************************************
  * IWineD3DSwapChainImpl implementation structure (extends IUnknown)
-- 
1.4.4.3



More information about the wine-patches mailing list