Commit f0307d93 authored by Roderick Colenbrander's avatar Roderick Colenbrander Committed by Alexandre Julliard

wgl: Add a wine specific WGL extension which allows you to change the pixel format multiple times.

parent 2823e1d2
...@@ -203,6 +203,7 @@ static struct graphics_driver *create_driver( HMODULE module ) ...@@ -203,6 +203,7 @@ static struct graphics_driver *create_driver( HMODULE module )
GET_FUNC(wglGetPbufferDCARB); GET_FUNC(wglGetPbufferDCARB);
GET_FUNC(wglMakeContextCurrentARB); GET_FUNC(wglMakeContextCurrentARB);
GET_FUNC(wglMakeCurrent); GET_FUNC(wglMakeCurrent);
GET_FUNC(wglSetPixelFormatWINE);
GET_FUNC(wglShareLists); GET_FUNC(wglShareLists);
GET_FUNC(wglUseFontBitmapsA); GET_FUNC(wglUseFontBitmapsA);
GET_FUNC(wglUseFontBitmapsW); GET_FUNC(wglUseFontBitmapsW);
......
...@@ -230,6 +230,7 @@ typedef struct tagDC_FUNCS ...@@ -230,6 +230,7 @@ typedef struct tagDC_FUNCS
HDC (*pwglGetPbufferDCARB)(PHYSDEV, void*); HDC (*pwglGetPbufferDCARB)(PHYSDEV, void*);
BOOL (*pwglMakeCurrent)(PHYSDEV, HGLRC); BOOL (*pwglMakeCurrent)(PHYSDEV, HGLRC);
BOOL (*pwglMakeContextCurrentARB)(PHYSDEV, PHYSDEV, HGLRC); BOOL (*pwglMakeContextCurrentARB)(PHYSDEV, PHYSDEV, HGLRC);
BOOL (*pwglSetPixelFormatWINE)(PHYSDEV,INT,const PIXELFORMATDESCRIPTOR *);
BOOL (*pwglShareLists)(HGLRC hglrc1, HGLRC hglrc2); BOOL (*pwglShareLists)(HGLRC hglrc1, HGLRC hglrc2);
BOOL (*pwglUseFontBitmapsA)(PHYSDEV, DWORD, DWORD, DWORD); BOOL (*pwglUseFontBitmapsA)(PHYSDEV, DWORD, DWORD, DWORD);
BOOL (*pwglUseFontBitmapsW)(PHYSDEV, DWORD, DWORD, DWORD); BOOL (*pwglUseFontBitmapsW)(PHYSDEV, DWORD, DWORD, DWORD);
......
...@@ -240,6 +240,26 @@ static BOOL WINAPI wglMakeContextCurrentARB(HDC hDrawDC, HDC hReadDC, HGLRC hglr ...@@ -240,6 +240,26 @@ static BOOL WINAPI wglMakeContextCurrentARB(HDC hDrawDC, HDC hReadDC, HGLRC hglr
return ret; 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.@) * wglShareLists (OPENGL32.@)
*/ */
...@@ -333,6 +353,8 @@ PROC WINAPI wglGetProcAddress(LPCSTR func) ...@@ -333,6 +353,8 @@ PROC WINAPI wglGetProcAddress(LPCSTR func)
return (PROC)wglMakeContextCurrentARB; return (PROC)wglMakeContextCurrentARB;
else if(ret && strcmp(func, "wglGetPbufferDCARB") == 0) else if(ret && strcmp(func, "wglGetPbufferDCARB") == 0)
return (PROC)wglGetPbufferDCARB; return (PROC)wglGetPbufferDCARB;
else if(ret && strcmp(func, "wglSetPixelFormatWINE") == 0)
return (PROC)wglSetPixelFormatWINE;
return ret; return ret;
} }
...@@ -296,12 +296,24 @@ WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *tar ...@@ -296,12 +296,24 @@ WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *tar
if(!res) { if(!res) {
int oldPixelFormat = GetPixelFormat(hdc); 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. /* 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. */ * 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); 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); ERR("SetPixelFormat failed on HDC=%p for iPixelFormat=%d\n", hdc, iPixelFormat);
return FALSE; return FALSE;
} }
......
...@@ -1377,6 +1377,10 @@ BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) { ...@@ -1377,6 +1377,10 @@ BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) {
gl_info->supported[WGL_ARB_PBUFFER] = TRUE; gl_info->supported[WGL_ARB_PBUFFER] = TRUE;
TRACE_(d3d_caps)("FOUND: WGL_ARB_pbuffer support\n"); 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");
}
} }
} }
} }
......
...@@ -3129,6 +3129,28 @@ static void WINAPI X11DRV_wglFreeMemoryNV(GLvoid* pointer) { ...@@ -3129,6 +3129,28 @@ static void WINAPI X11DRV_wglFreeMemoryNV(GLvoid* pointer) {
} }
/** /**
* 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) * glxRequireVersion (internal)
* *
* Check if the supported GLX version matches requiredVersion. * Check if the supported GLX version matches requiredVersion.
...@@ -3266,6 +3288,14 @@ static const WineGLExtension WGL_NV_vertex_array_range = ...@@ -3266,6 +3288,14 @@ static const WineGLExtension WGL_NV_vertex_array_range =
} }
}; };
static const WineGLExtension WGL_WINE_pixel_format_passthrough =
{
"WGL_WINE_pixel_format_passthrough",
{
{ "wglSetPixelFormatWINE", X11DRV_wglSetPixelFormatWINE },
}
};
/** /**
* X11DRV_WineGL_LoadExtensions * X11DRV_WineGL_LoadExtensions
*/ */
...@@ -3335,6 +3365,13 @@ static void X11DRV_WineGL_LoadExtensions(void) ...@@ -3335,6 +3365,13 @@ static void X11DRV_WineGL_LoadExtensions(void)
/* The OpenGL extension GL_NV_vertex_array_range adds wgl/glX functions which aren't exported as 'real' wgl/glX extensions. */ /* 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) if(strstr(WineGLInfo.glExtensions, "GL_NV_vertex_array_range") != NULL)
register_extension(&WGL_NV_vertex_array_range); 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 @@ BOOL X11DRV_wglUseFontBitmapsW(X11DRV_PDEVICE *physDev, DWORD first, DWORD count ...@@ -3598,6 +3635,18 @@ BOOL X11DRV_wglUseFontBitmapsW(X11DRV_PDEVICE *physDev, DWORD first, DWORD count
return FALSE; 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) Drawable get_glxdrawable(X11DRV_PDEVICE *physDev)
{ {
return 0; return 0;
......
...@@ -405,8 +405,6 @@ BOOL X11DRV_set_win_format( HWND hwnd, XID fbconfig_id ) ...@@ -405,8 +405,6 @@ BOOL X11DRV_set_win_format( HWND hwnd, XID fbconfig_id )
if (!(data = X11DRV_get_win_data(hwnd)) && if (!(data = X11DRV_get_win_data(hwnd)) &&
!(data = X11DRV_create_win_data(hwnd))) return FALSE; !(data = X11DRV_create_win_data(hwnd))) return FALSE;
if (data->fbconfig_id) return FALSE; /* can't change it twice */
wine_tsx11_lock(); wine_tsx11_lock();
vis = visual_from_fbconfig_id(fbconfig_id); vis = visual_from_fbconfig_id(fbconfig_id);
wine_tsx11_unlock(); wine_tsx11_unlock();
...@@ -451,6 +449,7 @@ BOOL X11DRV_set_win_format( HWND hwnd, XID fbconfig_id ) ...@@ -451,6 +449,7 @@ BOOL X11DRV_set_win_format( HWND hwnd, XID fbconfig_id )
attrib.colormap = data->colormap; attrib.colormap = data->colormap;
XInstallColormap(gdi_display, attrib.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, data->gl_drawable = XCreateWindow(display, parent, -w, 0, w, h, 0,
vis->depth, InputOutput, vis->visual, vis->depth, InputOutput, vis->visual,
CWColormap | CWOverrideRedirect, CWColormap | CWOverrideRedirect,
...@@ -470,6 +469,8 @@ BOOL X11DRV_set_win_format( HWND hwnd, XID fbconfig_id ) ...@@ -470,6 +469,8 @@ BOOL X11DRV_set_win_format( HWND hwnd, XID fbconfig_id )
WARN("XComposite is not available, using GLXPixmap hack\n"); WARN("XComposite is not available, using GLXPixmap hack\n");
wine_tsx11_lock(); wine_tsx11_lock();
if(data->pixmap) XFreePixmap(display, data->pixmap);
data->pixmap = XCreatePixmap(display, root_window, w, h, vis->depth); data->pixmap = XCreatePixmap(display, root_window, w, h, vis->depth);
if(!data->pixmap) if(!data->pixmap)
{ {
...@@ -478,6 +479,7 @@ BOOL X11DRV_set_win_format( HWND hwnd, XID fbconfig_id ) ...@@ -478,6 +479,7 @@ BOOL X11DRV_set_win_format( HWND hwnd, XID fbconfig_id )
return FALSE; return FALSE;
} }
if(data->gl_drawable) destroy_glxpixmap(display, data->gl_drawable);
data->gl_drawable = create_glxpixmap(display, vis, data->pixmap); data->gl_drawable = create_glxpixmap(display, vis, data->pixmap);
if(!data->gl_drawable) if(!data->gl_drawable)
{ {
......
...@@ -142,6 +142,7 @@ ...@@ -142,6 +142,7 @@
@ cdecl wglGetPbufferDCARB(ptr ptr) X11DRV_wglGetPbufferDCARB @ cdecl wglGetPbufferDCARB(ptr ptr) X11DRV_wglGetPbufferDCARB
@ cdecl wglMakeContextCurrentARB(ptr ptr long) X11DRV_wglMakeContextCurrentARB @ cdecl wglMakeContextCurrentARB(ptr ptr long) X11DRV_wglMakeContextCurrentARB
@ cdecl wglMakeCurrent(ptr long) X11DRV_wglMakeCurrent @ cdecl wglMakeCurrent(ptr long) X11DRV_wglMakeCurrent
@ cdecl wglSetPixelFormatWINE(ptr long ptr) X11DRV_wglSetPixelFormatWINE
@ cdecl wglShareLists(long long) X11DRV_wglShareLists @ cdecl wglShareLists(long long) X11DRV_wglShareLists
@ cdecl wglUseFontBitmapsA(ptr long long long) X11DRV_wglUseFontBitmapsA @ cdecl wglUseFontBitmapsA(ptr long long long) X11DRV_wglUseFontBitmapsA
@ cdecl wglUseFontBitmapsW(ptr long long long) X11DRV_wglUseFontBitmapsW @ cdecl wglUseFontBitmapsW(ptr long long long) X11DRV_wglUseFontBitmapsW
......
...@@ -3373,6 +3373,7 @@ typedef enum _GL_SupportedExt { ...@@ -3373,6 +3373,7 @@ typedef enum _GL_SupportedExt {
/* WGL extensions */ /* WGL extensions */
WGL_ARB_PBUFFER, WGL_ARB_PBUFFER,
WGL_WINE_PIXEL_FORMAT_PASSTHROUGH,
OPENGL_SUPPORTED_EXT_END OPENGL_SUPPORTED_EXT_END
} GL_SupportedExt; } GL_SupportedExt;
...@@ -3762,6 +3763,8 @@ typedef BOOL (WINAPI * WINED3D_PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer, ...@@ -3762,6 +3763,8 @@ typedef BOOL (WINAPI * WINED3D_PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer,
#define WGL_ARB_pixel_format_float 1 #define WGL_ARB_pixel_format_float 1
#define WGL_TYPE_RGBA_FLOAT_ARB 0x21A0 #define WGL_TYPE_RGBA_FLOAT_ARB 0x21A0
#endif #endif
/* WGL_WINE_pixel_format_passthrough */
typedef BOOL (WINAPI * WINED3D_PFNWGLSETPIXELFORMATWINE) (HDC hdc, int iPixelFormat, const PIXELFORMATDESCRIPTOR* ppfd);
#define WGL_EXT_FUNCS_GEN \ #define WGL_EXT_FUNCS_GEN \
USE_GL_FUNC(WINED3D_PFNWGLGETEXTENSIONSSTRINGARBPROC, wglGetExtensionsStringARB, 0, NULL); \ USE_GL_FUNC(WINED3D_PFNWGLGETEXTENSIONSSTRINGARBPROC, wglGetExtensionsStringARB, 0, NULL); \
...@@ -3774,7 +3777,8 @@ typedef BOOL (WINAPI * WINED3D_PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer, ...@@ -3774,7 +3777,8 @@ typedef BOOL (WINAPI * WINED3D_PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer,
USE_GL_FUNC(WINED3D_PFNWGLGETPBUFFERDCARBPROC, wglGetPbufferDCARB, 0, NULL); \ USE_GL_FUNC(WINED3D_PFNWGLGETPBUFFERDCARBPROC, wglGetPbufferDCARB, 0, NULL); \
USE_GL_FUNC(WINED3D_PFNWGLRELEASEPBUFFERDCARBPROC, wglReleasePbufferDCARB, 0, NULL); \ USE_GL_FUNC(WINED3D_PFNWGLRELEASEPBUFFERDCARBPROC, wglReleasePbufferDCARB, 0, NULL); \
USE_GL_FUNC(WINED3D_PFNWGLDESTROYPBUFFERARBPROC, wglDestroyPbufferARB, 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);
/**************************************************** /****************************************************
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment