wgl: Add a wine specific WGL extension which allows you to change the pixel format multiple times.
diff --git a/dlls/gdi32/driver.c b/dlls/gdi32/driver.c
index 8d75803..3a2776c 100644
--- a/dlls/gdi32/driver.c
+++ b/dlls/gdi32/driver.c
@@ -203,6 +203,7 @@
GET_FUNC(wglGetPbufferDCARB);
GET_FUNC(wglMakeContextCurrentARB);
GET_FUNC(wglMakeCurrent);
+ GET_FUNC(wglSetPixelFormatWINE);
GET_FUNC(wglShareLists);
GET_FUNC(wglUseFontBitmapsA);
GET_FUNC(wglUseFontBitmapsW);
diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h
index e3a320a..cbca896 100644
--- a/dlls/gdi32/gdi_private.h
+++ b/dlls/gdi32/gdi_private.h
@@ -230,6 +230,7 @@
HDC (*pwglGetPbufferDCARB)(PHYSDEV, void*);
BOOL (*pwglMakeCurrent)(PHYSDEV, HGLRC);
BOOL (*pwglMakeContextCurrentARB)(PHYSDEV, PHYSDEV, HGLRC);
+ BOOL (*pwglSetPixelFormatWINE)(PHYSDEV,INT,const PIXELFORMATDESCRIPTOR *);
BOOL (*pwglShareLists)(HGLRC hglrc1, HGLRC hglrc2);
BOOL (*pwglUseFontBitmapsA)(PHYSDEV, DWORD, DWORD, DWORD);
BOOL (*pwglUseFontBitmapsW)(PHYSDEV, DWORD, DWORD, DWORD);
diff --git a/dlls/gdi32/opengl.c b/dlls/gdi32/opengl.c
index f948cda..f0810a8 100644
--- a/dlls/gdi32/opengl.c
+++ b/dlls/gdi32/opengl.c
@@ -240,6 +240,26 @@
return ret;
}
+/**************************************************************************************
+ * WINE-specific wglSetPixelFormat which can set the iPixelFormat multiple times
+ *
+ */
+static BOOL WINAPI wglSetPixelFormatWINE(HDC hdc, int iPixelFormat, const PIXELFORMATDESCRIPTOR *ppfd)
+{
+ INT bRet = FALSE;
+ DC * dc = get_dc_ptr( hdc );
+
+ TRACE("(%p,%d,%p)\n", hdc, iPixelFormat, ppfd);
+
+ if (!dc) return 0;
+
+ if (!dc->funcs->pwglSetPixelFormatWINE) FIXME(" :stub\n");
+ else bRet = dc->funcs->pwglSetPixelFormatWINE(dc->physDev, iPixelFormat, ppfd);
+
+ release_dc_ptr( dc );
+ return bRet;
+}
+
/***********************************************************************
* wglShareLists (OPENGL32.@)
*/
@@ -333,6 +353,8 @@
return (PROC)wglMakeContextCurrentARB;
else if(ret && strcmp(func, "wglGetPbufferDCARB") == 0)
return (PROC)wglGetPbufferDCARB;
+ else if(ret && strcmp(func, "wglSetPixelFormatWINE") == 0)
+ return (PROC)wglSetPixelFormatWINE;
return ret;
}
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index 6e19cae..1fb65ae 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -296,12 +296,24 @@
if(!res) {
int oldPixelFormat = GetPixelFormat(hdc);
- if(oldPixelFormat) {
+ /* By default WGL doesn't allow pixel format adjustments but we need it here.
+ * For this reason there is a WINE-specific wglSetPixelFormat which allows you to
+ * set the pixel format multiple times. Only use it when it is really needed. */
+
+ if(oldPixelFormat == iPixelFormat) {
+ /* We don't have to do anything as the formats are the same :) */
+ } else if(oldPixelFormat && GL_SUPPORT(WGL_WINE_PIXEL_FORMAT_PASSTHROUGH)) {
+ res = GL_EXTCALL(wglSetPixelFormatWINE(hdc, iPixelFormat, NULL));
+
+ if(!res) {
+ ERR("wglSetPixelFormatWINE failed on HDC=%p for iPixelFormat=%d\n", hdc, iPixelFormat);
+ return FALSE;
+ }
+ } else if(oldPixelFormat) {
/* OpenGL doesn't allow pixel format adjustments. Print an error and continue using the old format.
* There's a big chance that the old format works although with a performance hit and perhaps rendering errors. */
ERR("HDC=%p is already set to iPixelFormat=%d and OpenGL doesn't allow changes!\n", hdc, oldPixelFormat);
- }
- else {
+ } else {
ERR("SetPixelFormat failed on HDC=%p for iPixelFormat=%d\n", hdc, iPixelFormat);
return FALSE;
}
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 6fb0d5e..b585a55 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -1377,6 +1377,10 @@
gl_info->supported[WGL_ARB_PBUFFER] = TRUE;
TRACE_(d3d_caps)("FOUND: WGL_ARB_pbuffer support\n");
}
+ if (!strcmp(ThisExtn, "WGL_WINE_pixel_format_passthrough")) {
+ gl_info->supported[WGL_WINE_PIXEL_FORMAT_PASSTHROUGH] = TRUE;
+ TRACE_(d3d_caps)("FOUND: WGL_WINE_pixel_format_passthrough support\n");
+ }
}
}
}
diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c
index 5ed354b..23896a2 100644
--- a/dlls/winex11.drv/opengl.c
+++ b/dlls/winex11.drv/opengl.c
@@ -3129,6 +3129,28 @@
}
/**
+ * X11DRV_wglSetPixelFormatWINE
+ *
+ * WGL_WINE_pixel_format_passthrough: wglSetPixelFormatWINE
+ * This is a WINE-specific wglSetPixelFormat which can set the pixel format multiple times.
+ */
+BOOL X11DRV_wglSetPixelFormatWINE(X11DRV_PDEVICE *physDev, int iPixelFormat, const PIXELFORMATDESCRIPTOR *ppfd)
+{
+ TRACE("(%p,%d,%p)\n", physDev, iPixelFormat, ppfd);
+
+ if (!has_opengl()) {
+ ERR("No libGL on this box - disabling OpenGL support !\n");
+ return FALSE;
+ }
+
+ if (physDev->current_pf == iPixelFormat) return TRUE;
+
+ /* Relay to the core SetPixelFormat */
+ TRACE("Changing iPixelFormat from %d to %d\n", physDev->current_pf, iPixelFormat);
+ return internal_SetPixelFormat(physDev, iPixelFormat, ppfd);
+}
+
+/**
* glxRequireVersion (internal)
*
* Check if the supported GLX version matches requiredVersion.
@@ -3266,6 +3288,14 @@
}
};
+static const WineGLExtension WGL_WINE_pixel_format_passthrough =
+{
+ "WGL_WINE_pixel_format_passthrough",
+ {
+ { "wglSetPixelFormatWINE", X11DRV_wglSetPixelFormatWINE },
+ }
+};
+
/**
* X11DRV_WineGL_LoadExtensions
*/
@@ -3335,6 +3365,13 @@
/* The OpenGL extension GL_NV_vertex_array_range adds wgl/glX functions which aren't exported as 'real' wgl/glX extensions. */
if(strstr(WineGLInfo.glExtensions, "GL_NV_vertex_array_range") != NULL)
register_extension(&WGL_NV_vertex_array_range);
+
+ /* WINE-specific WGL Extensions */
+
+ /* In WineD3D we need the ability to set the pixel format more than once (e.g. after a device reset).
+ * The default wglSetPixelFormat doesn't allow this, so add our own which allows it.
+ */
+ register_extension(&WGL_WINE_pixel_format_passthrough);
}
@@ -3598,6 +3635,18 @@
return FALSE;
}
+/**
+ * X11DRV_wglSetPixelFormatWINE
+ *
+ * WGL_WINE_pixel_format_passthrough: wglSetPixelFormatWINE
+ * This is a WINE-specific wglSetPixelFormat which can set the pixel format multiple times.
+ */
+BOOL X11DRV_wglSetPixelFormatWINE(X11DRV_PDEVICE *physDev, int iPixelFormat, const PIXELFORMATDESCRIPTOR *ppfd)
+{
+ ERR_(opengl)("No OpenGL support compiled in.\n");
+ return FALSE;
+}
+
Drawable get_glxdrawable(X11DRV_PDEVICE *physDev)
{
return 0;
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index 89b7150..3658c71 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -405,8 +405,6 @@
if (!(data = X11DRV_get_win_data(hwnd)) &&
!(data = X11DRV_create_win_data(hwnd))) return FALSE;
- if (data->fbconfig_id) return FALSE; /* can't change it twice */
-
wine_tsx11_lock();
vis = visual_from_fbconfig_id(fbconfig_id);
wine_tsx11_unlock();
@@ -451,6 +449,7 @@
attrib.colormap = data->colormap;
XInstallColormap(gdi_display, attrib.colormap);
+ if(data->gl_drawable) XDestroyWindow(gdi_display, data->gl_drawable);
data->gl_drawable = XCreateWindow(display, parent, -w, 0, w, h, 0,
vis->depth, InputOutput, vis->visual,
CWColormap | CWOverrideRedirect,
@@ -470,6 +469,8 @@
WARN("XComposite is not available, using GLXPixmap hack\n");
wine_tsx11_lock();
+
+ if(data->pixmap) XFreePixmap(display, data->pixmap);
data->pixmap = XCreatePixmap(display, root_window, w, h, vis->depth);
if(!data->pixmap)
{
@@ -478,6 +479,7 @@
return FALSE;
}
+ if(data->gl_drawable) destroy_glxpixmap(display, data->gl_drawable);
data->gl_drawable = create_glxpixmap(display, vis, data->pixmap);
if(!data->gl_drawable)
{
diff --git a/dlls/winex11.drv/winex11.drv.spec b/dlls/winex11.drv/winex11.drv.spec
index 959721d..6d469f8 100644
--- a/dlls/winex11.drv/winex11.drv.spec
+++ b/dlls/winex11.drv/winex11.drv.spec
@@ -142,6 +142,7 @@
@ cdecl wglGetPbufferDCARB(ptr ptr) X11DRV_wglGetPbufferDCARB
@ cdecl wglMakeContextCurrentARB(ptr ptr long) X11DRV_wglMakeContextCurrentARB
@ cdecl wglMakeCurrent(ptr long) X11DRV_wglMakeCurrent
+@ cdecl wglSetPixelFormatWINE(ptr long ptr) X11DRV_wglSetPixelFormatWINE
@ cdecl wglShareLists(long long) X11DRV_wglShareLists
@ cdecl wglUseFontBitmapsA(ptr long long long) X11DRV_wglUseFontBitmapsA
@ cdecl wglUseFontBitmapsW(ptr long long long) X11DRV_wglUseFontBitmapsW
diff --git a/include/wine/wined3d_gl.h b/include/wine/wined3d_gl.h
index 02432db..2467a73 100644
--- a/include/wine/wined3d_gl.h
+++ b/include/wine/wined3d_gl.h
@@ -3373,6 +3373,7 @@
/* WGL extensions */
WGL_ARB_PBUFFER,
+ WGL_WINE_PIXEL_FORMAT_PASSTHROUGH,
OPENGL_SUPPORTED_EXT_END
} GL_SupportedExt;
@@ -3762,6 +3763,8 @@
#define WGL_ARB_pixel_format_float 1
#define WGL_TYPE_RGBA_FLOAT_ARB 0x21A0
#endif
+/* WGL_WINE_pixel_format_passthrough */
+typedef BOOL (WINAPI * WINED3D_PFNWGLSETPIXELFORMATWINE) (HDC hdc, int iPixelFormat, const PIXELFORMATDESCRIPTOR* ppfd);
#define WGL_EXT_FUNCS_GEN \
USE_GL_FUNC(WINED3D_PFNWGLGETEXTENSIONSSTRINGARBPROC, wglGetExtensionsStringARB, 0, NULL); \
@@ -3774,7 +3777,8 @@
USE_GL_FUNC(WINED3D_PFNWGLGETPBUFFERDCARBPROC, wglGetPbufferDCARB, 0, NULL); \
USE_GL_FUNC(WINED3D_PFNWGLRELEASEPBUFFERDCARBPROC, wglReleasePbufferDCARB, 0, NULL); \
USE_GL_FUNC(WINED3D_PFNWGLDESTROYPBUFFERARBPROC, wglDestroyPbufferARB, 0, NULL); \
- USE_GL_FUNC(WINED3D_PFNWGLQUERYPBUFFERARBPROC, wglQueryPbufferARB, 0, NULL);
+ USE_GL_FUNC(WINED3D_PFNWGLQUERYPBUFFERARBPROC, wglQueryPbufferARB, 0, NULL) \
+ USE_GL_FUNC(WINED3D_PFNWGLSETPIXELFORMATWINE, wglSetPixelFormatWINE, 0, NULL);
/****************************************************