ULONG CDECL wined3d_query_decref(struct wined3d_query *query) { ULONG refcount = InterlockedDecrement(&query->ref); TRACE("%p decreasing refcount to %u.\n", query, refcount); if (!refcount) { /* Queries are specific to the GL context that created them. Not * deleting the query will obviously leak it, but that's still better * than potentially deleting a different query with the same id in this * context, and (still) leaking the actual query. */ if (query->type == WINED3D_QUERY_TYPE_EVENT) { struct wined3d_event_query *event_query = query->extendedData; if (event_query) wined3d_event_query_destroy(event_query); } else if (query->type == WINED3D_QUERY_TYPE_OCCLUSION) { struct wined3d_occlusion_query *oq = query->extendedData; if (oq->context) context_free_occlusion_query(oq); HeapFree(GetProcessHeap(), 0, query->extendedData); } HeapFree(GetProcessHeap(), 0, query); } return refcount; }
static ULONG WINAPI IWineD3DQueryImpl_Release(IWineD3DQuery *iface) { IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface; ULONG ref; TRACE("(%p) : Releasing from %d\n", This, This->ref); ref = InterlockedDecrement(&This->ref); if (!ref) { /* Queries are specific to the GL context that created them. Not * deleting the query will obviously leak it, but that's still better * than potentially deleting a different query with the same id in this * context, and (still) leaking the actual query. */ if (This->type == WINED3DQUERYTYPE_EVENT) { struct wined3d_event_query *query = This->extendedData; if (query) wined3d_event_query_destroy(query); } else if (This->type == WINED3DQUERYTYPE_OCCLUSION) { struct wined3d_occlusion_query *query = This->extendedData; if (query->context) context_free_occlusion_query(query); HeapFree(GetProcessHeap(), 0, This->extendedData); } HeapFree(GetProcessHeap(), 0, This); } return ref; }
void wined3d_query_destroy(struct wined3d_query *query) { /* Queries are specific to the GL context that created them. Not * deleting the query will obviously leak it, but that's still better * than potentially deleting a different query with the same id in this * context, and (still) leaking the actual query. */ if (query->type == WINED3D_QUERY_TYPE_EVENT) { struct wined3d_event_query *event_query = query->extendedData; if (event_query) wined3d_event_query_destroy(event_query); } else if (query->type == WINED3D_QUERY_TYPE_OCCLUSION) { struct wined3d_occlusion_query *oq = query->extendedData; if (oq->context) context_free_occlusion_query(oq); HeapFree(GetProcessHeap(), 0, query->extendedData); } else if (query->type == WINED3D_QUERY_TYPE_TIMESTAMP) { struct wined3d_timestamp_query *tq = query->extendedData; if (tq->context) context_free_timestamp_query(tq); HeapFree(GetProcessHeap(), 0, query->extendedData); } HeapFree(GetProcessHeap(), 0, query); }
static void wined3d_query_destroy_object(void *object) { struct wined3d_query *query = object; #if defined(STAGING_CSMT) if (!list_empty(&query->poll_list_entry)) list_remove(&query->poll_list_entry); #endif /* STAGING_CSMT */ /* Queries are specific to the GL context that created them. Not * deleting the query will obviously leak it, but that's still better * than potentially deleting a different query with the same id in this * context, and (still) leaking the actual query. */ if (query->type == WINED3D_QUERY_TYPE_EVENT) { wined3d_event_query_destroy(wined3d_event_query_from_query(query)); } else if (query->type == WINED3D_QUERY_TYPE_OCCLUSION) { struct wined3d_occlusion_query *oq = wined3d_occlusion_query_from_query(query); if (oq->context) context_free_occlusion_query(oq); HeapFree(GetProcessHeap(), 0, oq); } else if (query->type == WINED3D_QUERY_TYPE_TIMESTAMP) { struct wined3d_timestamp_query *tq = wined3d_timestamp_query_from_query(query); if (tq->context) context_free_timestamp_query(tq); HeapFree(GetProcessHeap(), 0, tq); } else if (query->type == WINED3D_QUERY_TYPE_TIMESTAMP_DISJOINT || query->type == WINED3D_QUERY_TYPE_TIMESTAMP_FREQ) { HeapFree(GetProcessHeap(), 0, query); } else if (query->type == WINED3D_QUERY_TYPE_SO_STATISTICS) { HeapFree(GetProcessHeap(), 0, query); } else if (query->type == WINED3D_QUERY_TYPE_SO_OVERFLOW) { HeapFree(GetProcessHeap(), 0, query); } else { ERR("Query %p has invalid type %#x.\n", query, query->type); } }
static HRESULT wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DWORD flags) { struct wined3d_device *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 *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 (query->state == QUERY_BUILDING) { if (oq->context->tid != GetCurrentThreadId()) { FIXME("Wrong thread, can't restart query.\n"); context_free_occlusion_query(oq); context = context_acquire(query->device, NULL); context_alloc_occlusion_query(context, oq); } else { context = context_acquire(query->device, oq->context->current_rt); GL_EXTCALL(glEndQueryARB(GL_SAMPLES_PASSED_ARB)); checkGLcall("glEndQuery()"); } } else { if (oq->context) context_free_occlusion_query(oq); context = context_acquire(query->device, NULL); context_alloc_occlusion_query(context, oq); } GL_EXTCALL(glBeginQueryARB(GL_SAMPLES_PASSED_ARB, oq->id)); checkGLcall("glBeginQuery()"); context_release(context); } if (flags & WINED3DISSUE_END) { /* Msdn says _END on a non-building occlusion query returns an error, but * our tests show that it returns OK. But OpenGL doesn't like it, so avoid * generating an error */ if (query->state == QUERY_BUILDING) { if (oq->context->tid != GetCurrentThreadId()) { FIXME("Wrong thread, can't end query.\n"); } else { context = context_acquire(query->device, oq->context->current_rt); GL_EXTCALL(glEndQueryARB(GL_SAMPLES_PASSED_ARB)); checkGLcall("glEndQuery()"); context_release(context); } } } } else { FIXME("%p Occlusion queries not supported.\n", query); } if (flags & WINED3DISSUE_BEGIN) query->state = QUERY_BUILDING; else query->state = QUERY_SIGNALLED; return WINED3D_OK; /* can be WINED3DERR_INVALIDCALL. */ }
static HRESULT WINAPI IWineD3DOcclusionQueryImpl_Issue(IWineD3DQuery* iface, DWORD dwIssueFlags) { IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface; IWineD3DDeviceImpl *device = This->device; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; if (gl_info->supported[ARB_OCCLUSION_QUERY]) { struct wined3d_occlusion_query *query = This->extendedData; struct wined3d_context *context; /* This is allowed according to msdn and our tests. Reset the query and restart */ if (dwIssueFlags & WINED3DISSUE_BEGIN) { if (This->state == QUERY_BUILDING) { if (query->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); } else { context = context_acquire(This->device, query->context->current_rt); ENTER_GL(); GL_EXTCALL(glEndQueryARB(GL_SAMPLES_PASSED_ARB)); checkGLcall("glEndQuery()"); LEAVE_GL(); } } else { if (query->context) context_free_occlusion_query(query); context = context_acquire(This->device, NULL); context_alloc_occlusion_query(context, query); } ENTER_GL(); GL_EXTCALL(glBeginQueryARB(GL_SAMPLES_PASSED_ARB, query->id)); checkGLcall("glBeginQuery()"); LEAVE_GL(); context_release(context); } if (dwIssueFlags & WINED3DISSUE_END) { /* Msdn says _END on a non-building occlusion query returns an error, but * 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->context->tid != GetCurrentThreadId()) { FIXME("Wrong thread, can't end query.\n"); } else { context = context_acquire(This->device, query->context->current_rt); ENTER_GL(); GL_EXTCALL(glEndQueryARB(GL_SAMPLES_PASSED_ARB)); checkGLcall("glEndQuery()"); LEAVE_GL(); context_release(context); } } } } else { FIXME("(%p) : Occlusion queries not supported\n", This); } if(dwIssueFlags & WINED3DISSUE_BEGIN) { This->state = QUERY_BUILDING; } else { This->state = QUERY_SIGNALLED; } return WINED3D_OK; /* can be WINED3DERR_INVALIDCALL. */ }
static BOOL wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DWORD flags) { struct wined3d_device *device = query->device; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; BOOL poll = FALSE; TRACE("query %p, flags %#x.\n", query, flags); if (gl_info->supported[ARB_OCCLUSION_QUERY]) { 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 (oq->started) { if (oq->context->tid != GetCurrentThreadId()) { FIXME("Wrong thread, can't restart query.\n"); context_free_occlusion_query(oq); context = context_acquire(query->device, NULL); context_alloc_occlusion_query(context, oq); } else { context = context_acquire(device, context_get_rt_surface(oq->context)); GL_EXTCALL(glEndQuery(GL_SAMPLES_PASSED)); checkGLcall("glEndQuery()"); } } else { if (oq->context) context_free_occlusion_query(oq); context = context_acquire(query->device, NULL); context_alloc_occlusion_query(context, oq); } GL_EXTCALL(glBeginQuery(GL_SAMPLES_PASSED, oq->id)); checkGLcall("glBeginQuery()"); context_release(context); oq->started = TRUE; } if (flags & WINED3DISSUE_END) { /* Msdn says _END on a non-building occlusion query returns an error, but * our tests show that it returns OK. But OpenGL doesn't like it, so avoid * generating an error */ if (oq->started) { if (oq->context->tid != GetCurrentThreadId()) { FIXME("Wrong thread, can't end query.\n"); } else { context = context_acquire(device, context_get_rt_surface(oq->context)); GL_EXTCALL(glEndQuery(GL_SAMPLES_PASSED)); checkGLcall("glEndQuery()"); context_release(context); poll = TRUE; } } oq->started = FALSE; } } else { FIXME("%p Occlusion queries not supported.\n", query); } return poll; }