[6/6] WineD3D: Support GL_APPLE_fence for event queries

Stefan Dösinger stefan at codeweavers.com
Wed Feb 28 18:55:25 CST 2007


Now we only need to wait for a GL_ATI_fence and GL_MESA_fence extension and we 
can support them on all cards :-)
-------------- next part --------------
From 6bf3cb058f24c531c1c34184fdd7f51fda9d6283 Mon Sep 17 00:00:00 2001
From: Stefan Doesinger <stefan at codeweavers.com>
Date: Thu, 1 Mar 2007 01:17:05 +0100
Subject: [PATCH] WineD3D: Support GL_APPLE_fence for event queries

For the sake of nice design of this patch:

       *
      *
  * * * *
 *        *
*        *   <--- This is supposed to be an apple
*         *
 *    *  *
  * *   *
---
 dlls/wined3d/device.c     |    8 ++++++--
 dlls/wined3d/directx.c    |   16 ++++++++++++++--
 dlls/wined3d/query.c      |   30 +++++++++++++++++++++---------
 include/wine/wined3d_gl.h |   24 ++++++++++++++++++++++++
 4 files changed, 65 insertions(+), 13 deletions(-)

diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 3ab1279..0ad2c47 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -1075,7 +1075,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateQuery(IWineD3DDevice *iface, WINE
         break;
 
     case WINED3DQUERYTYPE_EVENT:
-        if(!GL_SUPPORT(NV_FENCE)) {
+        if(!(GL_SUPPORT(NV_FENCE) || GL_SUPPORT(APPLE_FENCE) )) {
             /* Half-Life 2 needs this query. It does not render the main menu correctly otherwise
              * Pretend to support it, faking this query does not do much harm except potentially lowering performance
              */
@@ -1116,7 +1116,11 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateQuery(IWineD3DDevice *iface, WINE
         }
     case WINED3DQUERYTYPE_EVENT:
         /* TODO: GL_APPLE_fence */
-        if(GL_SUPPORT(NV_FENCE)) {
+        if(GL_SUPPORT(APPLE_FENCE)) {
+            object->extendedData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WineQueryEventData));
+            GL_EXTCALL(glGenFencesAPPLE(1, &((WineQueryEventData *)(object->extendedData))->fenceId));
+            checkGLcall("glGenFencesAPPLE");
+        } else if(GL_SUPPORT(NV_FENCE)) {
             object->extendedData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WineQueryEventData));
             GL_EXTCALL(glGenFencesNV(1, &((WineQueryEventData *)(object->extendedData))->fenceId));
             checkGLcall("glGenFencesNV");
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 291ac5b..d3ce06f 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -788,7 +788,9 @@ BOOL IWineD3DImpl_FillGLCaps(IWineD3D *iface, Display* display) {
                 TRACE_(d3d_caps)(" FOUND: NVIDIA (NV) Vertex Shader support - version=%02x\n", gl_info->vs_nv_version);
                 gl_info->supported[NV_VERTEX_PROGRAM] = TRUE;
             } else if (strstr(ThisExtn, "GL_NV_fence")) {
-                gl_info->supported[NV_FENCE] = TRUE;
+                if(!gl_info->supported[APPLE_FENCE]) {
+                    gl_info->supported[NV_FENCE] = TRUE;
+                }
 
             /**
              * ATI
@@ -807,9 +809,19 @@ BOOL IWineD3DImpl_FillGLCaps(IWineD3D *iface, Display* display) {
                 gl_info->vs_ati_version = VS_VERSION_11;
                 TRACE_(d3d_caps)(" FOUND: ATI (EXT) Vertex Shader support - version=%02x\n", gl_info->vs_ati_version);
                 gl_info->supported[EXT_VERTEX_SHADER] = TRUE;
+            /**
+             * Apple
+             */
+            } else if (strstr(ThisExtn, "GL_APPLE_fence")) {
+                /* GL_NV_fence and GL_APPLE_fence provide the same functionality basically.
+                 * The apple extension interacts with some other apple exts. Disable the NV
+                 * extension if the apple one is support to prevent confusion in other parts
+                 * of the code
+                 */
+                gl_info->supported[NV_FENCE] = FALSE;
+                gl_info->supported[APPLE_FENCE] = TRUE;
             }
 
-
             if (*GL_Extensions == ' ') GL_Extensions++;
         }
     }
