diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 9f2b9101fa7..8062896b357 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1143,11 +1143,14 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateQuery(IWineD3DDevice *iface, WINE IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; IWineD3DQueryImpl *object; /*NOTE: impl ref allowed since this is a create function */ HRESULT hr = WINED3DERR_NOTAVAILABLE; + const IWineD3DQueryVtbl *vtable; /* Just a check to see if we support this type of query */ switch(Type) { case WINED3DQUERYTYPE_OCCLUSION: TRACE("(%p) occlusion query\n", This); + /* Use the base Query vtable until we have a occlusion query one */ + vtable = &IWineD3DQuery_Vtbl; if (GL_SUPPORT(ARB_OCCLUSION_QUERY)) hr = WINED3D_OK; else @@ -1161,6 +1164,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateQuery(IWineD3DDevice *iface, WINE */ FIXME("(%p) Event query: Unimplemented, but pretending to be supported\n", This); } + vtable = &IWineD3DEventQuery_Vtbl; hr = WINED3D_OK; break; @@ -1177,6 +1181,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateQuery(IWineD3DDevice *iface, WINE case WINED3DQUERYTYPE_BANDWIDTHTIMINGS: case WINED3DQUERYTYPE_CACHEUTILIZATION: default: + /* Use the base Query vtable until we have a special one for each query */ + vtable = &IWineD3DQuery_Vtbl; FIXME("(%p) Unhandled query type %d\n", This, Type); } if(NULL == ppQuery || hr != WINED3D_OK) { @@ -1184,6 +1190,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateQuery(IWineD3DDevice *iface, WINE } D3DCREATEOBJECTINSTANCE(object, Query) + object->lpVtbl = vtable; object->type = Type; object->state = QUERY_CREATED; /* allocated the 'extended' data based on the type of query requested */ diff --git a/dlls/wined3d/query.c b/dlls/wined3d/query.c index b8b7a9511e3..d69e23d7eda 100644 --- a/dlls/wined3d/query.c +++ b/dlls/wined3d/query.c @@ -158,28 +158,6 @@ static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa } break; - case WINED3DQUERYTYPE_EVENT: - { - BOOL* data = pData; - WineD3DContext *ctx = ((WineQueryEventData *)This->extendedData)->ctx; - if(pData == NULL || dwSize == 0) { - break; - } 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)) { - *data = GL_EXTCALL(glTestFenceNV(((WineQueryEventData *)This->extendedData)->fenceId)); - checkGLcall("glTestFenceNV"); - } else { - WARN("(%p): reporting GPU idle\n", This); - *data = TRUE; - } - } - break; case WINED3DQUERYTYPE_OCCLUSION: { DWORD* data = pData; @@ -329,6 +307,32 @@ static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa return res; /* S_OK if the query data is available*/ } +static HRESULT WINAPI IWineD3DEventQueryImpl_GetData(IWineD3DQuery* iface, void* pData, DWORD dwSize, DWORD dwGetDataFlags) { + IWineD3DQueryImpl *This = (IWineD3DQueryImpl *) iface; + BOOL* data = pData; + WineD3DContext *ctx; + TRACE("(%p) : type D3DQUERY_EVENT, pData %p, dwSize %#x, dwGetDataFlags %#x\n", This, pData, dwSize, dwGetDataFlags); + + ctx = ((WineQueryEventData *)This->extendedData)->ctx; + if(pData == NULL || dwSize == 0) { + return S_OK; + } 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)) { + *data = GL_EXTCALL(glTestFenceNV(((WineQueryEventData *)This->extendedData)->fenceId)); + checkGLcall("glTestFenceNV"); + } else { + WARN("(%p): reporting GPU idle\n", This); + *data = TRUE; + } + + return S_OK; +} static DWORD WINAPI IWineD3DQueryImpl_GetDataSize(IWineD3DQuery* iface){ IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface; @@ -384,6 +388,11 @@ static DWORD WINAPI IWineD3DQueryImpl_GetDataSize(IWineD3DQuery* iface){ return dataSize; } +static DWORD WINAPI IWineD3DEventQueryImpl_GetDataSize(IWineD3DQuery* iface){ + TRACE("(%p) : type D3DQUERY_EVENT\n", iface); + + return sizeof(BOOL); +} static WINED3DQUERYTYPE WINAPI IWineD3DQueryImpl_GetType(IWineD3DQuery* iface){ IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface; @@ -391,6 +400,42 @@ static WINED3DQUERYTYPE WINAPI IWineD3DQueryImpl_GetType(IWineD3DQuery* iface){ } +static HRESULT WINAPI IWineD3DEventQueryImpl_Issue(IWineD3DQuery* iface, DWORD dwIssueFlags) { + IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface; + + TRACE("(%p) : dwIssueFlags %#x, type D3DQUERY_EVENT\n", This, dwIssueFlags); + if (dwIssueFlags & WINED3DISSUE_END) { + 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)) { + GL_EXTCALL(glSetFenceNV(((WineQueryEventData *)This->extendedData)->fenceId, GL_ALL_COMPLETED_NV)); + checkGLcall("glSetFenceNV"); + } + } else if(dwIssueFlags & WINED3DISSUE_BEGIN) { + /* Started implicitly at device creation */ + ERR("Event query issued with START flag - what to do?\n"); + } + + if(dwIssueFlags & WINED3DISSUE_BEGIN) { + This->state = QUERY_BUILDING; + } else { + This->state = QUERY_SIGNALLED; + } + + return WINED3D_OK; +} + static HRESULT WINAPI IWineD3DQueryImpl_Issue(IWineD3DQuery* iface, DWORD dwIssueFlags){ IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface; @@ -430,31 +475,6 @@ static HRESULT WINAPI IWineD3DQueryImpl_Issue(IWineD3DQuery* iface, DWORD dwIs } break; - case WINED3DQUERYTYPE_EVENT: { - if (dwIssueFlags & WINED3DISSUE_END) { - 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)) { - GL_EXTCALL(glSetFenceNV(((WineQueryEventData *)This->extendedData)->fenceId, GL_ALL_COMPLETED_NV)); - checkGLcall("glSetFenceNV"); - } - } 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); @@ -489,3 +509,18 @@ const IWineD3DQueryVtbl IWineD3DQuery_Vtbl = IWineD3DQueryImpl_GetType, IWineD3DQueryImpl_Issue }; + +const IWineD3DQueryVtbl IWineD3DEventQuery_Vtbl = +{ + /*** IUnknown methods ***/ + IWineD3DQueryImpl_QueryInterface, + IWineD3DQueryImpl_AddRef, + IWineD3DQueryImpl_Release, + /*** IWineD3Dquery methods ***/ + IWineD3DQueryImpl_GetParent, + IWineD3DQueryImpl_GetDevice, + IWineD3DEventQueryImpl_GetData, + IWineD3DEventQueryImpl_GetDataSize, + IWineD3DQueryImpl_GetType, + IWineD3DEventQueryImpl_Issue +}; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 1071871dead..f19ad4be414 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1571,6 +1571,7 @@ typedef struct IWineD3DQueryImpl } IWineD3DQueryImpl; extern const IWineD3DQueryVtbl IWineD3DQuery_Vtbl; +extern const IWineD3DQueryVtbl IWineD3DEventQuery_Vtbl; /* Datastructures for IWineD3DQueryImpl.extendedData */ typedef struct WineQueryOcclusionData {