diff --git a/dlls/wined3d/query.c b/dlls/wined3d/query.c index e2e2fca5cbc..ca7f48a7891 100644 --- a/dlls/wined3d/query.c +++ b/dlls/wined3d/query.c @@ -284,12 +284,40 @@ static ULONG WINAPI IWineD3DQueryImpl_Release(IWineD3DQuery *iface) { return ref; } -static HRESULT WINAPI IWineD3DOcclusionQueryImpl_GetData(IWineD3DQuery *iface, +static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery *iface, + void *data, DWORD data_size, DWORD flags) +{ + struct IWineD3DQueryImpl *query = (struct IWineD3DQueryImpl *)iface; + + TRACE("iface %p, data %p, data_size %u, flags %#x.\n", + iface, data, data_size, flags); + + return query->query_ops->query_get_data(query, data, data_size, flags); +} + +static DWORD WINAPI IWineD3DQueryImpl_GetDataSize(IWineD3DQuery *iface) +{ + struct IWineD3DQueryImpl *query = (struct IWineD3DQueryImpl *)iface; + + TRACE("iface %p.\n", iface); + + return query->data_size; +} + +static HRESULT WINAPI IWineD3DQueryImpl_Issue(IWineD3DQuery *iface, DWORD flags) +{ + struct IWineD3DQueryImpl *query = (struct IWineD3DQueryImpl *)iface; + + TRACE("iface %p, flags %#x.\n", iface, flags); + + return query->query_ops->query_issue(query, flags); +} + +static HRESULT wined3d_occlusion_query_ops_get_data(struct IWineD3DQueryImpl *query, void *pData, DWORD dwSize, DWORD flags) { - IWineD3DQueryImpl *This = (IWineD3DQueryImpl *) iface; - struct wined3d_occlusion_query *query = This->extendedData; - IWineD3DDeviceImpl *device = This->device; + struct wined3d_occlusion_query *oq = query->extendedData; + IWineD3DDeviceImpl *device = query->device; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; struct wined3d_context *context; DWORD* data = pData; @@ -297,11 +325,12 @@ static HRESULT WINAPI IWineD3DOcclusionQueryImpl_GetData(IWineD3DQuery *iface, GLuint samples; HRESULT res; - TRACE("(%p) : type D3DQUERY_OCCLUSION, pData %p, dwSize %#x, flags %#x.\n", This, pData, dwSize, flags); + TRACE("(%p) : type D3DQUERY_OCCLUSION, pData %p, dwSize %#x, flags %#x.\n", query, pData, dwSize, flags); - if (!query->context) This->state = QUERY_CREATED; + if (!oq->context) + query->state = QUERY_CREATED; - if (This->state == QUERY_CREATED) + if (query->state == QUERY_CREATED) { /* D3D allows GetData on a new query, OpenGL doesn't. So just invent the data ourselves */ TRACE("Query wasn't yet started, returning S_OK\n"); @@ -309,7 +338,7 @@ static HRESULT WINAPI IWineD3DOcclusionQueryImpl_GetData(IWineD3DQuery *iface, return S_OK; } - if (This->state == QUERY_BUILDING) + if (query->state == QUERY_BUILDING) { /* Msdn says this returns an error, but our tests show that S_FALSE is returned */ TRACE("Query is building, returning S_FALSE\n"); @@ -318,33 +347,33 @@ static HRESULT WINAPI IWineD3DOcclusionQueryImpl_GetData(IWineD3DQuery *iface, if (!gl_info->supported[ARB_OCCLUSION_QUERY]) { - WARN("(%p) : Occlusion queries not supported. Returning 1.\n", This); + WARN("%p Occlusion queries not supported. Returning 1.\n", query); *data = 1; return S_OK; } - if (query->context->tid != GetCurrentThreadId()) + if (oq->context->tid != GetCurrentThreadId()) { - FIXME("%p Wrong thread, returning 1.\n", This); + FIXME("%p Wrong thread, returning 1.\n", query); *data = 1; return S_OK; } - context = context_acquire(This->device, query->context->current_rt); + context = context_acquire(query->device, oq->context->current_rt); ENTER_GL(); - GL_EXTCALL(glGetQueryObjectuivARB(query->id, GL_QUERY_RESULT_AVAILABLE_ARB, &available)); + GL_EXTCALL(glGetQueryObjectuivARB(oq->id, GL_QUERY_RESULT_AVAILABLE_ARB, &available)); checkGLcall("glGetQueryObjectuivARB(GL_QUERY_RESULT_AVAILABLE)"); - TRACE("(%p) : available %d.\n", This, available); + TRACE("available %#x.\n", available); if (available) { if (data) { - GL_EXTCALL(glGetQueryObjectuivARB(query->id, GL_QUERY_RESULT_ARB, &samples)); + GL_EXTCALL(glGetQueryObjectuivARB(oq->id, GL_QUERY_RESULT_ARB, &samples)); checkGLcall("glGetQueryObjectuivARB(GL_QUERY_RESULT)"); - TRACE("(%p) : Returning %d samples.\n", This, samples); + TRACE("Returning %d samples.\n", samples); *data = samples; } res = S_OK; @@ -361,25 +390,24 @@ static HRESULT WINAPI IWineD3DOcclusionQueryImpl_GetData(IWineD3DQuery *iface, return res; } -static HRESULT WINAPI IWineD3DEventQueryImpl_GetData(IWineD3DQuery *iface, +static HRESULT wined3d_event_query_ops_get_data(IWineD3DQueryImpl *query, void *pData, DWORD dwSize, DWORD flags) { - IWineD3DQueryImpl *This = (IWineD3DQueryImpl *) iface; - struct wined3d_event_query *query = This->extendedData; + struct wined3d_event_query *event_query = query->extendedData; BOOL *data = pData; enum wined3d_event_query_result ret; - TRACE("(%p) : type D3DQUERY_EVENT, pData %p, dwSize %#x, flags %#x.\n", This, pData, dwSize, flags); + TRACE("query %p, pData %p, dwSize %#x, flags %#x.\n", query, pData, dwSize, flags); if (!pData || !dwSize) return S_OK; - if (!query) + if (!event_query) { - WARN("(%p): Event query not supported by GL, reporting GPU idle\n", This); + WARN("Event query not supported by GL, reporting GPU idle.\n"); *data = TRUE; return S_OK; } - ret = wined3d_event_query_test(query, This->device); + ret = wined3d_event_query_test(event_query, query->device); switch(ret) { case WINED3D_EVENT_QUERY_OK: @@ -392,7 +420,7 @@ static HRESULT WINAPI IWineD3DEventQueryImpl_GetData(IWineD3DQuery *iface, break; case WINED3D_EVENT_QUERY_WRONG_THREAD: - FIXME("(%p) Wrong thread, reporting GPU idle.\n", This); + FIXME("(%p) Wrong thread, reporting GPU idle.\n", query); *data = TRUE; break; @@ -404,36 +432,24 @@ static HRESULT WINAPI IWineD3DEventQueryImpl_GetData(IWineD3DQuery *iface, return S_OK; } -static DWORD WINAPI IWineD3DEventQueryImpl_GetDataSize(IWineD3DQuery* iface){ - TRACE("(%p) : type D3DQUERY_EVENT\n", iface); - - return sizeof(BOOL); -} - -static DWORD WINAPI IWineD3DOcclusionQueryImpl_GetDataSize(IWineD3DQuery* iface){ - TRACE("(%p) : type D3DQUERY_OCCLUSION\n", iface); - - return sizeof(DWORD); -} - static WINED3DQUERYTYPE WINAPI IWineD3DQueryImpl_GetType(IWineD3DQuery* iface){ IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface; return This->type; } -static HRESULT WINAPI IWineD3DEventQueryImpl_Issue(IWineD3DQuery* iface, DWORD flags) +static HRESULT wined3d_event_query_ops_issue(struct IWineD3DQueryImpl *query, DWORD flags) { - IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface; + TRACE("query %p, flags %#x.\n", query, flags); - TRACE("(%p) : flags %#x, type D3DQUERY_EVENT\n", This, flags); + TRACE("(%p) : flags %#x, type D3DQUERY_EVENT\n", query, flags); if (flags & WINED3DISSUE_END) { - struct wined3d_event_query *query = This->extendedData; + struct wined3d_event_query *event_query = query->extendedData; /* Faked event query support */ - if (!query) return WINED3D_OK; + if (!event_query) return WINED3D_OK; - wined3d_event_query_issue(query, This->device); + wined3d_event_query_issue(event_query, query->device); } else if (flags & WINED3DISSUE_BEGIN) { @@ -442,40 +458,41 @@ static HRESULT WINAPI IWineD3DEventQueryImpl_Issue(IWineD3DQuery* iface, DWORD f } if (flags & WINED3DISSUE_BEGIN) - This->state = QUERY_BUILDING; + query->state = QUERY_BUILDING; else - This->state = QUERY_SIGNALLED; + query->state = QUERY_SIGNALLED; return WINED3D_OK; } -static HRESULT WINAPI IWineD3DOcclusionQueryImpl_Issue(IWineD3DQuery *iface, DWORD flags) +static HRESULT wined3d_occlusion_query_ops_issue(struct IWineD3DQueryImpl *query, DWORD flags) { - IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface; - IWineD3DDeviceImpl *device = This->device; + IWineD3DDeviceImpl *device = query->device; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + TRACE("query %p, flags %#x.\n", query, flags); + if (gl_info->supported[ARB_OCCLUSION_QUERY]) { - struct wined3d_occlusion_query *query = This->extendedData; + struct wined3d_occlusion_query *oq = query->extendedData; struct wined3d_context *context; /* This is allowed according to msdn and our tests. Reset the query and restart */ if (flags & WINED3DISSUE_BEGIN) { - if (This->state == QUERY_BUILDING) + if (query->state == QUERY_BUILDING) { - if (query->context->tid != GetCurrentThreadId()) + if (oq->context->tid != GetCurrentThreadId()) { FIXME("Wrong thread, can't restart query.\n"); - context_free_occlusion_query(query); - context = context_acquire(This->device, NULL); - context_alloc_occlusion_query(context, query); + context_free_occlusion_query(oq); + context = context_acquire(query->device, NULL); + context_alloc_occlusion_query(context, oq); } else { - context = context_acquire(This->device, query->context->current_rt); + context = context_acquire(query->device, oq->context->current_rt); ENTER_GL(); GL_EXTCALL(glEndQueryARB(GL_SAMPLES_PASSED_ARB)); @@ -485,13 +502,13 @@ static HRESULT WINAPI IWineD3DOcclusionQueryImpl_Issue(IWineD3DQuery *iface, DWO } else { - if (query->context) context_free_occlusion_query(query); - context = context_acquire(This->device, NULL); - context_alloc_occlusion_query(context, query); + if (oq->context) context_free_occlusion_query(oq); + context = context_acquire(query->device, NULL); + context_alloc_occlusion_query(context, oq); } ENTER_GL(); - GL_EXTCALL(glBeginQueryARB(GL_SAMPLES_PASSED_ARB, query->id)); + GL_EXTCALL(glBeginQueryARB(GL_SAMPLES_PASSED_ARB, oq->id)); checkGLcall("glBeginQuery()"); LEAVE_GL(); @@ -503,15 +520,15 @@ static HRESULT WINAPI IWineD3DOcclusionQueryImpl_Issue(IWineD3DQuery *iface, DWO * our tests show that it returns OK. But OpenGL doesn't like it, so avoid * generating an error */ - if (This->state == QUERY_BUILDING) + if (query->state == QUERY_BUILDING) { - if (query->context->tid != GetCurrentThreadId()) + if (oq->context->tid != GetCurrentThreadId()) { FIXME("Wrong thread, can't end query.\n"); } else { - context = context_acquire(This->device, query->context->current_rt); + context = context_acquire(query->device, oq->context->current_rt); ENTER_GL(); GL_EXTCALL(glEndQueryARB(GL_SAMPLES_PASSED_ARB)); @@ -522,42 +539,43 @@ static HRESULT WINAPI IWineD3DOcclusionQueryImpl_Issue(IWineD3DQuery *iface, DWO } } } - } else { - FIXME("(%p) : Occlusion queries not supported\n", This); + } + else + { + FIXME("%p Occlusion queries not supported.\n", query); } if (flags & WINED3DISSUE_BEGIN) - This->state = QUERY_BUILDING; + query->state = QUERY_BUILDING; else - This->state = QUERY_SIGNALLED; + query->state = QUERY_SIGNALLED; return WINED3D_OK; /* can be WINED3DERR_INVALIDCALL. */ } -static const IWineD3DQueryVtbl IWineD3DEventQuery_Vtbl = +static const struct wined3d_query_ops event_query_ops = { - /*** IUnknown methods ***/ - IWineD3DQueryImpl_QueryInterface, - IWineD3DQueryImpl_AddRef, - IWineD3DQueryImpl_Release, - /*** IWineD3Dquery methods ***/ - IWineD3DEventQueryImpl_GetData, - IWineD3DEventQueryImpl_GetDataSize, - IWineD3DQueryImpl_GetType, - IWineD3DEventQueryImpl_Issue + wined3d_event_query_ops_get_data, + wined3d_event_query_ops_issue, }; -static const IWineD3DQueryVtbl IWineD3DOcclusionQuery_Vtbl = +static const struct wined3d_query_ops occlusion_query_ops = +{ + wined3d_occlusion_query_ops_get_data, + wined3d_occlusion_query_ops_issue, +}; + +static const struct IWineD3DQueryVtbl IWineD3DQuery_Vtbl = { /*** IUnknown methods ***/ IWineD3DQueryImpl_QueryInterface, IWineD3DQueryImpl_AddRef, IWineD3DQueryImpl_Release, /*** IWineD3Dquery methods ***/ - IWineD3DOcclusionQueryImpl_GetData, - IWineD3DOcclusionQueryImpl_GetDataSize, + IWineD3DQueryImpl_GetData, + IWineD3DQueryImpl_GetDataSize, IWineD3DQueryImpl_GetType, - IWineD3DOcclusionQueryImpl_Issue + IWineD3DQueryImpl_Issue, }; HRESULT query_init(IWineD3DQueryImpl *query, IWineD3DDeviceImpl *device, WINED3DQUERYTYPE type) @@ -573,7 +591,8 @@ HRESULT query_init(IWineD3DQueryImpl *query, IWineD3DDeviceImpl *device, WINED3D WARN("Unsupported in local OpenGL implementation: ARB_OCCLUSION_QUERY.\n"); return WINED3DERR_NOTAVAILABLE; } - query->lpVtbl = &IWineD3DOcclusionQuery_Vtbl; + query->query_ops = &occlusion_query_ops; + query->data_size = sizeof(DWORD); query->extendedData = HeapAlloc(GetProcessHeap(), 0, sizeof(struct wined3d_occlusion_query)); if (!query->extendedData) { @@ -593,7 +612,8 @@ HRESULT query_init(IWineD3DQueryImpl *query, IWineD3DDeviceImpl *device, WINED3D * lowering performance. */ FIXME("Event query: Unimplemented, but pretending to be supported.\n"); } - query->lpVtbl = &IWineD3DEventQuery_Vtbl; + query->query_ops = &event_query_ops; + query->data_size = sizeof(BOOL); query->extendedData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct wined3d_event_query)); if (!query->extendedData) { @@ -619,6 +639,7 @@ HRESULT query_init(IWineD3DQueryImpl *query, IWineD3DDeviceImpl *device, WINED3D return WINED3DERR_NOTAVAILABLE; } + query->lpVtbl = &IWineD3DQuery_Vtbl; query->type = type; query->state = QUERY_CREATED; query->device = device; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 34fdc3fe024..33d830dfbad 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2467,6 +2467,15 @@ enum query_state { QUERY_SIGNALLED, QUERY_BUILDING }; + +struct IWineD3DQueryImpl; + +struct wined3d_query_ops +{ + HRESULT (*query_get_data)(struct IWineD3DQueryImpl *query, void *data, DWORD data_size, DWORD flags); + HRESULT (*query_issue)(struct IWineD3DQueryImpl *query, DWORD flags); +}; + /***************************************************************************** * IWineD3DQueryImpl implementation structure (extends IUnknown) */ @@ -2475,12 +2484,13 @@ typedef struct IWineD3DQueryImpl const IWineD3DQueryVtbl *lpVtbl; LONG ref; /* Note: Ref counting not required */ + const struct wined3d_query_ops *query_ops; IWineD3DDeviceImpl *device; /* IWineD3DQuery fields */ enum query_state state; WINED3DQUERYTYPE type; - /* TODO: Think about using a IUnknown instead of a void* */ + DWORD data_size; void *extendedData; } IWineD3DQueryImpl;