[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