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