diff --git a/dlls/wined3d/query.c b/dlls/wined3d/query.c
index 10a43e3..10f5c6d 100644
--- a/dlls/wined3d/query.c
+++ b/dlls/wined3d/query.c
@@ -65,9 +65,14 @@ static ULONG  WINAPI IWineD3DQueryImpl_Release(IWineD3DQuery *iface) {
     TRACE("(%p) : Releasing from %d\n", This, This->ref);
     ref = InterlockedDecrement(&This->ref);
     if (ref == 0) {
-        if(This->type == WINED3DQUERYTYPE_EVENT && GL_SUPPORT(NV_FENCE)) {
-            GL_EXTCALL(glDeleteFencesNV(1, &((WineQueryEventData *)(This->extendedData))->fenceId));
-            checkGLcall("glDeleteFencesNV");
+        if(This->type == WINED3DQUERYTYPE_EVENT) {
+            if(GL_SUPPORT(APPLE_FENCE)) {
+                GL_EXTCALL(glDeleteFencesAPPLE(1, &((WineQueryEventData *)(This->extendedData))->fenceId));
+                checkGLcall("glDeleteFencesAPPLE");
+            } else if(GL_SUPPORT(NV_FENCE)) {
+                GL_EXTCALL(glDeleteFencesNV(1, &((WineQueryEventData *)(This->extendedData))->fenceId));
+                checkGLcall("glDeleteFencesNV");
+            }
         } else if(This->type == WINED3DQUERYTYPE_OCCLUSION && GL_SUPPORT(ARB_OCCLUSION_QUERY)) {
             GL_EXTCALL(glDeleteQueriesARB(1, &((WineQueryOcclusionData *)(This->extendedData))->queryId));
             checkGLcall("glDeleteQueriesARB");
@@ -162,7 +167,10 @@ static HRESULT  WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa
     case WINED3DQUERYTYPE_EVENT:
     {
         BOOL* data = pData;
-        if(GL_SUPPORT(NV_FENCE)) {
+        if(GL_SUPPORT(APPLE_FENCE)) {
+            *data = GL_EXTCALL(glTestFenceAPPLE(((WineQueryEventData *)This->extendedData)->fenceId));
+            checkGLcall("glTestFenceAPPLE");
+        } else if(GL_SUPPORT(NV_FENCE)) {
             *data = GL_EXTCALL(glTestFenceNV(((WineQueryEventData *)This->extendedData)->fenceId));
             checkGLcall("glTestFenceNV");
         } else {
@@ -381,13 +389,17 @@ static HRESULT  WINAPI IWineD3DQueryImpl_Issue(IWineD3DQuery* iface,  DWORD dwIs
             break;
 
         case WINED3DQUERYTYPE_EVENT: {
-            if (GL_SUPPORT(GL_NV_fence)) {
-                if (dwIssueFlags & WINED3DISSUE_END) {
+            if (dwIssueFlags & WINED3DISSUE_END) {
+                if(GL_SUPPORT(APPLE_FENCE)) {
+                    GL_EXTCALL(glSetFenceAPPLE(((WineQueryEventData *)This->extendedData)->fenceId));
+                    checkGLcall("glSetFenceAPPLE");
+                } else if (GL_SUPPORT(NV_FENCE)) {
                     GL_EXTCALL(glSetFenceNV(((WineQueryEventData *)This->extendedData)->fenceId, GL_ALL_COMPLETED_NV));
-                } else if(dwIssueFlags & WINED3DISSUE_BEGIN) {
-                    /* Started implicitly at device creation */
-                    ERR("Event query issued with START flag - what to do?\n");
+                    checkGLcall("glSetFenceNV");
                 }
+            } else if(dwIssueFlags & WINED3DISSUE_BEGIN) {
+                /* Started implicitly at device creation */
+                ERR("Event query issued with START flag - what to do?\n");
             }
         }
 
diff --git a/include/wine/wined3d_gl.h b/include/wine/wined3d_gl.h
index 3d3f22b..7af8c98 100644
--- a/include/wine/wined3d_gl.h
+++ b/include/wine/wined3d_gl.h
@@ -1146,6 +1146,19 @@ typedef GLboolean (APIENTRY * PGLFNTESTFENCENVPROC) (GLuint);
 typedef void (APIENTRY * PGLFNFINISHFENCENVPROC) (GLuint);
 typedef GLboolean (APIENTRY * PGLFNISFENCENVPROC) (GLuint);
 typedef void (APIENTRY * PGLFNGETFENCEIVNVPROC) (GLuint, GLenum, GLint *);
+/* GL_APPLE_fence */
+#ifndef GL_NV_fence
+#define GL_DRAW_PIXELS_APPLE                0x8A0A
+#define GL_FENCE_APPLE                      0x84F3
+#endif
+typedef void (APIENTRY * PGLFNGENFENCESAPPLEPROC) (GLsizei, GLuint *);
+typedef void (APIENTRY * PGLFNDELETEFENCESAPPLEPROC) (GLuint, const GLuint *);
+typedef void (APIENTRY * PGLFNSETFENCEAPPLEPROC) (GLuint);
+typedef GLboolean (APIENTRY * PGLFNTESTFENCEAPPLEPROC) (GLuint);
+typedef void (APIENTRY * PGLFNFINISHFENCEAPPLEPROC) (GLuint);
+typedef GLboolean (APIENTRY * PGLFNISFENCEAPPLEPROC) (GLuint);
+typedef GLboolean (APIENTRY * PGLFNTESTOBJECTAPPLEPROC) (GLenum, GLuint);
+typedef void (APIENTRY * PGLFNFINISHOBJECTAPPLEPROC) (GLenum, GLuint);
 
 /* GL_VERSION_2_0 */
 #ifndef GL_VERSION_2_0
@@ -1509,6 +1522,8 @@ typedef enum _GL_SupportedExt {
   ATI_TEXTURE_ENV_COMBINE3,
   ATI_TEXTURE_MIRROR_ONCE,
   EXT_VERTEX_SHADER,
+  /* APPLE */
+  APPLE_FENCE,
 
   OPENGL_SUPPORTED_EXT_END
 } GL_SupportedExt;
@@ -1708,6 +1723,15 @@ typedef enum _GL_SupportedExt {
     USE_GL_FUNC(PGLFNFINISHFENCENVPROC,                         glFinishFenceNV); \
     USE_GL_FUNC(PGLFNISFENCENVPROC,                             glIsFenceNV); \
     USE_GL_FUNC(PGLFNGETFENCEIVNVPROC,                          glGetFenceivNV); \
+    /* GL_APPLE_fence */ \
+    USE_GL_FUNC(PGLFNGENFENCESAPPLEPROC,                        glGenFencesAPPLE); \
+    USE_GL_FUNC(PGLFNDELETEFENCESAPPLEPROC,                     glDeleteFencesAPPLE); \
+    USE_GL_FUNC(PGLFNSETFENCEAPPLEPROC,                         glSetFenceAPPLE); \
+    USE_GL_FUNC(PGLFNTESTFENCEAPPLEPROC,                        glTestFenceAPPLE); \
+    USE_GL_FUNC(PGLFNFINISHFENCEAPPLEPROC,                      glFinishFenceAPPLE); \
+    USE_GL_FUNC(PGLFNISFENCEAPPLEPROC,                          glIsFenceAPPLE); \
+    USE_GL_FUNC(PGLFNTESTOBJECTAPPLEPROC,                       glTestObjectAPPLE); \
+    USE_GL_FUNC(PGLFNFINISHOBJECTAPPLEPROC,                     glFinishObjectAPPLE); \
 
 /* OpenGL 2.0 functions */
 #define GL2_FUNCS_GEN \
-- 
1.4.4.3



More information about the wine-patches mailing list