Module: wine Branch: master Commit: a99907d1d22f28b4ae6a532bea963379c78ba21f URL: http://source.winehq.org/git/wine.git/?a=commit;h=a99907d1d22f28b4ae6a532bea...
Author: Stefan Dösinger stefan@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;
/*****************************************************************************