wined3d: Add an ARB_sync implementation of event queries.
This commit is contained in:
parent
c698171fa3
commit
96b150929b
|
@ -532,32 +532,38 @@ void context_alloc_event_query(struct wined3d_context *context, struct wined3d_e
|
||||||
|
|
||||||
if (context->free_event_query_count)
|
if (context->free_event_query_count)
|
||||||
{
|
{
|
||||||
query->id = context->free_event_queries[--context->free_event_query_count];
|
query->object = context->free_event_queries[--context->free_event_query_count];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (gl_info->supported[APPLE_FENCE])
|
if (gl_info->supported[ARB_SYNC])
|
||||||
|
{
|
||||||
|
/* Using ARB_sync, not much to do here. */
|
||||||
|
query->object.sync = NULL;
|
||||||
|
TRACE("Allocated event query %p in context %p.\n", query->object.sync, context);
|
||||||
|
}
|
||||||
|
else if (gl_info->supported[APPLE_FENCE])
|
||||||
{
|
{
|
||||||
ENTER_GL();
|
ENTER_GL();
|
||||||
GL_EXTCALL(glGenFencesAPPLE(1, &query->id));
|
GL_EXTCALL(glGenFencesAPPLE(1, &query->object.id));
|
||||||
checkGLcall("glGenFencesAPPLE");
|
checkGLcall("glGenFencesAPPLE");
|
||||||
LEAVE_GL();
|
LEAVE_GL();
|
||||||
|
|
||||||
TRACE("Allocated event query %u in context %p.\n", query->id, context);
|
TRACE("Allocated event query %u in context %p.\n", query->object.id, context);
|
||||||
}
|
}
|
||||||
else if(gl_info->supported[NV_FENCE])
|
else if(gl_info->supported[NV_FENCE])
|
||||||
{
|
{
|
||||||
ENTER_GL();
|
ENTER_GL();
|
||||||
GL_EXTCALL(glGenFencesNV(1, &query->id));
|
GL_EXTCALL(glGenFencesNV(1, &query->object.id));
|
||||||
checkGLcall("glGenFencesNV");
|
checkGLcall("glGenFencesNV");
|
||||||
LEAVE_GL();
|
LEAVE_GL();
|
||||||
|
|
||||||
TRACE("Allocated event query %u in context %p.\n", query->id, context);
|
TRACE("Allocated event query %u in context %p.\n", query->object.id, context);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
WARN("Event queries not supported, not allocating query id.\n");
|
WARN("Event queries not supported, not allocating query id.\n");
|
||||||
query->id = 0;
|
query->object.id = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -575,12 +581,12 @@ void context_free_event_query(struct wined3d_event_query *query)
|
||||||
if (context->free_event_query_count >= context->free_event_query_size - 1)
|
if (context->free_event_query_count >= context->free_event_query_size - 1)
|
||||||
{
|
{
|
||||||
UINT new_size = context->free_event_query_size << 1;
|
UINT new_size = context->free_event_query_size << 1;
|
||||||
GLuint *new_data = HeapReAlloc(GetProcessHeap(), 0, context->free_event_queries,
|
union wined3d_gl_query_object *new_data = HeapReAlloc(GetProcessHeap(), 0, context->free_event_queries,
|
||||||
new_size * sizeof(*context->free_event_queries));
|
new_size * sizeof(*context->free_event_queries));
|
||||||
|
|
||||||
if (!new_data)
|
if (!new_data)
|
||||||
{
|
{
|
||||||
ERR("Failed to grow free list, leaking query %u in context %p.\n", query->id, context);
|
ERR("Failed to grow free list, leaking query %u in context %p.\n", query->object.id, context);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -588,7 +594,7 @@ void context_free_event_query(struct wined3d_event_query *query)
|
||||||
context->free_event_queries = new_data;
|
context->free_event_queries = new_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
context->free_event_queries[context->free_event_query_count++] = query->id;
|
context->free_event_queries[context->free_event_query_count++] = query->object;
|
||||||
}
|
}
|
||||||
|
|
||||||
void context_resource_released(IWineD3DDevice *iface, IWineD3DResource *resource, WINED3DRESOURCETYPE type)
|
void context_resource_released(IWineD3DDevice *iface, IWineD3DResource *resource, WINED3DRESOURCETYPE type)
|
||||||
|
@ -661,6 +667,7 @@ static void context_destroy_gl_resources(struct wined3d_context *context)
|
||||||
struct fbo_entry *entry, *entry2;
|
struct fbo_entry *entry, *entry2;
|
||||||
HGLRC restore_ctx;
|
HGLRC restore_ctx;
|
||||||
HDC restore_dc;
|
HDC restore_dc;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
restore_ctx = pwglGetCurrentContext();
|
restore_ctx = pwglGetCurrentContext();
|
||||||
restore_dc = pwglGetCurrentDC();
|
restore_dc = pwglGetCurrentDC();
|
||||||
|
@ -682,8 +689,12 @@ static void context_destroy_gl_resources(struct wined3d_context *context)
|
||||||
{
|
{
|
||||||
if (context->valid)
|
if (context->valid)
|
||||||
{
|
{
|
||||||
if (gl_info->supported[APPLE_FENCE]) GL_EXTCALL(glDeleteFencesAPPLE(1, &event_query->id));
|
if (gl_info->supported[ARB_SYNC])
|
||||||
else if (gl_info->supported[NV_FENCE]) GL_EXTCALL(glDeleteFencesNV(1, &event_query->id));
|
{
|
||||||
|
if (event_query->object.sync) GL_EXTCALL(glDeleteSync(event_query->object.sync));
|
||||||
|
}
|
||||||
|
else if (gl_info->supported[APPLE_FENCE]) GL_EXTCALL(glDeleteFencesAPPLE(1, &event_query->object.id));
|
||||||
|
else if (gl_info->supported[NV_FENCE]) GL_EXTCALL(glDeleteFencesNV(1, &event_query->object.id));
|
||||||
}
|
}
|
||||||
event_query->context = NULL;
|
event_query->context = NULL;
|
||||||
}
|
}
|
||||||
|
@ -720,10 +731,24 @@ static void context_destroy_gl_resources(struct wined3d_context *context)
|
||||||
if (gl_info->supported[ARB_OCCLUSION_QUERY])
|
if (gl_info->supported[ARB_OCCLUSION_QUERY])
|
||||||
GL_EXTCALL(glDeleteQueriesARB(context->free_occlusion_query_count, context->free_occlusion_queries));
|
GL_EXTCALL(glDeleteQueriesARB(context->free_occlusion_query_count, context->free_occlusion_queries));
|
||||||
|
|
||||||
if (gl_info->supported[APPLE_FENCE])
|
if (gl_info->supported[ARB_SYNC])
|
||||||
GL_EXTCALL(glDeleteFencesAPPLE(context->free_event_query_count, context->free_event_queries));
|
{
|
||||||
|
if (event_query->object.sync) GL_EXTCALL(glDeleteSync(event_query->object.sync));
|
||||||
|
}
|
||||||
|
else if (gl_info->supported[APPLE_FENCE])
|
||||||
|
{
|
||||||
|
for (i = 0; i < context->free_event_query_count; ++i)
|
||||||
|
{
|
||||||
|
GL_EXTCALL(glDeleteFencesAPPLE(1, &context->free_event_queries[i].id));
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (gl_info->supported[NV_FENCE])
|
else if (gl_info->supported[NV_FENCE])
|
||||||
GL_EXTCALL(glDeleteFencesNV(context->free_event_query_count, context->free_event_queries));
|
{
|
||||||
|
for (i = 0; i < context->free_event_query_count; ++i)
|
||||||
|
{
|
||||||
|
GL_EXTCALL(glDeleteFencesNV(1, &context->free_event_queries[i].id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
checkGLcall("context cleanup");
|
checkGLcall("context cleanup");
|
||||||
}
|
}
|
||||||
|
|
|
@ -195,7 +195,7 @@ static HRESULT WINAPI IWineD3DEventQueryImpl_GetData(IWineD3DQuery* iface, void
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (query->context->tid != GetCurrentThreadId())
|
if (!query->context->gl_info->supported[ARB_SYNC] && query->context->tid != GetCurrentThreadId())
|
||||||
{
|
{
|
||||||
/* See comment in IWineD3DQuery::Issue, event query codeblock */
|
/* See comment in IWineD3DQuery::Issue, event query codeblock */
|
||||||
FIXME("Wrong thread, reporting GPU idle.\n");
|
FIXME("Wrong thread, reporting GPU idle.\n");
|
||||||
|
@ -209,14 +209,37 @@ static HRESULT WINAPI IWineD3DEventQueryImpl_GetData(IWineD3DQuery* iface, void
|
||||||
|
|
||||||
ENTER_GL();
|
ENTER_GL();
|
||||||
|
|
||||||
if (gl_info->supported[APPLE_FENCE])
|
if (gl_info->supported[ARB_SYNC])
|
||||||
{
|
{
|
||||||
*data = GL_EXTCALL(glTestFenceAPPLE(query->id));
|
GLenum ret = GL_EXTCALL(glClientWaitSync(query->object.sync, 0, 0));
|
||||||
|
checkGLcall("glClientWaitSync");
|
||||||
|
|
||||||
|
switch (ret)
|
||||||
|
{
|
||||||
|
case GL_ALREADY_SIGNALED:
|
||||||
|
case GL_CONDITION_SATISFIED:
|
||||||
|
*data = TRUE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GL_TIMEOUT_EXPIRED:
|
||||||
|
*data = FALSE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GL_WAIT_FAILED:
|
||||||
|
default:
|
||||||
|
ERR("glClientWaitSync returned %#x.\n", ret);
|
||||||
|
*data = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (gl_info->supported[APPLE_FENCE])
|
||||||
|
{
|
||||||
|
*data = GL_EXTCALL(glTestFenceAPPLE(query->object.id));
|
||||||
checkGLcall("glTestFenceAPPLE");
|
checkGLcall("glTestFenceAPPLE");
|
||||||
}
|
}
|
||||||
else if (gl_info->supported[NV_FENCE])
|
else if (gl_info->supported[NV_FENCE])
|
||||||
{
|
{
|
||||||
*data = GL_EXTCALL(glTestFenceNV(query->id));
|
*data = GL_EXTCALL(glTestFenceNV(query->object.id));
|
||||||
checkGLcall("glTestFenceNV");
|
checkGLcall("glTestFenceNV");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -262,7 +285,7 @@ static HRESULT WINAPI IWineD3DEventQueryImpl_Issue(IWineD3DQuery* iface, DWORD
|
||||||
|
|
||||||
if (query->context)
|
if (query->context)
|
||||||
{
|
{
|
||||||
if (query->context->tid != GetCurrentThreadId())
|
if (!query->context->gl_info->supported[ARB_SYNC] && query->context->tid != GetCurrentThreadId())
|
||||||
{
|
{
|
||||||
context_free_event_query(query);
|
context_free_event_query(query);
|
||||||
context = context_acquire(This->device, NULL, CTXUSAGE_RESOURCELOAD);
|
context = context_acquire(This->device, NULL, CTXUSAGE_RESOURCELOAD);
|
||||||
|
@ -283,14 +306,21 @@ static HRESULT WINAPI IWineD3DEventQueryImpl_Issue(IWineD3DQuery* iface, DWORD
|
||||||
|
|
||||||
ENTER_GL();
|
ENTER_GL();
|
||||||
|
|
||||||
if (gl_info->supported[APPLE_FENCE])
|
if (gl_info->supported[ARB_SYNC])
|
||||||
{
|
{
|
||||||
GL_EXTCALL(glSetFenceAPPLE(query->id));
|
if (query->object.sync) GL_EXTCALL(glDeleteSync(query->object.sync));
|
||||||
|
checkGLcall("glDeleteSync");
|
||||||
|
query->object.sync = GL_EXTCALL(glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0));
|
||||||
|
checkGLcall("glFenceSync");
|
||||||
|
}
|
||||||
|
else if (gl_info->supported[APPLE_FENCE])
|
||||||
|
{
|
||||||
|
GL_EXTCALL(glSetFenceAPPLE(query->object.id));
|
||||||
checkGLcall("glSetFenceAPPLE");
|
checkGLcall("glSetFenceAPPLE");
|
||||||
}
|
}
|
||||||
else if (gl_info->supported[NV_FENCE])
|
else if (gl_info->supported[NV_FENCE])
|
||||||
{
|
{
|
||||||
GL_EXTCALL(glSetFenceNV(query->id, GL_ALL_COMPLETED_NV));
|
GL_EXTCALL(glSetFenceNV(query->object.id, GL_ALL_COMPLETED_NV));
|
||||||
checkGLcall("glSetFenceNV");
|
checkGLcall("glSetFenceNV");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -450,7 +480,8 @@ HRESULT query_init(IWineD3DQueryImpl *query, IWineD3DDeviceImpl *device,
|
||||||
|
|
||||||
case WINED3DQUERYTYPE_EVENT:
|
case WINED3DQUERYTYPE_EVENT:
|
||||||
TRACE("Event query.\n");
|
TRACE("Event query.\n");
|
||||||
if (!gl_info->supported[NV_FENCE] && !gl_info->supported[APPLE_FENCE])
|
if (!gl_info->supported[ARB_SYNC] && !gl_info->supported[NV_FENCE]
|
||||||
|
&& !gl_info->supported[APPLE_FENCE])
|
||||||
{
|
{
|
||||||
/* Half-Life 2 needs this query. It does not render the main
|
/* Half-Life 2 needs this query. It does not render the main
|
||||||
* menu correctly otherwise. Pretend to support it, faking
|
* menu correctly otherwise. Pretend to support it, faking
|
||||||
|
|
|
@ -1014,10 +1014,16 @@ struct wined3d_occlusion_query
|
||||||
struct wined3d_context *context;
|
struct wined3d_context *context;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
union wined3d_gl_query_object
|
||||||
|
{
|
||||||
|
GLuint id;
|
||||||
|
GLsync sync;
|
||||||
|
};
|
||||||
|
|
||||||
struct wined3d_event_query
|
struct wined3d_event_query
|
||||||
{
|
{
|
||||||
struct list entry;
|
struct list entry;
|
||||||
GLuint id;
|
union wined3d_gl_query_object object;
|
||||||
struct wined3d_context *context;
|
struct wined3d_context *context;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1090,7 +1096,7 @@ struct wined3d_context
|
||||||
UINT free_occlusion_query_count;
|
UINT free_occlusion_query_count;
|
||||||
struct list occlusion_queries;
|
struct list occlusion_queries;
|
||||||
|
|
||||||
GLuint *free_event_queries;
|
union wined3d_gl_query_object *free_event_queries;
|
||||||
UINT free_event_query_size;
|
UINT free_event_query_size;
|
||||||
UINT free_event_query_count;
|
UINT free_event_query_count;
|
||||||
struct list event_queries;
|
struct list event_queries;
|
||||||
|
|
Loading…
Reference in New Issue