[4/5] WineD3D: Implement manual fencing with GL_APPLE_flush_buffer_range
Henri Verbeet
hverbeet at gmail.com
Wed Jan 6 06:06:47 CST 2010
2010/1/5 Stefan Dösinger <stefandoesinger at gmx.at>:
> After the discussion on IRC I wasn't quite sure what you intended with wined3d_event_query_wait(), but maybe it was something like this:
>
More something along the lines of the attached patch, actually. There
are of course some intermediate steps.
-------------- next part --------------
diff --git a/dlls/wined3d/query.c b/dlls/wined3d/query.c
index 1280a3b..fd146ba 100644
--- a/dlls/wined3d/query.c
+++ b/dlls/wined3d/query.c
@@ -31,7 +31,126 @@
*/
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
-#define GLINFO_LOCATION This->device->adapter->gl_info
+#define GLINFO_LOCATION (*gl_info)
+
+void wined3d_event_query_set(struct wined3d_event_query *query, const struct wined3d_context *context)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+ if (query->context != context)
+ {
+ ERR("Query was allocated in a different context, or not at all.\n");
+ return;
+ }
+
+ ENTER_GL();
+
+ if (gl_info->supported[APPLE_FENCE])
+ {
+ GL_EXTCALL(glSetFenceAPPLE(query->id));
+ checkGLcall("glSetFenceAPPLE");
+ }
+ else if (gl_info->supported[NV_FENCE])
+ {
+ GL_EXTCALL(glSetFenceNV(query->id, GL_ALL_COMPLETED_NV));
+ checkGLcall("glSetFenceNV");
+ }
+
+ LEAVE_GL();
+}
+
+BOOL wined3d_event_query_test(struct wined3d_event_query *query, IWineD3DDeviceImpl *device)
+{
+ const struct wined3d_gl_info *gl_info;
+ struct wined3d_context *context;
+ BOOL ret;
+
+ if (!query->context)
+ {
+ TRACE("Query not started, returning TRUE.\n");
+ return TRUE;
+ }
+
+ if (query->context->tid != GetCurrentThreadId())
+ {
+ FIXME("Wrong thread, returning FALSE.\n");
+ return FALSE;
+ }
+
+ context = context_acquire(device, query->context->current_rt, CTXUSAGE_RESOURCELOAD);
+ gl_info = context->gl_info;
+
+ ENTER_GL();
+
+ if (gl_info->supported[APPLE_FENCE])
+ {
+ ret = GL_EXTCALL(glTestFenceAPPLE(query->id));
+ checkGLcall("glTestFenceAPPLE");
+ }
+ else if (gl_info->supported[NV_FENCE])
+ {
+ ret = GL_EXTCALL(glTestFenceNV(query->id));
+ checkGLcall("glTestFenceNV");
+ }
+ else
+ {
+ ERR("Query shouldn't exist.\n");
+ ret = FALSE;
+ }
+
+ LEAVE_GL();
+
+ context_release(context);
+
+ return ret;
+}
+
+void wined3d_event_query_wait(struct wined3d_event_query *query, IWineD3DDeviceImpl *device)
+{
+ const struct wined3d_gl_info *gl_info;
+ struct wined3d_context *context;
+
+ if (!query->context)
+ {
+ TRACE("Query not started, returning.\n");
+ return;
+ }
+
+ if (query->context->tid != GetCurrentThreadId())
+ {
+ FIXME("Wrong thread, falling back to wglFinish().\n");
+ /* We can also end all other event queries here. */
+ wine_wglFinish();
+ return;
+ }
+
+ context = context_acquire(device, query->context->current_rt, CTXUSAGE_RESOURCELOAD);
+ gl_info = context->gl_info;
+
+ ENTER_GL();
+
+ if (gl_info->supported[APPLE_FENCE])
+ {
+ GL_EXTCALL(glFinishFenceAPPLE(query->id));
+ checkGLcall("glFinishFenceAPPLE");
+ }
+ else if (gl_info->supported[NV_FENCE])
+ {
+ GL_EXTCALL(glFinishFenceNV(query->id));
+ checkGLcall("glFinishFenceNV");
+ }
+ else
+ {
+ ERR("Query shouldn't exist, falling back to wglFinish().\n");
+ /* We can also end all other event queries here. */
+ wine_wglFinish();
+ return;
+ }
+
+ LEAVE_GL();
+
+ context_release(context);
+}
/* *******************************************
IWineD3DQuery IUnknown parts follow
@@ -341,53 +460,13 @@ static HRESULT WINAPI IWineD3DOcclusionQueryImpl_GetData(IWineD3DQuery* iface,
static HRESULT WINAPI IWineD3DEventQueryImpl_GetData(IWineD3DQuery* iface, void* pData, DWORD dwSize, DWORD dwGetDataFlags) {
IWineD3DQueryImpl *This = (IWineD3DQueryImpl *) iface;
struct wined3d_event_query *query = This->extendedData;
- struct wined3d_context *context;
BOOL *data = pData;
TRACE("(%p) : type D3DQUERY_EVENT, pData %p, dwSize %#x, dwGetDataFlags %#x\n", This, pData, dwSize, dwGetDataFlags);
if (!pData || !dwSize) return S_OK;
- if (!query->context)
- {
- TRACE("Query not started, returning TRUE.\n");
- *data = TRUE;
-
- return S_OK;
- }
-
- if (query->context->tid != GetCurrentThreadId())
- {
- /* See comment in IWineD3DQuery::Issue, event query codeblock */
- FIXME("Wrong thread, reporting GPU idle.\n");
- *data = TRUE;
-
- return S_OK;
- }
-
- context = context_acquire(This->device, query->context->current_rt, CTXUSAGE_RESOURCELOAD);
-
- ENTER_GL();
-
- if (context->gl_info->supported[APPLE_FENCE])
- {
- *data = GL_EXTCALL(glTestFenceAPPLE(query->id));
- checkGLcall("glTestFenceAPPLE");
- }
- else if (context->gl_info->supported[NV_FENCE])
- {
- *data = GL_EXTCALL(glTestFenceNV(query->id));
- checkGLcall("glTestFenceNV");
- }
- else
- {
- WARN("(%p): reporting GPU idle\n", This);
- *data = TRUE;
- }
-
- LEAVE_GL();
-
- context_release(context);
+ *data = wined3d_event_query_test(query, This->device);
return S_OK;
}
@@ -489,20 +568,7 @@ static HRESULT WINAPI IWineD3DEventQueryImpl_Issue(IWineD3DQuery* iface, DWORD
context_alloc_event_query(context, query);
}
- ENTER_GL();
-
- if (context->gl_info->supported[APPLE_FENCE])
- {
- GL_EXTCALL(glSetFenceAPPLE(query->id));
- checkGLcall("glSetFenceAPPLE");
- }
- else if (context->gl_info->supported[NV_FENCE])
- {
- GL_EXTCALL(glSetFenceNV(query->id, GL_ALL_COMPLETED_NV));
- checkGLcall("glSetFenceNV");
- }
-
- LEAVE_GL();
+ wined3d_event_query_set(query, context);
context_release(context);
}
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index de0bcdc..82ce83c 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2346,6 +2346,10 @@ extern const IWineD3DQueryVtbl IWineD3DQuery_Vtbl DECLSPEC_HIDDEN;
extern const IWineD3DQueryVtbl IWineD3DEventQuery_Vtbl DECLSPEC_HIDDEN;
extern const IWineD3DQueryVtbl IWineD3DOcclusionQuery_Vtbl DECLSPEC_HIDDEN;
+void wined3d_event_query_set(struct wined3d_event_query *query, const struct wined3d_context *context) DECLSPEC_HIDDEN;
+BOOL wined3d_event_query_test(struct wined3d_event_query *query, IWineD3DDeviceImpl *device) DECLSPEC_HIDDEN;
+void wined3d_event_query_wait(struct wined3d_event_query *query, IWineD3DDeviceImpl *device) DECLSPEC_HIDDEN;
+
/* IWineD3DBuffer */
/* TODO: Add tests and support for FLOAT16_4 POSITIONT, D3DCOLOR position, other
More information about the wine-devel
mailing list