Stefan Dösinger : wined3d: Deal with multithreading in event queries.

Alexandre Julliard julliard at wine.codeweavers.com
Thu Aug 23 07:26:03 CDT 2007


Module: wine
Branch: master
Commit: a99907d1d22f28b4ae6a532bea963379c78ba21f
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=a99907d1d22f28b4ae6a532bea963379c78ba21f

Author: Stefan Dösinger <stefan at codeweavers.com>
Date:   Tue Aug 14 15:26:02 2007 +0200

wined3d: Deal with multithreading in event queries.

---

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

diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 92b0943..8509192 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -1143,15 +1143,16 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateQuery(IWineD3DDevice *iface, WINE
             break;
         }
     case WINED3DQUERYTYPE_EVENT:
-        /* TODO: GL_APPLE_fence */
         if(GL_SUPPORT(APPLE_FENCE)) {
             object->extendedData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WineQueryEventData));
             GL_EXTCALL(glGenFencesAPPLE(1, &((WineQueryEventData *)(object->extendedData))->fenceId));
             checkGLcall("glGenFencesAPPLE");
+            ((WineQueryEventData *)(object->extendedData))->ctx = This->activeContext;
         } else if(GL_SUPPORT(NV_FENCE)) {
             object->extendedData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WineQueryEventData));
             GL_EXTCALL(glGenFencesNV(1, &((WineQueryEventData *)(object->extendedData))->fenceId));
             checkGLcall("glGenFencesNV");
+            ((WineQueryEventData *)(object->extendedData))->ctx = This->activeContext;
         }
         break;
 
diff --git a/dlls/wined3d/query.c b/dlls/wined3d/query.c
index 99390f8..f787c78 100644
--- a/dlls/wined3d/query.c
+++ b/dlls/wined3d/query.c
@@ -167,7 +167,12 @@ static HRESULT  WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa
     case WINED3DQUERYTYPE_EVENT:
     {
         BOOL* data = pData;
-        if(GL_SUPPORT(APPLE_FENCE)) {
+        WineD3DContext *ctx = ((WineQueryEventData *)This->extendedData)->ctx;
+        if(ctx != This->wineD3DDevice->activeContext || ctx->tid != GetCurrentThreadId()) {
+            /* See comment in IWineD3DQuery::Issue, event query codeblock */
+            WARN("Query context not active, reporting GPU idle\n");
+            *data = TRUE;
+        } else if(GL_SUPPORT(APPLE_FENCE)) {
             *data = GL_EXTCALL(glTestFenceAPPLE(((WineQueryEventData *)This->extendedData)->fenceId));
             checkGLcall("glTestFenceAPPLE");
         } else if(GL_SUPPORT(NV_FENCE)) {
@@ -390,7 +395,17 @@ static HRESULT  WINAPI IWineD3DQueryImpl_Issue(IWineD3DQuery* iface,  DWORD dwIs
 
         case WINED3DQUERYTYPE_EVENT: {
             if (dwIssueFlags & WINED3DISSUE_END) {
-                if(GL_SUPPORT(APPLE_FENCE)) {
+                WineD3DContext *ctx = ((WineQueryEventData *)This->extendedData)->ctx;
+                if(ctx != This->wineD3DDevice->activeContext || ctx->tid != GetCurrentThreadId()) {
+                    /* GL fences can be used only from the context that created them,
+                     * so if a different context is active, don't bother setting the query. The penalty
+                     * of a context switch is most likely higher than the gain of a correct query result
+                     *
+                     * If the query is used from a different thread, don't bother creating a multithread
+                     * context - there's no point in doing that as the query would be unusable anyway
+                     */
+                    WARN("Query context not active\n");
+                } else if(GL_SUPPORT(APPLE_FENCE)) {
                     GL_EXTCALL(glSetFenceAPPLE(((WineQueryEventData *)This->extendedData)->fenceId));
                     checkGLcall("glSetFenceAPPLE");
                 } else if (GL_SUPPORT(NV_FENCE)) {
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 73d13cc..84e0480 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1464,6 +1464,7 @@ typedef struct  WineQueryOcclusionData {
 
 typedef struct  WineQueryEventData {
     GLuint  fenceId;
+    WineD3DContext *ctx;
 } WineQueryEventData;
 
 /*****************************************************************************




More information about the wine-cvs mailing list