From 1448ee75e22daff989aa5721ad3ea6262393775d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20D=C3=B6singer?= Date: Mon, 25 Jan 2010 21:44:28 +0100 Subject: [PATCH 03/18] WineD3D: Add an internal event query finish function This matches glFinishFenceAPPLE/glFinishFenceNV, just on top of the wined3d event query interface. --- dlls/wined3d/query.c | 70 ++++++++++++++++++++++++++++++++++++++++ dlls/wined3d/wined3d_private.h | 2 + 2 files changed, 72 insertions(+), 0 deletions(-) diff --git a/dlls/wined3d/query.c b/dlls/wined3d/query.c index 85d5311..e52cab2 100644 --- a/dlls/wined3d/query.c +++ b/dlls/wined3d/query.c @@ -255,6 +255,76 @@ static HRESULT WINAPI IWineD3DEventQueryImpl_GetData(IWineD3DQuery* iface, void return S_OK; } +HRESULT wined3d_event_query_finish(IWineD3DQuery* iface) { + IWineD3DQueryImpl *This = (IWineD3DQueryImpl *) iface; + struct wined3d_context *context; + struct wined3d_event_query *query = This->extendedData; + const struct wined3d_gl_info *gl_info = &This->device->adapter->gl_info; + HRESULT hr = WINED3D_OK; + + TRACE("(%p) : type D3DQUERY_EVENT\n", This); + + if (!query->context) + { + TRACE("Query not started\n"); + return WINED3D_OK; + } + + if (query->context->tid != GetCurrentThreadId() && !gl_info->supported[ARB_SYNC]) + { + /* A glFinish does not reliably wait for draws in other contexts. The caller has + * to find its own way to cope with the thread switch + */ + WARN("Wrong thread, returning WINED3DERR_INVALIDCALL\n"); + return WINED3DERR_INVALIDCALL; + } + + if (!gl_info->supported[APPLE_FENCE] && !gl_info->supported[NV_FENCE] && gl_info->supported[ARB_SYNC]) + { + /* Since this is an internal call the caller should know that event Query support is faked */ + FIXME("(%p): Event query not supported, calling glFinish\n", This); + wglFinish(); + return WINED3D_OK; + } + + context = context_acquire(This->device, query->context->current_rt, CTXUSAGE_RESOURCELOAD); + + ENTER_GL(); + if (gl_info->supported[ARB_SYNC]) + { + GLenum ret = GL_EXTCALL(glClientWaitSync(query->object.sync, 0, ~0U)); + checkGLcall("glClientWaitSync"); + + switch (ret) + { + case GL_ALREADY_SIGNALED: + case GL_CONDITION_SATISFIED: + break; + + /* We don't expect a timeout for a ~584 year wait */ + case GL_TIMEOUT_EXPIRED: + case GL_WAIT_FAILED: + default: + ERR("glClientWaitSync returned %#x.\n", ret); + hr = WINED3DERR_INVALIDCALL; + } + } + else if (context->gl_info->supported[APPLE_FENCE]) + { + GL_EXTCALL(glFinishFenceAPPLE(query->object.id)); + checkGLcall("glFinishFenceAPPLE"); + } + else if (context->gl_info->supported[NV_FENCE]) + { + GL_EXTCALL(glFinishFenceNV(query->object.id)); + checkGLcall("glFinishFenceNV"); + } + LEAVE_GL(); + + context_release(context); + return hr; +} + static DWORD WINAPI IWineD3DEventQueryImpl_GetDataSize(IWineD3DQuery* iface){ TRACE("(%p) : type D3DQUERY_EVENT\n", iface); diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 164cc6b..0ea4bb9 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2357,6 +2357,8 @@ typedef struct IWineD3DQueryImpl HRESULT query_init(IWineD3DQueryImpl *query, IWineD3DDeviceImpl *device, WINED3DQUERYTYPE type, IUnknown *parent) DECLSPEC_HIDDEN; +HRESULT wined3d_event_query_finish(IWineD3DQuery* iface) DECLSPEC_HIDDEN; + /* IWineD3DBuffer */ /* TODO: Add tests and support for FLOAT16_4 POSITIONT, D3DCOLOR position, other -- 1.6.4.4