2002-06-01 01:06:46 +02:00
/*
2000-05-12 22:18:14 +02:00
* X11DRV OpenGL functions
*
* Copyright 2000 Lionel Ulmer
2006-09-11 21:28:32 +02:00
* Copyright 2005 Alex Woods
* Copyright 2005 Raphael Junqueira
2009-04-20 22:57:19 +02:00
* Copyright 2006 - 2009 Roderick Colenbrander
2006-09-11 21:28:32 +02:00
* Copyright 2006 Tomas Carnecky
2000-05-12 22:18:14 +02:00
*
2002-03-10 00:29:33 +01:00
* This library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation ; either
* version 2.1 of the License , or ( at your option ) any later version .
*
* This library is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* Lesser General Public License for more details .
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library ; if not , write to the Free Software
2006-05-18 14:49:52 +02:00
* Foundation , Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 , USA
2000-05-12 22:18:14 +02:00
*/
# include "config.h"
2002-11-15 05:16:38 +01:00
# include "wine/port.h"
2000-05-12 22:18:14 +02:00
2006-09-12 11:50:36 +02:00
# include <assert.h>
2000-05-12 22:18:14 +02:00
# include <stdlib.h>
# include <string.h>
# include "x11drv.h"
2006-08-29 16:58:49 +02:00
# include "winternl.h"
2004-01-20 23:48:57 +01:00
# include "wine/library.h"
2002-09-25 02:29:56 +02:00
# include "wine/debug.h"
2000-05-12 22:18:14 +02:00
2006-03-25 13:07:23 +01:00
WINE_DEFAULT_DEBUG_CHANNEL ( wgl ) ;
2000-05-12 22:18:14 +02:00
2007-07-04 12:44:12 +02:00
# ifdef SONAME_LIBGL
2000-05-12 22:18:14 +02:00
2002-09-25 02:29:56 +02:00
# undef APIENTRY
# undef CALLBACK
# undef WINAPI
2002-10-02 03:24:27 +02:00
# ifdef HAVE_GL_GL_H
# include <GL / gl.h>
# endif
# ifdef HAVE_GL_GLX_H
# include <GL / glx.h>
# endif
2002-09-25 02:29:56 +02:00
# ifdef HAVE_GL_GLEXT_H
# include <GL / glext.h>
# endif
2006-09-11 21:28:32 +02:00
# include "wine/wgl.h"
2002-09-25 02:29:56 +02:00
# undef APIENTRY
# undef CALLBACK
# undef WINAPI
/* Redefines the constants */
# define CALLBACK __stdcall
# define WINAPI __stdcall
# define APIENTRY WINAPI
2006-09-11 21:28:32 +02:00
2006-08-25 18:37:52 +02:00
WINE_DECLARE_DEBUG_CHANNEL ( fps ) ;
2002-09-25 02:29:56 +02:00
2006-09-11 21:28:32 +02:00
typedef struct wine_glextension {
const char * extName ;
struct {
const char * funcName ;
void * funcAddress ;
2007-09-23 05:45:27 +02:00
} extEntryPoints [ 9 ] ;
2006-09-11 21:28:32 +02:00
} WineGLExtension ;
struct WineGLInfo {
const char * glVersion ;
2009-05-26 00:52:05 +02:00
char * glExtensions ;
2006-09-11 21:28:32 +02:00
int glxVersion [ 2 ] ;
const char * glxServerVersion ;
2007-08-08 16:40:34 +02:00
const char * glxServerVendor ;
2006-09-11 21:28:32 +02:00
const char * glxServerExtensions ;
const char * glxClientVersion ;
2007-08-08 16:40:34 +02:00
const char * glxClientVendor ;
2006-09-11 21:28:32 +02:00
const char * glxClientExtensions ;
const char * glxExtensions ;
BOOL glxDirect ;
char wglExtensions [ 4096 ] ;
} ;
2006-11-18 23:29:48 +01:00
typedef struct wine_glpixelformat {
2007-07-26 19:23:39 +02:00
int iPixelFormat ;
GLXFBConfig fbconfig ;
int fmt_id ;
2007-07-28 18:56:12 +02:00
int render_type ;
2007-07-26 19:23:39 +02:00
BOOL offscreenOnly ;
2009-05-14 17:05:20 +02:00
DWORD dwFlags ; /* We store some PFD_* flags in here for emulated bitmap formats */
2006-11-18 23:29:48 +01:00
} WineGLPixelFormat ;
2007-07-28 18:56:12 +02:00
typedef struct wine_glcontext {
HDC hdc ;
2008-04-30 21:06:13 +02:00
BOOL do_escape ;
2007-07-28 18:56:12 +02:00
XVisualInfo * vis ;
WineGLPixelFormat * fmt ;
GLXContext ctx ;
2007-10-10 17:38:51 +02:00
HDC read_hdc ;
2007-09-26 16:15:52 +02:00
Drawable drawables [ 2 ] ;
BOOL refresh_drawables ;
2007-07-28 18:56:12 +02:00
struct wine_glcontext * next ;
struct wine_glcontext * prev ;
} Wine_GLContext ;
2007-07-27 15:19:46 +02:00
typedef struct wine_glpbuffer {
Drawable drawable ;
Display * display ;
WineGLPixelFormat * fmt ;
int width ;
int height ;
int * attribList ;
HDC hdc ;
2007-07-28 00:20:44 +02:00
int use_render_texture ; /* This is also the internal texture format */
int texture_bind_target ;
int texture_bpp ;
GLint texture_format ;
2007-07-27 15:19:46 +02:00
GLuint texture_target ;
2007-07-28 00:20:44 +02:00
GLenum texture_type ;
2007-07-27 15:19:46 +02:00
GLuint texture ;
int texture_level ;
} Wine_GLPBuffer ;
2006-08-29 16:56:57 +02:00
static Wine_GLContext * context_list ;
2006-09-11 21:28:32 +02:00
static struct WineGLInfo WineGLInfo = { 0 } ;
2007-07-25 22:32:07 +02:00
static int use_render_texture_emulation = 1 ;
2007-08-17 11:16:29 +02:00
static int use_render_texture_ati = 0 ;
2006-09-11 21:28:32 +02:00
static int swap_interval = 1 ;
2006-09-12 11:50:36 +02:00
# define MAX_EXTENSIONS 16
static const WineGLExtension * WineGLExtensionList [ MAX_EXTENSIONS ] ;
static int WineGLExtensionListSize ;
static void X11DRV_WineGL_LoadExtensions ( void ) ;
2007-08-08 16:40:34 +02:00
static BOOL glxRequireVersion ( int requiredVersion ) ;
static BOOL glxRequireExtension ( const char * requiredExtension ) ;
2006-08-29 16:56:57 +02:00
2004-11-30 22:38:57 +01:00
static void dump_PIXELFORMATDESCRIPTOR ( const PIXELFORMATDESCRIPTOR * ppfd ) {
2005-09-25 17:23:21 +02:00
TRACE ( " - size / version : %d / %d \n " , ppfd - > nSize , ppfd - > nVersion ) ;
TRACE ( " - dwFlags : " ) ;
# define TEST_AND_DUMP(t,tv) if ((t) & (tv)) TRACE(#tv " ")
2000-05-12 22:18:14 +02:00
TEST_AND_DUMP ( ppfd - > dwFlags , PFD_DEPTH_DONTCARE ) ;
TEST_AND_DUMP ( ppfd - > dwFlags , PFD_DOUBLEBUFFER ) ;
TEST_AND_DUMP ( ppfd - > dwFlags , PFD_DOUBLEBUFFER_DONTCARE ) ;
TEST_AND_DUMP ( ppfd - > dwFlags , PFD_DRAW_TO_WINDOW ) ;
TEST_AND_DUMP ( ppfd - > dwFlags , PFD_DRAW_TO_BITMAP ) ;
TEST_AND_DUMP ( ppfd - > dwFlags , PFD_GENERIC_ACCELERATED ) ;
TEST_AND_DUMP ( ppfd - > dwFlags , PFD_GENERIC_FORMAT ) ;
TEST_AND_DUMP ( ppfd - > dwFlags , PFD_NEED_PALETTE ) ;
TEST_AND_DUMP ( ppfd - > dwFlags , PFD_NEED_SYSTEM_PALETTE ) ;
TEST_AND_DUMP ( ppfd - > dwFlags , PFD_STEREO ) ;
TEST_AND_DUMP ( ppfd - > dwFlags , PFD_STEREO_DONTCARE ) ;
TEST_AND_DUMP ( ppfd - > dwFlags , PFD_SUPPORT_GDI ) ;
TEST_AND_DUMP ( ppfd - > dwFlags , PFD_SUPPORT_OPENGL ) ;
TEST_AND_DUMP ( ppfd - > dwFlags , PFD_SWAP_COPY ) ;
TEST_AND_DUMP ( ppfd - > dwFlags , PFD_SWAP_EXCHANGE ) ;
TEST_AND_DUMP ( ppfd - > dwFlags , PFD_SWAP_LAYER_BUFFERS ) ;
2007-08-14 11:31:14 +02:00
/* PFD_SUPPORT_COMPOSITION is new in Vista, it is similar to composition
* under X e . g . COMPOSITE + GLX_EXT_TEXTURE_FROM_PIXMAP . */
TEST_AND_DUMP ( ppfd - > dwFlags , PFD_SUPPORT_COMPOSITION ) ;
2000-05-12 22:18:14 +02:00
# undef TEST_AND_DUMP
2005-09-25 17:23:21 +02:00
TRACE ( " \n " ) ;
2002-06-01 01:06:46 +02:00
2005-09-25 17:23:21 +02:00
TRACE ( " - iPixelType : " ) ;
2000-05-12 22:18:14 +02:00
switch ( ppfd - > iPixelType ) {
2005-09-25 17:23:21 +02:00
case PFD_TYPE_RGBA : TRACE ( " PFD_TYPE_RGBA " ) ; break ;
case PFD_TYPE_COLORINDEX : TRACE ( " PFD_TYPE_COLORINDEX " ) ; break ;
2000-05-12 22:18:14 +02:00
}
2005-09-25 17:23:21 +02:00
TRACE ( " \n " ) ;
2002-06-01 01:06:46 +02:00
2005-09-25 17:23:21 +02:00
TRACE ( " - Color : %d \n " , ppfd - > cColorBits ) ;
TRACE ( " - Red : %d \n " , ppfd - > cRedBits ) ;
TRACE ( " - Green : %d \n " , ppfd - > cGreenBits ) ;
TRACE ( " - Blue : %d \n " , ppfd - > cBlueBits ) ;
TRACE ( " - Alpha : %d \n " , ppfd - > cAlphaBits ) ;
TRACE ( " - Accum : %d \n " , ppfd - > cAccumBits ) ;
TRACE ( " - Depth : %d \n " , ppfd - > cDepthBits ) ;
TRACE ( " - Stencil : %d \n " , ppfd - > cStencilBits ) ;
TRACE ( " - Aux : %d \n " , ppfd - > cAuxBuffers ) ;
2002-06-01 01:06:46 +02:00
2005-09-25 17:23:21 +02:00
TRACE ( " - iLayerType : " ) ;
2000-05-12 22:18:14 +02:00
switch ( ppfd - > iLayerType ) {
2005-09-25 17:23:21 +02:00
case PFD_MAIN_PLANE : TRACE ( " PFD_MAIN_PLANE " ) ; break ;
case PFD_OVERLAY_PLANE : TRACE ( " PFD_OVERLAY_PLANE " ) ; break ;
case ( BYTE ) PFD_UNDERLAY_PLANE : TRACE ( " PFD_UNDERLAY_PLANE " ) ; break ;
2000-05-12 22:18:14 +02:00
}
2005-09-25 17:23:21 +02:00
TRACE ( " \n " ) ;
2000-05-12 22:18:14 +02:00
}
2002-06-01 01:06:46 +02:00
2006-09-11 21:28:32 +02:00
# define PUSH1(attribs,att) do { attribs[nAttribs++] = (att); } while (0)
# define PUSH2(attribs,att,value) do { attribs[nAttribs++] = (att); attribs[nAttribs++] = (value); } while(0)
2002-11-15 05:16:38 +01:00
# define MAKE_FUNCPTR(f) static typeof(f) * p##f;
2006-09-11 21:28:32 +02:00
/* GLX 1.0 */
2002-11-15 05:16:38 +01:00
MAKE_FUNCPTR ( glXChooseVisual )
2007-11-11 21:32:12 +01:00
MAKE_FUNCPTR ( glXCopyContext )
2006-09-11 21:28:32 +02:00
MAKE_FUNCPTR ( glXCreateContext )
MAKE_FUNCPTR ( glXCreateGLXPixmap )
MAKE_FUNCPTR ( glXGetCurrentContext )
2007-07-25 22:32:07 +02:00
MAKE_FUNCPTR ( glXGetCurrentDrawable )
2006-09-11 21:28:32 +02:00
MAKE_FUNCPTR ( glXDestroyContext )
MAKE_FUNCPTR ( glXDestroyGLXPixmap )
2002-11-15 05:16:38 +01:00
MAKE_FUNCPTR ( glXGetConfig )
2006-09-11 21:28:32 +02:00
MAKE_FUNCPTR ( glXIsDirect )
MAKE_FUNCPTR ( glXMakeCurrent )
2002-11-15 05:16:38 +01:00
MAKE_FUNCPTR ( glXSwapBuffers )
MAKE_FUNCPTR ( glXQueryExtension )
2006-09-11 21:28:32 +02:00
MAKE_FUNCPTR ( glXQueryVersion )
2006-09-20 23:23:17 +02:00
MAKE_FUNCPTR ( glXUseXFont )
2006-09-11 21:28:32 +02:00
/* GLX 1.1 */
MAKE_FUNCPTR ( glXGetClientString )
MAKE_FUNCPTR ( glXQueryExtensionsString )
2006-08-29 16:58:49 +02:00
MAKE_FUNCPTR ( glXQueryServerString )
2005-04-28 20:29:12 +02:00
2006-09-11 21:28:32 +02:00
/* GLX 1.3 */
2005-04-28 20:29:12 +02:00
MAKE_FUNCPTR ( glXGetFBConfigs )
MAKE_FUNCPTR ( glXChooseFBConfig )
2006-09-11 21:28:32 +02:00
MAKE_FUNCPTR ( glXCreatePbuffer )
2007-07-26 20:32:22 +02:00
MAKE_FUNCPTR ( glXCreateNewContext )
2006-09-11 21:28:32 +02:00
MAKE_FUNCPTR ( glXDestroyPbuffer )
2005-04-28 20:29:12 +02:00
MAKE_FUNCPTR ( glXGetFBConfigAttrib )
2006-08-29 16:56:57 +02:00
MAKE_FUNCPTR ( glXGetVisualFromFBConfig )
2006-08-29 16:58:49 +02:00
MAKE_FUNCPTR ( glXMakeContextCurrent )
MAKE_FUNCPTR ( glXQueryDrawable )
2006-09-11 21:28:32 +02:00
MAKE_FUNCPTR ( glXGetCurrentReadDrawable )
2006-08-29 16:58:49 +02:00
2006-09-11 21:28:32 +02:00
/* GLX Extensions */
static void * ( * pglXGetProcAddressARB ) ( const GLubyte * ) ;
static int ( * pglXSwapIntervalSGI ) ( int ) ;
2007-08-12 17:31:25 +02:00
/* ATI GLX Extensions */
static BOOL ( * pglXBindTexImageATI ) ( Display * dpy , GLXPbuffer pbuffer , int buffer ) ;
static BOOL ( * pglXReleaseTexImageATI ) ( Display * dpy , GLXPbuffer pbuffer , int buffer ) ;
static BOOL ( * pglXDrawableAttribATI ) ( Display * dpy , GLXDrawable draw , const int * attribList ) ;
2006-12-03 22:40:24 +01:00
/* NV GLX Extension */
static void * ( * pglXAllocateMemoryNV ) ( GLsizei size , GLfloat readfreq , GLfloat writefreq , GLfloat priority ) ;
static void ( * pglXFreeMemoryNV ) ( GLvoid * pointer ) ;
2007-09-26 20:01:07 +02:00
/* MESA GLX Extensions */
static void ( * pglXCopySubBufferMESA ) ( Display * dpy , GLXDrawable drawable , int x , int y , int width , int height ) ;
2006-09-11 21:28:32 +02:00
/* Standard OpenGL */
MAKE_FUNCPTR ( glBindTexture )
2006-09-20 23:23:17 +02:00
MAKE_FUNCPTR ( glBitmap )
2006-09-11 21:28:32 +02:00
MAKE_FUNCPTR ( glCopyTexSubImage1D )
2007-07-29 14:13:45 +02:00
MAKE_FUNCPTR ( glCopyTexImage2D )
2006-09-11 21:28:32 +02:00
MAKE_FUNCPTR ( glCopyTexSubImage2D )
2006-08-29 16:58:49 +02:00
MAKE_FUNCPTR ( glDrawBuffer )
2006-09-20 23:23:17 +02:00
MAKE_FUNCPTR ( glEndList )
2006-09-11 21:28:32 +02:00
MAKE_FUNCPTR ( glGetError )
MAKE_FUNCPTR ( glGetIntegerv )
MAKE_FUNCPTR ( glGetString )
2006-09-20 23:23:17 +02:00
MAKE_FUNCPTR ( glNewList )
MAKE_FUNCPTR ( glPixelStorei )
2007-07-25 22:32:07 +02:00
MAKE_FUNCPTR ( glReadPixels )
MAKE_FUNCPTR ( glTexImage2D )
2007-09-23 05:45:27 +02:00
MAKE_FUNCPTR ( glFinish )
MAKE_FUNCPTR ( glFlush )
2002-11-15 05:16:38 +01:00
# undef MAKE_FUNCPTR
2009-05-26 00:52:05 +02:00
static BOOL infoInitialized = FALSE ;
2006-10-31 21:41:02 +01:00
static BOOL X11DRV_WineGL_InitOpenglInfo ( void )
2006-09-11 21:28:32 +02:00
{
int screen = DefaultScreen ( gdi_display ) ;
Window win = RootWindow ( gdi_display , screen ) ;
2009-05-26 00:52:05 +02:00
const char * str ;
2006-09-11 21:28:32 +02:00
Visual * visual ;
XVisualInfo template ;
XVisualInfo * vis ;
int num ;
GLXContext ctx = NULL ;
if ( infoInitialized )
return TRUE ;
infoInitialized = TRUE ;
wine_tsx11_lock ( ) ;
visual = DefaultVisual ( gdi_display , screen ) ;
template . visualid = XVisualIDFromVisual ( visual ) ;
vis = XGetVisualInfo ( gdi_display , VisualIDMask , & template , & num ) ;
if ( vis ) {
2007-02-14 18:18:07 +01:00
WORD old_fs = wine_get_fs ( ) ;
2006-09-11 21:28:32 +02:00
/* Create a GLX Context. Without one we can't query GL information */
ctx = pglXCreateContext ( gdi_display , vis , None , GL_TRUE ) ;
2007-02-14 18:18:07 +01:00
if ( wine_get_fs ( ) ! = old_fs )
{
wine_set_fs ( old_fs ) ;
wine_tsx11_unlock ( ) ;
ERR ( " %%fs register corrupted, probably broken ATI driver, disabling OpenGL. \n " ) ;
ERR ( " You need to set the \" UseFastTls \" option to \" 2 \" in your X config file. \n " ) ;
return FALSE ;
}
2006-09-11 21:28:32 +02:00
}
if ( ctx ) {
pglXMakeCurrent ( gdi_display , win , ctx ) ;
} else {
ERR ( " couldn't initialize OpenGL, expect problems \n " ) ;
2006-09-29 02:02:42 +02:00
wine_tsx11_unlock ( ) ;
2006-09-11 21:28:32 +02:00
return FALSE ;
}
WineGLInfo . glVersion = ( const char * ) pglGetString ( GL_VERSION ) ;
2009-05-26 00:52:05 +02:00
str = ( const char * ) pglGetString ( GL_EXTENSIONS ) ;
WineGLInfo . glExtensions = HeapAlloc ( GetProcessHeap ( ) , 0 , strlen ( str ) + 1 ) ;
strcpy ( WineGLInfo . glExtensions , str ) ;
2006-09-11 21:28:32 +02:00
/* Get the common GLX version supported by GLX client and server ( major/minor) */
pglXQueryVersion ( gdi_display , & WineGLInfo . glxVersion [ 0 ] , & WineGLInfo . glxVersion [ 1 ] ) ;
WineGLInfo . glxServerVersion = pglXQueryServerString ( gdi_display , screen , GLX_VERSION ) ;
2007-08-08 16:40:34 +02:00
WineGLInfo . glxServerVendor = pglXQueryServerString ( gdi_display , screen , GLX_VENDOR ) ;
2006-09-11 21:28:32 +02:00
WineGLInfo . glxServerExtensions = pglXQueryServerString ( gdi_display , screen , GLX_EXTENSIONS ) ;
WineGLInfo . glxClientVersion = pglXGetClientString ( gdi_display , GLX_VERSION ) ;
2007-08-08 16:40:34 +02:00
WineGLInfo . glxClientVendor = pglXGetClientString ( gdi_display , GLX_VENDOR ) ;
2006-09-11 21:28:32 +02:00
WineGLInfo . glxClientExtensions = pglXGetClientString ( gdi_display , GLX_EXTENSIONS ) ;
WineGLInfo . glxExtensions = pglXQueryExtensionsString ( gdi_display , screen ) ;
WineGLInfo . glxDirect = pglXIsDirect ( gdi_display , ctx ) ;
TRACE ( " GL version : %s. \n " , WineGLInfo . glVersion ) ;
2007-08-01 16:22:54 +02:00
TRACE ( " GL renderer : %s. \n " , pglGetString ( GL_RENDERER ) ) ;
2006-09-11 21:28:32 +02:00
TRACE ( " GLX version : %d.%d. \n " , WineGLInfo . glxVersion [ 0 ] , WineGLInfo . glxVersion [ 1 ] ) ;
TRACE ( " Server GLX version : %s. \n " , WineGLInfo . glxServerVersion ) ;
2007-08-08 16:40:34 +02:00
TRACE ( " Server GLX vendor: : %s. \n " , WineGLInfo . glxServerVendor ) ;
2006-09-11 21:28:32 +02:00
TRACE ( " Client GLX version : %s. \n " , WineGLInfo . glxClientVersion ) ;
2007-08-08 16:40:34 +02:00
TRACE ( " Client GLX vendor: : %s. \n " , WineGLInfo . glxClientVendor ) ;
2006-09-11 21:28:32 +02:00
TRACE ( " Direct rendering enabled: %s \n " , WineGLInfo . glxDirect ? " True " : " False " ) ;
if ( vis ) XFree ( vis ) ;
2006-09-18 20:13:21 +02:00
if ( ctx ) {
pglXMakeCurrent ( gdi_display , None , NULL ) ;
pglXDestroyContext ( gdi_display , ctx ) ;
}
2006-09-29 02:02:42 +02:00
wine_tsx11_unlock ( ) ;
2006-09-11 21:28:32 +02:00
return TRUE ;
}
2009-05-26 00:52:05 +02:00
void X11DRV_OpenGL_Cleanup ( void )
{
HeapFree ( GetProcessHeap ( ) , 0 , WineGLInfo . glExtensions ) ;
infoInitialized = FALSE ;
}
2005-06-29 21:28:06 +02:00
static BOOL has_opengl ( void )
{
static int init_done ;
static void * opengl_handle ;
2008-06-23 22:56:10 +02:00
char buffer [ 200 ] ;
2002-11-15 05:16:38 +01:00
int error_base , event_base ;
2005-06-29 21:28:06 +02:00
if ( init_done ) return ( opengl_handle ! = NULL ) ;
init_done = 1 ;
2007-07-04 12:44:12 +02:00
/* No need to load any other libraries as according to the ABI, libGL should be self-sufficient
and include all dependencies */
2008-06-23 22:56:10 +02:00
opengl_handle = wine_dlopen ( SONAME_LIBGL , RTLD_NOW | RTLD_GLOBAL , buffer , sizeof ( buffer ) ) ;
if ( opengl_handle = = NULL )
{
ERR ( " Failed to load libGL: %s \n " , buffer ) ;
ERR ( " OpenGL support is disabled. \n " ) ;
2006-09-11 21:28:32 +02:00
return FALSE ;
}
2008-06-23 22:56:10 +02:00
pglXGetProcAddressARB = wine_dlsym ( opengl_handle , " glXGetProcAddressARB " , NULL , 0 ) ;
if ( pglXGetProcAddressARB = = NULL ) {
ERR ( " Could not find glXGetProcAddressARB in libGL, disabling OpenGL. \n " ) ;
goto failed ;
}
# define LOAD_FUNCPTR(f) do if((p##f = (void*)pglXGetProcAddressARB((const unsigned char*)#f)) == NULL) \
{ \
ERR ( " %s not found in libGL, disabling OpenGL. \n " , # f ) ; \
goto failed ; \
} while ( 0 )
/* GLX 1.0 */
LOAD_FUNCPTR ( glXChooseVisual ) ;
LOAD_FUNCPTR ( glXCopyContext ) ;
LOAD_FUNCPTR ( glXCreateContext ) ;
LOAD_FUNCPTR ( glXCreateGLXPixmap ) ;
LOAD_FUNCPTR ( glXGetCurrentContext ) ;
LOAD_FUNCPTR ( glXGetCurrentDrawable ) ;
LOAD_FUNCPTR ( glXDestroyContext ) ;
LOAD_FUNCPTR ( glXDestroyGLXPixmap ) ;
LOAD_FUNCPTR ( glXGetConfig ) ;
LOAD_FUNCPTR ( glXIsDirect ) ;
LOAD_FUNCPTR ( glXMakeCurrent ) ;
LOAD_FUNCPTR ( glXSwapBuffers ) ;
LOAD_FUNCPTR ( glXQueryExtension ) ;
LOAD_FUNCPTR ( glXQueryVersion ) ;
LOAD_FUNCPTR ( glXUseXFont ) ;
/* GLX 1.1 */
LOAD_FUNCPTR ( glXGetClientString ) ;
LOAD_FUNCPTR ( glXQueryExtensionsString ) ;
LOAD_FUNCPTR ( glXQueryServerString ) ;
/* GLX 1.3 */
LOAD_FUNCPTR ( glXCreatePbuffer ) ;
LOAD_FUNCPTR ( glXCreateNewContext ) ;
LOAD_FUNCPTR ( glXDestroyPbuffer ) ;
LOAD_FUNCPTR ( glXMakeContextCurrent ) ;
LOAD_FUNCPTR ( glXGetCurrentReadDrawable ) ;
LOAD_FUNCPTR ( glXGetFBConfigs ) ;
/* Standard OpenGL calls */
LOAD_FUNCPTR ( glBindTexture ) ;
LOAD_FUNCPTR ( glBitmap ) ;
LOAD_FUNCPTR ( glCopyTexSubImage1D ) ;
LOAD_FUNCPTR ( glCopyTexImage2D ) ;
LOAD_FUNCPTR ( glCopyTexSubImage2D ) ;
LOAD_FUNCPTR ( glDrawBuffer ) ;
LOAD_FUNCPTR ( glEndList ) ;
LOAD_FUNCPTR ( glGetError ) ;
LOAD_FUNCPTR ( glGetIntegerv ) ;
LOAD_FUNCPTR ( glGetString ) ;
LOAD_FUNCPTR ( glNewList ) ;
LOAD_FUNCPTR ( glPixelStorei ) ;
LOAD_FUNCPTR ( glReadPixels ) ;
LOAD_FUNCPTR ( glTexImage2D ) ;
LOAD_FUNCPTR ( glFinish ) ;
LOAD_FUNCPTR ( glFlush ) ;
2006-12-06 06:30:36 +01:00
# undef LOAD_FUNCPTR
/* It doesn't matter if these fail. They'll only be used if the driver reports
the associated extension is available ( and if a driver reports the extension
is available but fails to provide the functions , it ' s quite broken ) */
2008-06-23 22:56:10 +02:00
# define LOAD_FUNCPTR(f) p##f = (void*)pglXGetProcAddressARB((const unsigned char*)#f)
/* NV GLX Extension */
LOAD_FUNCPTR ( glXAllocateMemoryNV ) ;
LOAD_FUNCPTR ( glXFreeMemoryNV ) ;
2002-11-15 05:16:38 +01:00
# undef LOAD_FUNCPTR
2008-06-23 22:56:10 +02:00
if ( ! X11DRV_WineGL_InitOpenglInfo ( ) ) goto failed ;
2006-09-11 21:28:32 +02:00
2002-11-15 05:16:38 +01:00
wine_tsx11_lock ( ) ;
2008-06-23 22:56:10 +02:00
if ( pglXQueryExtension ( gdi_display , & error_base , & event_base ) ) {
2006-08-29 16:58:49 +02:00
TRACE ( " GLX is up and running error_base = %d \n " , error_base ) ;
2002-11-15 05:16:38 +01:00
} else {
2008-06-23 22:56:10 +02:00
wine_tsx11_unlock ( ) ;
ERR ( " GLX extension is missing, disabling OpenGL. \n " ) ;
goto failed ;
2002-11-15 05:16:38 +01:00
}
2006-08-29 16:58:49 +02:00
2006-09-11 21:28:32 +02:00
/* In case of GLX you have direct and indirect rendering. Most of the time direct rendering is used
* as in general only that is hardware accelerated . In some cases like in case of remote X indirect
* rendering is used .
*
* The main problem for our OpenGL code is that we need certain GLX calls but their presence
* depends on the reported GLX client / server version and on the client / server extension list .
* Those don ' t have to be the same .
*
2007-08-08 16:40:34 +02:00
* In general the server GLX information lists the capabilities in case of indirect rendering .
* When direct rendering is used , the OpenGL client library is responsible for which GLX calls are
* available and in that case the client GLX informat can be used .
* OpenGL programs should use the ' intersection ' of both sets of information which is advertised
* in the GLX version / extension list . When a program does this it works for certain for both
* direct and indirect rendering .
2006-09-11 21:28:32 +02:00
*
2007-08-08 16:40:34 +02:00
* The problem we are having in this area is that ATI ' s Linux drivers are broken . For some reason
* they haven ' t added some very important GLX extensions like GLX_SGIX_fbconfig to their client
* extension list which causes this extension not to be listed . ( Wine requires this extension ) .
* ATI advertises a GLX client version of 1.3 which implies that this fbconfig extension among
* pbuffers is around .
*
* In order to provide users of Ati ' s proprietary drivers with OpenGL support , we need to detect
* the ATI drivers and from then on use GLX client information for them .
2006-09-11 21:28:32 +02:00
*/
2007-08-08 16:40:34 +02:00
if ( glxRequireVersion ( 3 ) ) {
2008-02-02 18:27:19 +01:00
pglXChooseFBConfig = pglXGetProcAddressARB ( ( const GLubyte * ) " glXChooseFBConfig " ) ;
pglXGetFBConfigAttrib = pglXGetProcAddressARB ( ( const GLubyte * ) " glXGetFBConfigAttrib " ) ;
pglXGetVisualFromFBConfig = pglXGetProcAddressARB ( ( const GLubyte * ) " glXGetVisualFromFBConfig " ) ;
pglXQueryDrawable = pglXGetProcAddressARB ( ( const GLubyte * ) " glXQueryDrawable " ) ;
2007-08-08 16:40:34 +02:00
} else if ( glxRequireExtension ( " GLX_SGIX_fbconfig " ) ) {
2008-02-02 18:27:19 +01:00
pglXChooseFBConfig = pglXGetProcAddressARB ( ( const GLubyte * ) " glXChooseFBConfigSGIX " ) ;
pglXGetFBConfigAttrib = pglXGetProcAddressARB ( ( const GLubyte * ) " glXGetFBConfigAttribSGIX " ) ;
pglXGetVisualFromFBConfig = pglXGetProcAddressARB ( ( const GLubyte * ) " glXGetVisualFromFBConfigSGIX " ) ;
2007-08-08 16:40:34 +02:00
/* The mesa libGL client library seems to forward glXQueryDrawable to the Xserver, so only
* enable this function when the Xserver understand GLX 1.3 or newer
*/
2006-08-29 16:58:49 +02:00
pglXQueryDrawable = NULL ;
2007-08-08 16:40:34 +02:00
} else if ( strcmp ( " ATI " , WineGLInfo . glxClientVendor ) = = 0 ) {
TRACE ( " Overriding ATI GLX capabilities! \n " ) ;
2008-02-02 18:27:19 +01:00
pglXChooseFBConfig = pglXGetProcAddressARB ( ( const GLubyte * ) " glXChooseFBConfig " ) ;
pglXGetFBConfigAttrib = pglXGetProcAddressARB ( ( const GLubyte * ) " glXGetFBConfigAttrib " ) ;
pglXGetVisualFromFBConfig = pglXGetProcAddressARB ( ( const GLubyte * ) " glXGetVisualFromFBConfig " ) ;
pglXQueryDrawable = pglXGetProcAddressARB ( ( const GLubyte * ) " glXQueryDrawable " ) ;
2007-08-08 16:40:34 +02:00
/* Use client GLX information in case of the ATI drivers. We override the
* capabilities over here and not somewhere else as ATI might better their
* life in the future . In case they release proper drivers this block of
* code won ' t be called . */
WineGLInfo . glxExtensions = WineGLInfo . glxClientExtensions ;
} else {
ERR ( " glx_version is %s and GLX_SGIX_fbconfig extension is unsupported. Expect problems. \n " , WineGLInfo . glxServerVersion ) ;
}
2006-08-29 16:58:49 +02:00
2007-08-08 16:40:34 +02:00
if ( glxRequireExtension ( " GLX_ATI_render_texture " ) ) {
2007-08-17 11:16:29 +02:00
use_render_texture_ati = 1 ;
2008-02-02 18:27:19 +01:00
pglXBindTexImageATI = pglXGetProcAddressARB ( ( const GLubyte * ) " glXBindTexImageATI " ) ;
pglXReleaseTexImageATI = pglXGetProcAddressARB ( ( const GLubyte * ) " glXReleaseTexImageATI " ) ;
pglXDrawableAttribATI = pglXGetProcAddressARB ( ( const GLubyte * ) " glXDrawableAttribATI " ) ;
2006-09-11 21:28:32 +02:00
}
2007-09-26 20:01:07 +02:00
if ( glxRequireExtension ( " GLX_MESA_copy_sub_buffer " ) ) {
2008-02-02 18:27:19 +01:00
pglXCopySubBufferMESA = pglXGetProcAddressARB ( ( const GLubyte * ) " glXCopySubBufferMESA " ) ;
2007-09-26 20:01:07 +02:00
}
2006-09-11 21:28:32 +02:00
X11DRV_WineGL_LoadExtensions ( ) ;
2002-11-15 05:16:38 +01:00
wine_tsx11_unlock ( ) ;
2008-06-23 22:56:10 +02:00
return TRUE ;
2002-11-15 05:16:38 +01:00
2008-06-23 22:56:10 +02:00
failed :
2002-11-15 05:16:38 +01:00
wine_dlclose ( opengl_handle , NULL , 0 ) ;
opengl_handle = NULL ;
2005-06-29 21:28:06 +02:00
return FALSE ;
2002-11-15 05:16:38 +01:00
}
2006-08-29 16:56:57 +02:00
static inline Wine_GLContext * alloc_context ( void )
{
Wine_GLContext * ret ;
if ( ( ret = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , sizeof ( Wine_GLContext ) ) ) )
{
ret - > next = context_list ;
if ( context_list ) context_list - > prev = ret ;
context_list = ret ;
}
return ret ;
}
static inline void free_context ( Wine_GLContext * context )
{
if ( context - > next ! = NULL ) context - > next - > prev = context - > prev ;
if ( context - > prev ! = NULL ) context - > prev - > next = context - > next ;
else context_list = context - > next ;
2007-09-11 22:52:23 +02:00
if ( context - > vis ) XFree ( context - > vis ) ;
2006-08-29 16:56:57 +02:00
HeapFree ( GetProcessHeap ( ) , 0 , context ) ;
}
2007-03-17 11:47:28 +01:00
static inline BOOL is_valid_context ( Wine_GLContext * ctx )
2006-08-29 16:56:57 +02:00
{
Wine_GLContext * ptr ;
for ( ptr = context_list ; ptr ; ptr = ptr - > next ) if ( ptr = = ctx ) break ;
return ( ptr ! = NULL ) ;
}
2006-08-29 16:58:49 +02:00
static int describeContext ( Wine_GLContext * ctx ) {
int tmp ;
int ctx_vis_id ;
TRACE ( " Context %p have (vis:%p): \n " , ctx , ctx - > vis ) ;
2007-07-28 18:56:12 +02:00
pglXGetFBConfigAttrib ( gdi_display , ctx - > fmt - > fbconfig , GLX_FBCONFIG_ID , & tmp ) ;
2006-08-29 16:58:49 +02:00
TRACE ( " - FBCONFIG_ID 0x%x \n " , tmp ) ;
2007-07-28 18:56:12 +02:00
pglXGetFBConfigAttrib ( gdi_display , ctx - > fmt - > fbconfig , GLX_VISUAL_ID , & tmp ) ;
2006-08-29 16:58:49 +02:00
TRACE ( " - VISUAL_ID 0x%x \n " , tmp ) ;
ctx_vis_id = tmp ;
return ctx_vis_id ;
}
static int describeDrawable ( Wine_GLContext * ctx , Drawable drawable ) {
int tmp ;
int nElements ;
int attribList [ 3 ] = { GLX_FBCONFIG_ID , 0 , None } ;
GLXFBConfig * fbCfgs ;
if ( pglXQueryDrawable = = NULL ) {
/** glXQueryDrawable not available so returns not supported */
return - 1 ;
}
TRACE ( " Drawable %p have : \n " , ( void * ) drawable ) ;
2006-12-12 18:23:34 +01:00
pglXQueryDrawable ( gdi_display , drawable , GLX_WIDTH , ( unsigned int * ) & tmp ) ;
2006-08-29 16:58:49 +02:00
TRACE ( " - WIDTH as %d \n " , tmp ) ;
2006-12-12 18:23:34 +01:00
pglXQueryDrawable ( gdi_display , drawable , GLX_HEIGHT , ( unsigned int * ) & tmp ) ;
2006-08-29 16:58:49 +02:00
TRACE ( " - HEIGHT as %d \n " , tmp ) ;
2006-12-12 18:23:34 +01:00
pglXQueryDrawable ( gdi_display , drawable , GLX_FBCONFIG_ID , ( unsigned int * ) & tmp ) ;
2006-08-29 16:58:49 +02:00
TRACE ( " - FBCONFIG_ID as 0x%x \n " , tmp ) ;
attribList [ 1 ] = tmp ;
2006-12-12 18:23:34 +01:00
fbCfgs = pglXChooseFBConfig ( gdi_display , DefaultScreen ( gdi_display ) , attribList , & nElements ) ;
2006-08-29 16:58:49 +02:00
if ( fbCfgs = = NULL ) {
return - 1 ;
}
2006-12-12 18:23:34 +01:00
pglXGetFBConfigAttrib ( gdi_display , fbCfgs [ 0 ] , GLX_VISUAL_ID , & tmp ) ;
2006-08-29 16:58:49 +02:00
TRACE ( " - VISUAL_ID as 0x%x \n " , tmp ) ;
XFree ( fbCfgs ) ;
return tmp ;
}
2006-09-11 21:28:32 +02:00
static int ConvertAttribWGLtoGLX ( const int * iWGLAttr , int * oGLXAttr , Wine_GLPBuffer * pbuf ) {
int nAttribs = 0 ;
unsigned cur = 0 ;
int pop ;
2006-12-10 09:00:47 +01:00
int drawattrib = 0 ;
2007-08-01 23:20:54 +02:00
int nvfloatattrib = GLX_DONT_CARE ;
int pixelattrib = 0 ;
2006-09-11 21:28:32 +02:00
2007-08-01 23:20:54 +02:00
/* The list of WGL attributes is allowed to be NULL. We don't return here for NULL
* because we need to do fixups for GLX_DRAWABLE_TYPE / GLX_RENDER_TYPE / GLX_FLOAT_COMPONENTS_NV . */
while ( iWGLAttr & & 0 ! = iWGLAttr [ cur ] ) {
2006-09-11 21:28:32 +02:00
TRACE ( " pAttr[%d] = %x \n " , cur , iWGLAttr [ cur ] ) ;
switch ( iWGLAttr [ cur ] ) {
2008-03-03 23:45:25 +01:00
case WGL_AUX_BUFFERS_ARB :
pop = iWGLAttr [ + + cur ] ;
PUSH2 ( oGLXAttr , GLX_AUX_BUFFERS , pop ) ;
TRACE ( " pAttr[%d] = GLX_AUX_BUFFERS: %d \n " , cur , pop ) ;
break ;
2006-09-11 21:28:32 +02:00
case WGL_COLOR_BITS_ARB :
pop = iWGLAttr [ + + cur ] ;
2007-08-03 04:03:12 +02:00
PUSH2 ( oGLXAttr , GLX_BUFFER_SIZE , pop ) ;
TRACE ( " pAttr[%d] = GLX_BUFFER_SIZE: %d \n " , cur , pop ) ;
2006-09-11 21:28:32 +02:00
break ;
case WGL_BLUE_BITS_ARB :
pop = iWGLAttr [ + + cur ] ;
PUSH2 ( oGLXAttr , GLX_BLUE_SIZE , pop ) ;
TRACE ( " pAttr[%d] = GLX_BLUE_SIZE: %d \n " , cur , pop ) ;
break ;
case WGL_RED_BITS_ARB :
pop = iWGLAttr [ + + cur ] ;
PUSH2 ( oGLXAttr , GLX_RED_SIZE , pop ) ;
TRACE ( " pAttr[%d] = GLX_RED_SIZE: %d \n " , cur , pop ) ;
break ;
case WGL_GREEN_BITS_ARB :
pop = iWGLAttr [ + + cur ] ;
PUSH2 ( oGLXAttr , GLX_GREEN_SIZE , pop ) ;
TRACE ( " pAttr[%d] = GLX_GREEN_SIZE: %d \n " , cur , pop ) ;
break ;
case WGL_ALPHA_BITS_ARB :
pop = iWGLAttr [ + + cur ] ;
PUSH2 ( oGLXAttr , GLX_ALPHA_SIZE , pop ) ;
TRACE ( " pAttr[%d] = GLX_ALPHA_SIZE: %d \n " , cur , pop ) ;
break ;
case WGL_DEPTH_BITS_ARB :
pop = iWGLAttr [ + + cur ] ;
PUSH2 ( oGLXAttr , GLX_DEPTH_SIZE , pop ) ;
TRACE ( " pAttr[%d] = GLX_DEPTH_SIZE: %d \n " , cur , pop ) ;
break ;
case WGL_STENCIL_BITS_ARB :
pop = iWGLAttr [ + + cur ] ;
PUSH2 ( oGLXAttr , GLX_STENCIL_SIZE , pop ) ;
TRACE ( " pAttr[%d] = GLX_STENCIL_SIZE: %d \n " , cur , pop ) ;
break ;
case WGL_DOUBLE_BUFFER_ARB :
pop = iWGLAttr [ + + cur ] ;
PUSH2 ( oGLXAttr , GLX_DOUBLEBUFFER , pop ) ;
TRACE ( " pAttr[%d] = GLX_DOUBLEBUFFER: %d \n " , cur , pop ) ;
break ;
2008-04-01 00:59:11 +02:00
case WGL_STEREO_ARB :
pop = iWGLAttr [ + + cur ] ;
PUSH2 ( oGLXAttr , GLX_STEREO , pop ) ;
TRACE ( " pAttr[%d] = GLX_STEREO: %d \n " , cur , pop ) ;
break ;
2006-09-11 21:28:32 +02:00
case WGL_PIXEL_TYPE_ARB :
pop = iWGLAttr [ + + cur ] ;
2007-08-01 23:20:54 +02:00
TRACE ( " pAttr[%d] = WGL_PIXEL_TYPE_ARB: %d \n " , cur , pop ) ;
2006-09-11 21:28:32 +02:00
switch ( pop ) {
2007-08-03 04:03:12 +02:00
case WGL_TYPE_COLORINDEX_ARB : pixelattrib = GLX_COLOR_INDEX_BIT ; break ;
2007-08-01 23:20:54 +02:00
case WGL_TYPE_RGBA_ARB : pixelattrib = GLX_RGBA_BIT ; break ;
2007-07-28 18:56:12 +02:00
/* This is the same as WGL_TYPE_RGBA_FLOAT_ATI but the GLX constants differ, only the ARB GLX one is widely supported so use that */
2007-08-01 23:20:54 +02:00
case WGL_TYPE_RGBA_FLOAT_ATI : pixelattrib = GLX_RGBA_FLOAT_BIT ; break ;
2009-04-20 22:57:19 +02:00
case WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT : pixelattrib = GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT ; break ;
2006-09-11 21:28:32 +02:00
default :
ERR ( " unexpected PixelType(%x) \n " , pop ) ;
pop = 0 ;
}
break ;
case WGL_SUPPORT_GDI_ARB :
2009-05-16 21:50:58 +02:00
/* This flag is set in a WineGLPixelFormat */
2006-09-11 21:28:32 +02:00
pop = iWGLAttr [ + + cur ] ;
2006-11-30 23:55:08 +01:00
TRACE ( " pAttr[%d] = WGL_SUPPORT_GDI_ARB: %d \n " , cur , pop ) ;
2006-09-11 21:28:32 +02:00
break ;
case WGL_DRAW_TO_BITMAP_ARB :
2009-05-17 21:50:56 +02:00
/* This flag is set in a WineGLPixelFormat */
2006-09-11 21:28:32 +02:00
pop = iWGLAttr [ + + cur ] ;
2006-11-30 23:55:08 +01:00
TRACE ( " pAttr[%d] = WGL_DRAW_TO_BITMAP_ARB: %d \n " , cur , pop ) ;
2006-09-11 21:28:32 +02:00
break ;
case WGL_DRAW_TO_WINDOW_ARB :
pop = iWGLAttr [ + + cur ] ;
2006-12-10 09:00:47 +01:00
TRACE ( " pAttr[%d] = WGL_DRAW_TO_WINDOW_ARB: %d \n " , cur , pop ) ;
/* GLX_DRAWABLE_TYPE flags need to be OR'd together. See below. */
2006-09-11 21:28:32 +02:00
if ( pop ) {
2006-12-10 09:00:47 +01:00
drawattrib | = GLX_WINDOW_BIT ;
2006-09-11 21:28:32 +02:00
}
break ;
case WGL_DRAW_TO_PBUFFER_ARB :
pop = iWGLAttr [ + + cur ] ;
2006-12-10 09:00:47 +01:00
TRACE ( " pAttr[%d] = WGL_DRAW_TO_PBUFFER_ARB: %d \n " , cur , pop ) ;
/* GLX_DRAWABLE_TYPE flags need to be OR'd together. See below. */
2006-09-11 21:28:32 +02:00
if ( pop ) {
2006-12-10 09:00:47 +01:00
drawattrib | = GLX_PBUFFER_BIT ;
2006-09-11 21:28:32 +02:00
}
break ;
case WGL_ACCELERATION_ARB :
2009-05-19 00:23:05 +02:00
/* This flag is set in a WineGLPixelFormat */
pop = iWGLAttr [ + + cur ] ;
TRACE ( " pAttr[%d] = WGL_ACCELERATION_ARB: %d \n " , cur , pop ) ;
break ;
2006-09-11 21:28:32 +02:00
case WGL_SUPPORT_OPENGL_ARB :
pop = iWGLAttr [ + + cur ] ;
/** nothing to do, if we are here, supposing support Accelerated OpenGL */
TRACE ( " pAttr[%d] = WGL_SUPPORT_OPENGL_ARB: %d \n " , cur , pop ) ;
break ;
2009-05-16 00:00:24 +02:00
case WGL_SWAP_METHOD_ARB :
pop = iWGLAttr [ + + cur ] ;
/* For now we ignore this and just return SWAP_EXCHANGE */
TRACE ( " pAttr[%d] = WGL_SWAP_METHOD_ARB: %#x \n " , cur , pop ) ;
break ;
2006-09-11 21:28:32 +02:00
case WGL_PBUFFER_LARGEST_ARB :
pop = iWGLAttr [ + + cur ] ;
PUSH2 ( oGLXAttr , GLX_LARGEST_PBUFFER , pop ) ;
TRACE ( " pAttr[%d] = GLX_LARGEST_PBUFFER: %x \n " , cur , pop ) ;
break ;
case WGL_SAMPLE_BUFFERS_ARB :
pop = iWGLAttr [ + + cur ] ;
PUSH2 ( oGLXAttr , GLX_SAMPLE_BUFFERS_ARB , pop ) ;
TRACE ( " pAttr[%d] = GLX_SAMPLE_BUFFERS_ARB: %x \n " , cur , pop ) ;
break ;
case WGL_SAMPLES_ARB :
pop = iWGLAttr [ + + cur ] ;
PUSH2 ( oGLXAttr , GLX_SAMPLES_ARB , pop ) ;
TRACE ( " pAttr[%d] = GLX_SAMPLES_ARB: %x \n " , cur , pop ) ;
break ;
case WGL_TEXTURE_FORMAT_ARB :
case WGL_TEXTURE_TARGET_ARB :
case WGL_MIPMAP_TEXTURE_ARB :
TRACE ( " WGL_render_texture Attributes: %x as %x \n " , iWGLAttr [ cur ] , iWGLAttr [ cur + 1 ] ) ;
pop = iWGLAttr [ + + cur ] ;
if ( NULL = = pbuf ) {
ERR ( " trying to use GLX_Pbuffer Attributes without Pbuffer (was %x) \n " , iWGLAttr [ cur ] ) ;
}
if ( use_render_texture_ati ) {
/** nothing to do here */
}
else if ( ! use_render_texture_emulation ) {
if ( WGL_NO_TEXTURE_ARB ! = pop ) {
ERR ( " trying to use WGL_render_texture Attributes without support (was %x) \n " , iWGLAttr [ cur ] ) ;
return - 1 ; /** error: don't support it */
} else {
PUSH2 ( oGLXAttr , GLX_X_RENDERABLE , pop ) ;
2006-12-10 09:00:47 +01:00
drawattrib | = GLX_PBUFFER_BIT ;
2006-09-11 21:28:32 +02:00
}
}
break ;
2007-07-27 15:01:52 +02:00
case WGL_FLOAT_COMPONENTS_NV :
2007-08-01 23:20:54 +02:00
nvfloatattrib = iWGLAttr [ + + cur ] ;
TRACE ( " pAttr[%d] = WGL_FLOAT_COMPONENTS_NV: %x \n " , cur , nvfloatattrib ) ;
2007-07-27 15:01:52 +02:00
break ;
2008-02-05 23:09:09 +01:00
case WGL_BIND_TO_TEXTURE_DEPTH_NV :
2006-09-11 21:28:32 +02:00
case WGL_BIND_TO_TEXTURE_RGB_ARB :
case WGL_BIND_TO_TEXTURE_RGBA_ARB :
2007-07-27 15:01:52 +02:00
case WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV :
case WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV :
case WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV :
case WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV :
2006-09-11 21:28:32 +02:00
pop = iWGLAttr [ + + cur ] ;
/** cannot be converted, see direct handling on
* - wglGetPixelFormatAttribivARB
* TODO : wglChoosePixelFormat
*/
break ;
2008-04-30 00:42:09 +02:00
case WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT :
pop = iWGLAttr [ + + cur ] ;
PUSH2 ( oGLXAttr , GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT , pop ) ;
TRACE ( " pAttr[%d] = GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT: %x \n " , cur , pop ) ;
break ;
2006-09-11 21:28:32 +02:00
2009-04-20 22:57:19 +02:00
case WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT :
pop = iWGLAttr [ + + cur ] ;
PUSH2 ( oGLXAttr , GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT , pop ) ;
TRACE ( " pAttr[%d] = GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT: %x \n " , cur , pop ) ;
break ;
2006-09-11 21:28:32 +02:00
default :
FIXME ( " unsupported %x WGL Attribute \n " , iWGLAttr [ cur ] ) ;
break ;
}
+ + cur ;
}
2007-08-01 23:20:54 +02:00
/* Apply the OR'd drawable type bitmask now EVEN when WGL_DRAW_TO* is unset.
* It is needed in all cases because GLX_DRAWABLE_TYPE default to GLX_WINDOW_BIT . */
PUSH2 ( oGLXAttr , GLX_DRAWABLE_TYPE , drawattrib ) ;
TRACE ( " pAttr[?] = GLX_DRAWABLE_TYPE: %#x \n " , drawattrib ) ;
/* Set GLX_RENDER_TYPE all the time */
PUSH2 ( oGLXAttr , GLX_RENDER_TYPE , pixelattrib ) ;
TRACE ( " pAttr[?] = GLX_RENDER_TYPE: %#x \n " , pixelattrib ) ;
/* Set GLX_FLOAT_COMPONENTS_NV all the time */
if ( strstr ( WineGLInfo . glxExtensions , " GLX_NV_float_buffer " ) ) {
PUSH2 ( oGLXAttr , GLX_FLOAT_COMPONENTS_NV , nvfloatattrib ) ;
TRACE ( " pAttr[?] = GLX_FLOAT_COMPONENTS_NV: %#x \n " , nvfloatattrib ) ;
2006-12-10 09:00:47 +01:00
}
2006-09-11 21:28:32 +02:00
return nAttribs ;
}
2007-07-28 18:56:12 +02:00
static int get_render_type_from_fbconfig ( Display * display , GLXFBConfig fbconfig )
{
int render_type = 0 , render_type_bit ;
pglXGetFBConfigAttrib ( display , fbconfig , GLX_RENDER_TYPE , & render_type_bit ) ;
switch ( render_type_bit )
{
case GLX_RGBA_BIT :
render_type = GLX_RGBA_TYPE ;
break ;
case GLX_COLOR_INDEX_BIT :
render_type = GLX_COLOR_INDEX_TYPE ;
break ;
2007-07-30 23:19:57 +02:00
case GLX_RGBA_FLOAT_BIT :
render_type = GLX_RGBA_FLOAT_TYPE ;
2007-07-28 18:56:12 +02:00
break ;
2009-04-20 22:57:19 +02:00
case GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT :
render_type = GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT ;
break ;
2007-07-28 18:56:12 +02:00
default :
ERR ( " Unknown render_type: %x \n " , render_type ) ;
}
return render_type ;
}
2009-05-14 17:05:20 +02:00
/* Check whether a fbconfig is suitable for Windows-style bitmap rendering */
static BOOL check_fbconfig_bitmap_capability ( Display * display , GLXFBConfig fbconfig )
{
int dbuf , value ;
pglXGetFBConfigAttrib ( display , fbconfig , GLX_DOUBLEBUFFER , & dbuf ) ;
pglXGetFBConfigAttrib ( gdi_display , fbconfig , GLX_DRAWABLE_TYPE , & value ) ;
/* Windows only supports bitmap rendering on single buffered formats, further the fbconfig needs to have
* the GLX_PIXMAP_BIT set . */
return ! dbuf & & ( value & GLX_PIXMAP_BIT ) ;
}
2008-05-28 16:57:46 +02:00
static WineGLPixelFormat * get_formats ( Display * display , int * size_ret , int * onscreen_size_ret )
2006-11-18 23:29:48 +01:00
{
2008-05-28 16:57:46 +02:00
static WineGLPixelFormat * list ;
static int size , onscreen_size ;
2009-05-14 17:05:20 +02:00
int fmt_id , nCfgs , i , run , bmp_formats ;
2007-08-20 15:48:11 +02:00
GLXFBConfig * cfgs ;
2007-09-13 01:04:30 +02:00
XVisualInfo * visinfo ;
2006-11-18 23:29:48 +01:00
2008-05-28 16:57:46 +02:00
wine_tsx11_lock ( ) ;
if ( list ) goto done ;
2006-11-18 23:29:48 +01:00
cfgs = pglXGetFBConfigs ( display , DefaultScreen ( display ) , & nCfgs ) ;
if ( NULL = = cfgs | | 0 = = nCfgs ) {
if ( cfgs ! = NULL ) XFree ( cfgs ) ;
2008-05-28 16:57:46 +02:00
wine_tsx11_unlock ( ) ;
ERR ( " glXChooseFBConfig returns NULL \n " ) ;
return NULL ;
2006-11-18 23:29:48 +01:00
}
2009-05-14 17:05:20 +02:00
/* Bitmap rendering on Windows implies the use of the Microsoft GDI software renderer.
* Further most GLX drivers only offer pixmap rendering using indirect rendering ( except for modern drivers which support ' AIGLX ' / composite ) .
* Indirect rendering can indicate software rendering ( on Nvidia it is hw accelerated )
* Since bitmap rendering implies the use of software rendering we can safely use indirect rendering for bitmaps .
*
* Below we count the number of formats which are suitable for bitmap rendering . Windows restricts bitmap rendering to single buffered formats .
*/
for ( i = 0 , bmp_formats = 0 ; i < nCfgs ; i + + )
{
if ( check_fbconfig_bitmap_capability ( display , cfgs [ i ] ) )
bmp_formats + + ;
}
TRACE ( " Found %d bitmap capable fbconfigs \n " , bmp_formats ) ;
list = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , ( nCfgs + bmp_formats ) * sizeof ( WineGLPixelFormat ) ) ;
2006-11-18 23:29:48 +01:00
2008-02-22 21:40:00 +01:00
/* Fill the pixel format list. Put onscreen formats at the top and offscreen ones at the bottom.
* Do this as GLX doesn ' t guarantee that the list is sorted */
for ( run = 0 ; run < 2 ; run + + )
{
for ( i = 0 ; i < nCfgs ; i + + ) {
2007-08-20 15:48:11 +02:00
pglXGetFBConfigAttrib ( display , cfgs [ i ] , GLX_FBCONFIG_ID , & fmt_id ) ;
2008-02-22 21:40:00 +01:00
visinfo = pglXGetVisualFromFBConfig ( display , cfgs [ i ] ) ;
/* The first run we only add onscreen formats (ones which have an associated X Visual).
* The second run we only set offscreen formats . */
if ( ! run & & visinfo )
{
/* We implement child window rendering using offscreen buffers (using composite or an XPixmap).
* The contents is copied to the destination using XCopyArea . For the copying to work
* the depth of the source and destination window should be the same . In general this should
* not be a problem for OpenGL as drivers only advertise formats with a similar depth ( or no depth ) .
* As of the introduction of composition managers at least Nvidia now also offers ARGB visuals
* with a depth of 32 in addition to the default 24 bit . In order to prevent BadMatch errors we only
* list formats with the same depth . */
if ( visinfo - > depth ! = screen_depth )
continue ;
2008-05-28 16:57:46 +02:00
TRACE ( " Found onscreen format FBCONFIG_ID 0x%x corresponding to iPixelFormat %d at GLX index %d \n " , fmt_id , size + 1 , i ) ;
list [ size ] . iPixelFormat = size + 1 ; /* The index starts at 1 */
list [ size ] . fbconfig = cfgs [ i ] ;
list [ size ] . fmt_id = fmt_id ;
list [ size ] . render_type = get_render_type_from_fbconfig ( display , cfgs [ i ] ) ;
list [ size ] . offscreenOnly = FALSE ;
2009-05-14 17:05:20 +02:00
list [ size ] . dwFlags = 0 ;
2008-05-28 16:57:46 +02:00
size + + ;
onscreen_size + + ;
2009-05-14 17:05:20 +02:00
/* Clone a format if it is bitmap capable for indirect rendering to bitmaps */
if ( check_fbconfig_bitmap_capability ( display , cfgs [ i ] ) )
{
TRACE ( " Found bitmap capable format FBCONFIG_ID 0x%x corresponding to iPixelFormat %d at GLX index %d \n " , fmt_id , size + 1 , i ) ;
list [ size ] . iPixelFormat = size + 1 ; /* The index starts at 1 */
list [ size ] . fbconfig = cfgs [ i ] ;
list [ size ] . fmt_id = fmt_id ;
list [ size ] . render_type = get_render_type_from_fbconfig ( display , cfgs [ i ] ) ;
list [ size ] . offscreenOnly = FALSE ;
2009-05-19 21:42:09 +02:00
list [ size ] . dwFlags = PFD_DRAW_TO_BITMAP | PFD_SUPPORT_GDI | PFD_GENERIC_FORMAT ;
2009-05-14 17:05:20 +02:00
size + + ;
onscreen_size + + ;
}
2008-02-22 21:40:00 +01:00
XFree ( visinfo ) ;
} else if ( run & & ! visinfo ) {
2008-05-28 16:57:46 +02:00
TRACE ( " Found offscreen format FBCONFIG_ID 0x%x corresponding to iPixelFormat %d at GLX index %d \n " , fmt_id , size + 1 , i ) ;
list [ size ] . iPixelFormat = size + 1 ; /* The index starts at 1 */
list [ size ] . fbconfig = cfgs [ i ] ;
list [ size ] . fmt_id = fmt_id ;
list [ size ] . render_type = get_render_type_from_fbconfig ( display , cfgs [ i ] ) ;
list [ size ] . offscreenOnly = TRUE ;
2009-05-14 17:05:20 +02:00
list [ size ] . dwFlags = 0 ;
2008-05-28 16:57:46 +02:00
size + + ;
2008-02-22 21:40:00 +01:00
}
2007-07-26 18:13:08 +02:00
}
}
if ( cfgs ! = NULL ) XFree ( cfgs ) ;
2006-11-18 23:29:48 +01:00
2008-05-28 16:57:46 +02:00
done :
if ( size_ret ) * size_ret = size ;
if ( onscreen_size_ret ) * onscreen_size_ret = onscreen_size ;
wine_tsx11_unlock ( ) ;
return list ;
2006-11-18 23:29:48 +01:00
}
2006-08-27 23:10:32 +02:00
/* GLX can advertise dozens of different pixelformats including offscreen and onscreen ones.
* In our WGL implementation we only support a subset of these formats namely the format of
* Wine ' s main visual and offscreen formats ( if they are available ) .
2007-07-26 19:23:39 +02:00
* This function converts a WGL format to its corresponding GLX one . It returns a WineGLPixelFormat
* and it returns the number of supported WGL formats in fmt_count .
2006-08-27 23:10:32 +02:00
*/
2007-07-26 19:23:39 +02:00
static WineGLPixelFormat * ConvertPixelFormatWGLtoGLX ( Display * display , int iPixelFormat , BOOL AllowOffscreen , int * fmt_count )
2006-08-16 16:42:23 +02:00
{
2008-05-28 16:57:46 +02:00
WineGLPixelFormat * list , * res = NULL ;
int size , onscreen_size ;
2006-12-03 03:06:42 +01:00
2008-05-28 16:57:46 +02:00
if ( ! ( list = get_formats ( display , & size , & onscreen_size ) ) ) return NULL ;
2006-08-16 16:42:23 +02:00
2007-07-26 19:23:39 +02:00
/* Check if the pixelformat is valid. Note that it is legal to pass an invalid
* iPixelFormat in case of probing the number of pixelformats .
*/
2008-05-28 16:57:46 +02:00
if ( ( iPixelFormat > 0 ) & & ( iPixelFormat < = size ) & &
( ! list [ iPixelFormat - 1 ] . offscreenOnly | | AllowOffscreen ) ) {
res = & list [ iPixelFormat - 1 ] ;
2007-07-26 19:23:39 +02:00
TRACE ( " Returning FBConfig=%p for iPixelFormat=%d \n " , res - > fbconfig , iPixelFormat ) ;
2006-08-16 16:42:23 +02:00
}
2007-09-11 22:09:14 +02:00
if ( AllowOffscreen )
2008-05-28 16:57:46 +02:00
* fmt_count = size ;
2007-09-11 22:09:14 +02:00
else
2008-05-28 16:57:46 +02:00
* fmt_count = onscreen_size ;
2007-09-11 22:09:14 +02:00
2007-07-26 18:13:08 +02:00
TRACE ( " Number of returned pixelformats=%d \n " , * fmt_count ) ;
2007-07-26 19:23:39 +02:00
return res ;
2006-11-18 23:29:48 +01:00
}
/* Search our internal pixelformat list for the WGL format corresponding to the given fbconfig */
2009-05-16 21:50:58 +02:00
static WineGLPixelFormat * ConvertPixelFormatGLXtoWGL ( Display * display , int fmt_id , DWORD dwFlags )
2006-11-18 23:29:48 +01:00
{
2008-05-28 16:57:46 +02:00
WineGLPixelFormat * list ;
int i , size ;
2006-08-27 23:10:32 +02:00
2008-05-28 16:57:46 +02:00
if ( ! ( list = get_formats ( display , & size , NULL ) ) ) return NULL ;
2006-08-27 23:10:32 +02:00
2008-05-28 16:57:46 +02:00
for ( i = 0 ; i < size ; i + + ) {
2009-05-16 21:50:58 +02:00
/* A GLX format can appear multiple times in the pixel format list due to fake formats for bitmap rendering.
* Fake formats might get selected when the user passes the proper flags using the dwFlags parameter . */
if ( ( list [ i ] . fmt_id = = fmt_id ) & & ( ( list [ i ] . dwFlags & dwFlags ) = = dwFlags ) ) {
2008-05-28 16:57:46 +02:00
TRACE ( " Returning iPixelFormat %d for fmt_id 0x%x \n " , list [ i ] . iPixelFormat , fmt_id ) ;
return & list [ i ] ;
2006-11-18 23:29:48 +01:00
}
}
2007-07-26 19:23:39 +02:00
TRACE ( " No compatible format found for fmt_id 0x%x \n " , fmt_id ) ;
2007-08-10 15:35:02 +02:00
return NULL ;
2006-08-16 16:42:23 +02:00
}
2000-05-12 22:18:14 +02:00
2007-09-15 22:02:32 +02:00
int pixelformat_from_fbconfig_id ( XID fbconfig_id )
{
WineGLPixelFormat * fmt ;
if ( ! fbconfig_id ) return 0 ;
2009-05-16 21:50:58 +02:00
fmt = ConvertPixelFormatGLXtoWGL ( gdi_display , fbconfig_id , 0 /* no flags */ ) ;
2007-09-15 22:02:32 +02:00
if ( fmt )
return fmt - > iPixelFormat ;
/* This will happen on hwnds without a pixel format set; it's ok */
return 0 ;
}
2007-09-26 16:15:52 +02:00
/* Mark any allocated context using the glx drawable 'old' to use 'new' */
void mark_drawable_dirty ( Drawable old , Drawable new )
{
Wine_GLContext * ctx ;
for ( ctx = context_list ; ctx ; ctx = ctx - > next ) {
if ( old = = ctx - > drawables [ 0 ] ) {
ctx - > drawables [ 0 ] = new ;
ctx - > refresh_drawables = TRUE ;
}
if ( old = = ctx - > drawables [ 1 ] ) {
ctx - > drawables [ 1 ] = new ;
ctx - > refresh_drawables = TRUE ;
}
}
}
/* Given the current context, make sure its drawable is sync'd */
static inline void sync_context ( Wine_GLContext * context )
{
if ( context & & context - > refresh_drawables ) {
if ( glxRequireVersion ( 3 ) )
pglXMakeContextCurrent ( gdi_display , context - > drawables [ 0 ] ,
context - > drawables [ 1 ] , context - > ctx ) ;
else
pglXMakeCurrent ( gdi_display , context - > drawables [ 0 ] , context - > ctx ) ;
context - > refresh_drawables = FALSE ;
}
}
2009-05-14 17:05:20 +02:00
static GLXContext create_glxcontext ( Display * display , Wine_GLContext * context , GLXContext shareList )
2008-10-25 23:36:32 +02:00
{
GLXContext ctx ;
2009-05-14 17:05:20 +02:00
/* We use indirect rendering for rendering to bitmaps. See get_formats for a comment about this. */
BOOL indirect = ( context - > fmt - > dwFlags & PFD_DRAW_TO_BITMAP ) ? FALSE : TRUE ;
2008-10-25 23:36:32 +02:00
if ( context - > vis )
2009-05-14 17:05:20 +02:00
ctx = pglXCreateContext ( gdi_display , context - > vis , shareList , indirect ) ;
2008-10-25 23:36:32 +02:00
else /* Create a GLX Context for a pbuffer */
2009-05-14 17:05:20 +02:00
ctx = pglXCreateNewContext ( gdi_display , context - > fmt - > fbconfig , context - > fmt - > render_type , shareList , TRUE ) ;
2008-10-25 23:36:32 +02:00
return ctx ;
}
2007-09-26 17:17:13 +02:00
Drawable create_glxpixmap ( Display * display , XVisualInfo * vis , Pixmap parent )
{
return pglXCreateGLXPixmap ( display , vis , parent ) ;
}
2007-10-03 18:29:28 +02:00
static XID create_bitmap_glxpixmap ( X11DRV_PDEVICE * physDev , WineGLPixelFormat * fmt )
2007-10-03 18:20:30 +02:00
{
2007-10-03 18:29:28 +02:00
GLXPixmap ret = 0 ;
2007-10-03 18:20:30 +02:00
XVisualInfo * vis ;
wine_tsx11_lock ( ) ;
2007-10-03 18:29:28 +02:00
vis = pglXGetVisualFromFBConfig ( gdi_display , fmt - > fbconfig ) ;
if ( vis ) {
if ( vis - > depth = = physDev - > bitmap - > pixmap_depth )
ret = pglXCreateGLXPixmap ( gdi_display , vis , physDev - > bitmap - > pixmap ) ;
XFree ( vis ) ;
}
2007-10-03 18:20:30 +02:00
wine_tsx11_unlock ( ) ;
TRACE ( " return %lx \n " , ret ) ;
return ret ;
}
2005-04-28 20:29:12 +02:00
/**
* X11DRV_ChoosePixelFormat
*
2006-11-12 20:23:38 +01:00
* Equivalent to glXChooseVisual .
2005-04-28 20:29:12 +02:00
*/
2008-12-16 14:18:49 +01:00
int CDECL X11DRV_ChoosePixelFormat ( X11DRV_PDEVICE * physDev ,
2000-05-12 22:18:14 +02:00
const PIXELFORMATDESCRIPTOR * ppfd ) {
2008-05-28 16:57:46 +02:00
WineGLPixelFormat * list ;
int onscreen_size ;
2007-08-09 01:17:07 +02:00
int ret = 0 ;
int value = 0 ;
int i = 0 ;
int bestFormat = - 1 ;
2007-08-12 14:40:24 +02:00
int bestDBuffer = - 1 ;
int bestStereo = - 1 ;
2007-08-09 01:17:07 +02:00
int bestColor = - 1 ;
int bestAlpha = - 1 ;
int bestDepth = - 1 ;
int bestStencil = - 1 ;
int bestAux = - 1 ;
2008-06-23 22:56:10 +02:00
if ( ! has_opengl ( ) ) return 0 ;
2002-06-01 01:06:46 +02:00
2008-03-31 00:21:03 +02:00
if ( TRACE_ON ( wgl ) ) {
2007-08-09 01:17:07 +02:00
TRACE ( " (%p,%p) \n " , physDev , ppfd ) ;
2006-08-16 16:42:23 +02:00
2008-02-02 18:27:19 +01:00
dump_PIXELFORMATDESCRIPTOR ( ppfd ) ;
2007-08-09 01:17:07 +02:00
}
2002-06-01 01:06:46 +02:00
2008-05-28 16:57:46 +02:00
if ( ! ( list = get_formats ( gdi_display , NULL , & onscreen_size ) ) ) return 0 ;
2007-08-09 01:17:07 +02:00
wine_tsx11_lock ( ) ;
2008-05-28 16:57:46 +02:00
for ( i = 0 ; i < onscreen_size ; i + + )
2007-08-09 01:17:07 +02:00
{
int dwFlags = 0 ;
int iPixelType = 0 ;
int alpha = 0 , color = 0 , depth = 0 , stencil = 0 , aux = 0 ;
2008-05-28 16:57:46 +02:00
WineGLPixelFormat * fmt = & list [ i ] ;
2006-08-16 16:42:23 +02:00
2007-08-09 01:17:07 +02:00
/* Pixel type */
pglXGetFBConfigAttrib ( gdi_display , fmt - > fbconfig , GLX_RENDER_TYPE , & value ) ;
if ( value & GLX_RGBA_BIT )
iPixelType = PFD_TYPE_RGBA ;
else
iPixelType = PFD_TYPE_COLORINDEX ;
2006-08-16 16:42:23 +02:00
2007-08-09 01:17:07 +02:00
if ( ppfd - > iPixelType ! = iPixelType )
{
TRACE ( " pixel type mismatch for iPixelFormat=%d \n " , i + 1 ) ;
continue ;
}
2002-06-01 01:06:46 +02:00
2009-05-14 21:03:19 +02:00
/* Only use bitmap capable for formats for bitmap rendering.
* See get_formats for more info . */
if ( ( ppfd - > dwFlags & PFD_DRAW_TO_BITMAP ) ! = ( fmt - > dwFlags & PFD_DRAW_TO_BITMAP ) )
{
TRACE ( " PFD_DRAW_TO_BITMAP mismatch for iPixelFormat=%d \n " , i + 1 ) ;
continue ;
}
2007-08-09 01:17:07 +02:00
pglXGetFBConfigAttrib ( gdi_display , fmt - > fbconfig , GLX_DOUBLEBUFFER , & value ) ;
if ( value ) dwFlags | = PFD_DOUBLEBUFFER ;
pglXGetFBConfigAttrib ( gdi_display , fmt - > fbconfig , GLX_STEREO , & value ) ;
if ( value ) dwFlags | = PFD_STEREO ;
pglXGetFBConfigAttrib ( gdi_display , fmt - > fbconfig , GLX_BUFFER_SIZE , & color ) ; /* cColorBits */
pglXGetFBConfigAttrib ( gdi_display , fmt - > fbconfig , GLX_ALPHA_SIZE , & alpha ) ; /* cAlphaBits */
pglXGetFBConfigAttrib ( gdi_display , fmt - > fbconfig , GLX_DEPTH_SIZE , & depth ) ; /* cDepthBits */
pglXGetFBConfigAttrib ( gdi_display , fmt - > fbconfig , GLX_STENCIL_SIZE , & stencil ) ; /* cStencilBits */
pglXGetFBConfigAttrib ( gdi_display , fmt - > fbconfig , GLX_AUX_BUFFERS , & aux ) ; /* cAuxBuffers */
2005-12-02 11:24:52 +01:00
2007-08-12 14:40:24 +02:00
/* The behavior of PDF_STEREO/PFD_STEREO_DONTCARE and PFD_DOUBLEBUFFER / PFD_DOUBLEBUFFER_DONTCARE
* is not very clear on MSDN . They specify that ChoosePixelFormat tries to match pixel formats
* with the flag ( PFD_STEREO / PFD_DOUBLEBUFFERING ) set . Otherwise it says that it tries to match
* formats without the given flag set .
* A test on Windows using a Radeon 9500 pro on WinXP ( the driver doesn ' t support Stereo )
* has indicated that a format without stereo is returned when stereo is unavailable .
* So in case PFD_STEREO is set , formats that support it should have priority above formats
* without . In case PFD_STEREO_DONTCARE is set , stereo is ignored .
*
* To summarize the following is most likely the correct behavior :
* stereo not set - > prefer no - stereo formats , else also accept stereo formats
* stereo set - > prefer stereo formats , else also accept no - stereo formats
* stereo don ' t care - > it doesn ' t matter whether we get stereo or not
*
* In Wine we will treat no - stereo the same way as don ' t care because it makes
* format selection even more complicated and second drivers with Stereo advertise
* each format twice anyway .
*/
/* Doublebuffer, see the comments above */
if ( ! ( ppfd - > dwFlags & PFD_DOUBLEBUFFER_DONTCARE ) ) {
if ( ( ( ppfd - > dwFlags & PFD_DOUBLEBUFFER ) ! = bestDBuffer ) & &
( ( dwFlags & PFD_DOUBLEBUFFER ) = = ( ppfd - > dwFlags & PFD_DOUBLEBUFFER ) ) )
{
bestDBuffer = dwFlags & PFD_DOUBLEBUFFER ;
bestStereo = dwFlags & PFD_STEREO ;
bestAlpha = alpha ;
bestColor = color ;
bestDepth = depth ;
bestStencil = stencil ;
bestAux = aux ;
bestFormat = i ;
continue ;
}
2007-09-11 22:00:13 +02:00
if ( bestDBuffer ! = - 1 & & ( dwFlags & PFD_DOUBLEBUFFER ) ! = bestDBuffer )
continue ;
2007-08-12 14:40:24 +02:00
}
/* Stereo, see the comments above. */
if ( ! ( ppfd - > dwFlags & PFD_STEREO_DONTCARE ) ) {
if ( ( ( ppfd - > dwFlags & PFD_STEREO ) ! = bestStereo ) & &
( ( dwFlags & PFD_STEREO ) = = ( ppfd - > dwFlags & PFD_STEREO ) ) )
{
bestDBuffer = dwFlags & PFD_DOUBLEBUFFER ;
bestStereo = dwFlags & PFD_STEREO ;
bestAlpha = alpha ;
bestColor = color ;
bestDepth = depth ;
bestStencil = stencil ;
bestAux = aux ;
bestFormat = i ;
continue ;
}
2007-09-11 22:00:13 +02:00
if ( bestStereo ! = - 1 & & ( dwFlags & PFD_STEREO ) ! = bestStereo )
continue ;
2007-08-12 14:40:24 +02:00
}
2007-08-09 01:17:07 +02:00
/* Below we will do a number of checks to select the 'best' pixelformat.
* We assume the precedence cColorBits > cAlphaBits > cDepthBits > cStencilBits - > cAuxBuffers .
* The code works by trying to match the most important options as close as possible .
2008-04-01 00:18:14 +02:00
* When a reasonable format is found , we will try to match more options .
* It appears ( see the opengl32 test ) that Windows opengl drivers ignore options
* like cColorBits , cAlphaBits and friends if they are set to 0 , so they are considered
* as DONTCARE . At least Serious Sam TSE relies on this behavior . */
2006-08-16 16:42:23 +02:00
2007-08-09 01:17:07 +02:00
/* Color bits */
2008-04-01 00:18:14 +02:00
if ( ppfd - > cColorBits ) {
if ( ( ( ppfd - > cColorBits > bestColor ) & & ( color > bestColor ) ) | |
( ( color > = ppfd - > cColorBits ) & & ( color < bestColor ) ) )
{
bestDBuffer = dwFlags & PFD_DOUBLEBUFFER ;
bestStereo = dwFlags & PFD_STEREO ;
bestAlpha = alpha ;
bestColor = color ;
bestDepth = depth ;
bestStencil = stencil ;
bestAux = aux ;
bestFormat = i ;
continue ;
} else if ( bestColor ! = color ) { /* Do further checks if the format is compatible */
TRACE ( " color mismatch for iPixelFormat=%d \n " , i + 1 ) ;
continue ;
}
2007-08-09 01:17:07 +02:00
}
2006-08-16 16:42:23 +02:00
2007-08-09 01:17:07 +02:00
/* Alpha bits */
2008-04-01 00:18:14 +02:00
if ( ppfd - > cAlphaBits ) {
if ( ( ( ppfd - > cAlphaBits > bestAlpha ) & & ( alpha > bestAlpha ) ) | |
( ( alpha > = ppfd - > cAlphaBits ) & & ( alpha < bestAlpha ) ) )
{
bestDBuffer = dwFlags & PFD_DOUBLEBUFFER ;
bestStereo = dwFlags & PFD_STEREO ;
bestAlpha = alpha ;
bestColor = color ;
bestDepth = depth ;
bestStencil = stencil ;
bestAux = aux ;
bestFormat = i ;
continue ;
} else if ( bestAlpha ! = alpha ) {
TRACE ( " alpha mismatch for iPixelFormat=%d \n " , i + 1 ) ;
continue ;
}
2007-08-09 01:17:07 +02:00
}
2002-06-01 01:06:46 +02:00
2007-08-09 01:17:07 +02:00
/* Depth bits */
2008-04-01 00:18:14 +02:00
if ( ppfd - > cDepthBits ) {
if ( ( ( ppfd - > cDepthBits > bestDepth ) & & ( depth > bestDepth ) ) | |
( ( depth > = ppfd - > cDepthBits ) & & ( depth < bestDepth ) ) )
{
bestDBuffer = dwFlags & PFD_DOUBLEBUFFER ;
bestStereo = dwFlags & PFD_STEREO ;
bestAlpha = alpha ;
bestColor = color ;
bestDepth = depth ;
bestStencil = stencil ;
bestAux = aux ;
bestFormat = i ;
continue ;
} else if ( bestDepth ! = depth ) {
TRACE ( " depth mismatch for iPixelFormat=%d \n " , i + 1 ) ;
continue ;
}
2007-08-09 01:17:07 +02:00
}
/* Stencil bits */
2008-04-01 00:18:14 +02:00
if ( ppfd - > cStencilBits ) {
if ( ( ( ppfd - > cStencilBits > bestStencil ) & & ( stencil > bestStencil ) ) | |
( ( stencil > = ppfd - > cStencilBits ) & & ( stencil < bestStencil ) ) )
{
bestDBuffer = dwFlags & PFD_DOUBLEBUFFER ;
bestStereo = dwFlags & PFD_STEREO ;
bestAlpha = alpha ;
bestColor = color ;
bestDepth = depth ;
bestStencil = stencil ;
bestAux = aux ;
bestFormat = i ;
continue ;
} else if ( bestStencil ! = stencil ) {
TRACE ( " stencil mismatch for iPixelFormat=%d \n " , i + 1 ) ;
continue ;
}
2007-08-09 01:17:07 +02:00
}
/* Aux buffers */
2008-04-01 00:18:14 +02:00
if ( ppfd - > cAuxBuffers ) {
if ( ( ( ppfd - > cAuxBuffers > bestAux ) & & ( aux > bestAux ) ) | |
( ( aux > = ppfd - > cAuxBuffers ) & & ( aux < bestAux ) ) )
{
bestDBuffer = dwFlags & PFD_DOUBLEBUFFER ;
bestStereo = dwFlags & PFD_STEREO ;
bestAlpha = alpha ;
bestColor = color ;
bestDepth = depth ;
bestStencil = stencil ;
bestAux = aux ;
bestFormat = i ;
continue ;
} else if ( bestAux ! = aux ) {
TRACE ( " aux mismatch for iPixelFormat=%d \n " , i + 1 ) ;
continue ;
}
2007-08-09 01:17:07 +02:00
}
2005-04-28 20:29:12 +02:00
}
2006-08-16 16:42:23 +02:00
2007-08-09 01:17:07 +02:00
if ( bestFormat = = - 1 ) {
TRACE ( " No matching mode was found returning 0 \n " ) ;
ret = 0 ;
}
else {
ret = bestFormat + 1 ; /* the return value should be a 1-based index */
2008-05-28 16:57:46 +02:00
TRACE ( " Successfully found a matching mode, returning index: %d %x \n " , ret , list [ bestFormat ] . fmt_id ) ;
2007-08-09 01:17:07 +02:00
}
2002-06-01 01:06:46 +02:00
2007-08-09 01:17:07 +02:00
wine_tsx11_unlock ( ) ;
2006-08-16 16:42:23 +02:00
2007-08-09 01:17:07 +02:00
return ret ;
2000-05-12 22:18:14 +02:00
}
2005-05-06 16:33:02 +02:00
/**
* X11DRV_DescribePixelFormat
*
* Get the pixel - format descriptor associated to the given id
*/
2008-12-16 14:18:49 +01:00
int CDECL X11DRV_DescribePixelFormat ( X11DRV_PDEVICE * physDev ,
2000-05-12 22:18:14 +02:00
int iPixelFormat ,
UINT nBytes ,
PIXELFORMATDESCRIPTOR * ppfd ) {
2005-04-28 20:29:12 +02:00
/*XVisualInfo *vis;*/
2000-05-12 22:18:14 +02:00
int value ;
int rb , gb , bb , ab ;
2007-07-26 19:23:39 +02:00
WineGLPixelFormat * fmt ;
2005-04-28 20:29:12 +02:00
int ret = 0 ;
2006-12-10 19:17:03 +01:00
int fmt_count = 0 ;
2005-04-28 20:29:12 +02:00
2008-06-23 22:56:10 +02:00
if ( ! has_opengl ( ) ) return 0 ;
2002-04-09 00:43:58 +02:00
TRACE ( " (%p,%d,%d,%p) \n " , physDev , iPixelFormat , nBytes , ppfd ) ;
2002-05-24 23:14:16 +02:00
2006-12-10 19:17:03 +01:00
/* Look for the iPixelFormat in our list of supported formats. If it is supported we get the index in the FBConfig table and the number of supported formats back */
2007-07-26 19:23:39 +02:00
fmt = ConvertPixelFormatWGLtoGLX ( gdi_display , iPixelFormat , FALSE /* Offscreen */ , & fmt_count ) ;
2002-05-24 23:14:16 +02:00
if ( ppfd = = NULL ) {
2007-07-26 19:23:39 +02:00
/* The application is only querying the number of pixelformats */
2006-12-10 19:17:03 +01:00
return fmt_count ;
2007-07-26 19:23:39 +02:00
} else if ( fmt = = NULL ) {
2006-12-10 19:17:03 +01:00
WARN ( " unexpected iPixelFormat(%d): not >=1 and <=nFormats(%d), returning NULL! \n " , iPixelFormat , fmt_count ) ;
return 0 ;
2002-05-24 23:14:16 +02:00
}
2002-06-01 01:06:46 +02:00
2000-05-12 22:18:14 +02:00
if ( nBytes < sizeof ( PIXELFORMATDESCRIPTOR ) ) {
ERR ( " Wrong structure size ! \n " ) ;
/* Should set error */
return 0 ;
}
2006-12-10 19:17:03 +01:00
ret = fmt_count ;
2000-05-12 22:18:14 +02:00
memset ( ppfd , 0 , sizeof ( PIXELFORMATDESCRIPTOR ) ) ;
ppfd - > nSize = sizeof ( PIXELFORMATDESCRIPTOR ) ;
ppfd - > nVersion = 1 ;
2002-06-01 01:06:46 +02:00
2000-05-12 22:18:14 +02:00
/* These flags are always the same... */
2007-08-12 22:57:02 +02:00
ppfd - > dwFlags = PFD_SUPPORT_OPENGL ;
2005-11-18 13:06:45 +01:00
/* Now the flags extracted from the Visual */
2005-04-28 20:29:12 +02:00
2002-09-25 02:29:56 +02:00
wine_tsx11_lock ( ) ;
2005-04-28 20:29:12 +02:00
2007-08-12 22:57:02 +02:00
pglXGetFBConfigAttrib ( gdi_display , fmt - > fbconfig , GLX_DRAWABLE_TYPE , & value ) ;
if ( value & GLX_WINDOW_BIT )
ppfd - > dwFlags | = PFD_DRAW_TO_WINDOW ;
2009-05-14 17:05:20 +02:00
/* On Windows bitmap rendering is only offered using the GDI Software renderer. We reserve some formats (see get_formats for more info)
* for bitmap rendering since we require indirect rendering for this . Further pixel format logs of a GeforceFX , Geforce8800GT , Radeon HD3400 and a
* Radeon 9000 indicated that all bitmap formats have PFD_SUPPORT_GDI . Except for 2 formats on the Radeon 9000 none of the hw accelerated formats
* offered the GDI bit either . */
ppfd - > dwFlags | = fmt - > dwFlags & ( PFD_DRAW_TO_BITMAP | PFD_SUPPORT_GDI ) ;
2007-08-12 22:57:02 +02:00
2009-05-15 00:00:49 +02:00
/* PFD_GENERIC_FORMAT - gdi software rendering
2009-05-19 21:42:09 +02:00
* PFD_GENERIC_ACCELERATED - some parts are accelerated by a display driver ( MCD e . g . 3 dfx minigl )
2009-05-15 00:00:49 +02:00
* none set - full hardware accelerated by a ICD
*
2009-05-19 21:42:09 +02:00
* We only set PFD_GENERIC_FORMAT on bitmap formats ( see get_formats ) as that ' s what ATI and Nvidia Windows drivers do */
ppfd - > dwFlags | = fmt - > dwFlags & ( PFD_GENERIC_FORMAT | PFD_GENERIC_ACCELERATED ) ;
2005-11-18 13:06:45 +01:00
2007-08-14 03:36:46 +02:00
pglXGetFBConfigAttrib ( gdi_display , fmt - > fbconfig , GLX_DOUBLEBUFFER , & value ) ;
if ( value ) {
ppfd - > dwFlags | = PFD_DOUBLEBUFFER ;
ppfd - > dwFlags & = ~ PFD_SUPPORT_GDI ;
}
2007-07-26 19:23:39 +02:00
pglXGetFBConfigAttrib ( gdi_display , fmt - > fbconfig , GLX_STEREO , & value ) ; if ( value ) ppfd - > dwFlags | = PFD_STEREO ;
2000-05-12 22:18:14 +02:00
/* Pixel type */
2007-07-26 19:23:39 +02:00
pglXGetFBConfigAttrib ( gdi_display , fmt - > fbconfig , GLX_RENDER_TYPE , & value ) ;
2005-04-28 20:29:12 +02:00
if ( value & GLX_RGBA_BIT )
2000-05-12 22:18:14 +02:00
ppfd - > iPixelType = PFD_TYPE_RGBA ;
else
ppfd - > iPixelType = PFD_TYPE_COLORINDEX ;
/* Color bits */
2007-07-26 19:23:39 +02:00
pglXGetFBConfigAttrib ( gdi_display , fmt - > fbconfig , GLX_BUFFER_SIZE , & value ) ;
2000-05-12 22:18:14 +02:00
ppfd - > cColorBits = value ;
/* Red, green, blue and alpha bits / shifts */
if ( ppfd - > iPixelType = = PFD_TYPE_RGBA ) {
2007-07-26 19:23:39 +02:00
pglXGetFBConfigAttrib ( gdi_display , fmt - > fbconfig , GLX_RED_SIZE , & rb ) ;
pglXGetFBConfigAttrib ( gdi_display , fmt - > fbconfig , GLX_GREEN_SIZE , & gb ) ;
pglXGetFBConfigAttrib ( gdi_display , fmt - > fbconfig , GLX_BLUE_SIZE , & bb ) ;
pglXGetFBConfigAttrib ( gdi_display , fmt - > fbconfig , GLX_ALPHA_SIZE , & ab ) ;
2001-05-11 02:17:47 +02:00
2000-05-12 22:18:14 +02:00
ppfd - > cRedBits = rb ;
ppfd - > cRedShift = gb + bb + ab ;
ppfd - > cBlueBits = bb ;
ppfd - > cBlueShift = ab ;
ppfd - > cGreenBits = gb ;
ppfd - > cGreenShift = bb + ab ;
ppfd - > cAlphaBits = ab ;
ppfd - > cAlphaShift = 0 ;
} else {
ppfd - > cRedBits = 0 ;
ppfd - > cRedShift = 0 ;
ppfd - > cBlueBits = 0 ;
ppfd - > cBlueShift = 0 ;
ppfd - > cGreenBits = 0 ;
ppfd - > cGreenShift = 0 ;
ppfd - > cAlphaBits = 0 ;
ppfd - > cAlphaShift = 0 ;
}
2007-08-02 21:20:56 +02:00
/* Accum RGBA bits */
pglXGetFBConfigAttrib ( gdi_display , fmt - > fbconfig , GLX_ACCUM_RED_SIZE , & rb ) ;
pglXGetFBConfigAttrib ( gdi_display , fmt - > fbconfig , GLX_ACCUM_GREEN_SIZE , & gb ) ;
pglXGetFBConfigAttrib ( gdi_display , fmt - > fbconfig , GLX_ACCUM_BLUE_SIZE , & bb ) ;
pglXGetFBConfigAttrib ( gdi_display , fmt - > fbconfig , GLX_ACCUM_ALPHA_SIZE , & ab ) ;
ppfd - > cAccumBits = rb + gb + bb + ab ;
ppfd - > cAccumRedBits = rb ;
ppfd - > cAccumGreenBits = gb ;
ppfd - > cAccumBlueBits = bb ;
ppfd - > cAccumAlphaBits = ab ;
2002-06-01 01:06:46 +02:00
2008-02-23 16:00:54 +01:00
/* Aux bits */
pglXGetFBConfigAttrib ( gdi_display , fmt - > fbconfig , GLX_AUX_BUFFERS , & value ) ;
ppfd - > cAuxBuffers = value ;
2000-05-12 22:18:14 +02:00
/* Depth bits */
2007-07-26 19:23:39 +02:00
pglXGetFBConfigAttrib ( gdi_display , fmt - > fbconfig , GLX_DEPTH_SIZE , & value ) ;
2000-05-12 22:18:14 +02:00
ppfd - > cDepthBits = value ;
2002-04-12 01:48:42 +02:00
/* stencil bits */
2007-07-26 19:23:39 +02:00
pglXGetFBConfigAttrib ( gdi_display , fmt - > fbconfig , GLX_STENCIL_SIZE , & value ) ;
2002-04-12 01:48:42 +02:00
ppfd - > cStencilBits = value ;
2002-06-01 01:06:46 +02:00
2002-09-25 02:29:56 +02:00
wine_tsx11_unlock ( ) ;
2000-05-12 22:18:14 +02:00
ppfd - > iLayerType = PFD_MAIN_PLANE ;
2002-06-01 01:06:46 +02:00
2008-03-31 00:21:03 +02:00
if ( TRACE_ON ( wgl ) ) {
2000-05-15 00:53:17 +02:00
dump_PIXELFORMATDESCRIPTOR ( ppfd ) ;
}
2002-06-01 01:06:46 +02:00
2005-04-28 20:29:12 +02:00
return ret ;
2000-05-12 22:18:14 +02:00
}
2005-05-06 16:33:02 +02:00
/**
* X11DRV_GetPixelFormat
*
* Get the pixel - format id used by this DC
*/
2008-12-16 14:18:49 +01:00
int CDECL X11DRV_GetPixelFormat ( X11DRV_PDEVICE * physDev ) {
2007-08-01 14:38:49 +02:00
WineGLPixelFormat * fmt ;
int tmp ;
TRACE ( " (%p) \n " , physDev ) ;
2008-05-12 19:58:35 +02:00
if ( ! physDev - > current_pf ) return 0 ; /* not set yet */
2007-08-01 14:38:49 +02:00
fmt = ConvertPixelFormatWGLtoGLX ( gdi_display , physDev - > current_pf , TRUE , & tmp ) ;
if ( ! fmt )
{
ERR ( " Unable to find a WineGLPixelFormat for iPixelFormat=%d \n " , physDev - > current_pf ) ;
return 0 ;
}
else if ( fmt - > offscreenOnly )
{
/* Offscreen formats can't be used with traditional WGL calls.
* As has been verified on Windows GetPixelFormat doesn ' t fail but returns iPixelFormat = 1. */
TRACE ( " Returning iPixelFormat=1 for offscreen format: %d \n " , fmt - > iPixelFormat ) ;
return 1 ;
}
2000-05-12 22:18:14 +02:00
2007-08-01 14:38:49 +02:00
TRACE ( " (%p): returns %d \n " , physDev , physDev - > current_pf ) ;
2007-08-04 00:56:50 +02:00
return physDev - > current_pf ;
2000-05-12 22:18:14 +02:00
}
2008-04-23 22:40:43 +02:00
/* This function is the core of X11DRV_SetPixelFormat and X11DRV_SetPixelFormatWINE.
* Both functions are the same except that X11DRV_SetPixelFormatWINE allows you to
* set the pixel format multiple times . */
static BOOL internal_SetPixelFormat ( X11DRV_PDEVICE * physDev ,
2000-05-12 22:18:14 +02:00
int iPixelFormat ,
const PIXELFORMATDESCRIPTOR * ppfd ) {
2008-04-23 22:40:43 +02:00
WineGLPixelFormat * fmt ;
int value ;
HWND hwnd ;
2007-08-01 15:58:51 +02:00
2008-04-23 22:40:43 +02:00
/* SetPixelFormat is not allowed on the X root_window e.g. GetDC(0) */
if ( get_glxdrawable ( physDev ) = = root_window )
{
ERR ( " Invalid operation on root_window \n " ) ;
return FALSE ;
}
2006-08-16 16:42:23 +02:00
2008-04-23 22:40:43 +02:00
/* Check if iPixelFormat is in our list of supported formats to see if it is supported. */
fmt = ConvertPixelFormatWGLtoGLX ( gdi_display , iPixelFormat , FALSE /* Offscreen */ , & value ) ;
if ( ! fmt ) {
ERR ( " Invalid iPixelFormat: %d \n " , iPixelFormat ) ;
return FALSE ;
}
2007-09-19 12:21:08 +02:00
2008-05-28 17:02:07 +02:00
wine_tsx11_lock ( ) ;
2007-09-15 22:02:32 +02:00
pglXGetFBConfigAttrib ( gdi_display , fmt - > fbconfig , GLX_DRAWABLE_TYPE , & value ) ;
2008-05-28 17:02:07 +02:00
wine_tsx11_unlock ( ) ;
2007-09-15 22:02:32 +02:00
hwnd = WindowFromDC ( physDev - > hdc ) ;
if ( hwnd ) {
if ( ! ( value & GLX_WINDOW_BIT ) ) {
WARN ( " Pixel format %d is not compatible for window rendering \n " , iPixelFormat ) ;
2007-09-19 12:21:08 +02:00
return FALSE ;
2007-09-15 22:02:32 +02:00
}
if ( ! SendMessageW ( hwnd , WM_X11DRV_SET_WIN_FORMAT , ( WPARAM ) fmt - > fmt_id , 0 ) ) {
ERR ( " Couldn't set format of the window, returning failure \n " ) ;
2007-09-19 12:21:08 +02:00
return FALSE ;
2007-09-15 22:02:32 +02:00
}
}
2007-10-03 18:20:30 +02:00
else if ( physDev - > bitmap ) {
if ( ! ( value & GLX_PIXMAP_BIT ) ) {
WARN ( " Pixel format %d is not compatible for bitmap rendering \n " , iPixelFormat ) ;
return FALSE ;
}
2007-10-03 18:29:28 +02:00
physDev - > bitmap - > glxpixmap = create_bitmap_glxpixmap ( physDev , fmt ) ;
2007-10-03 18:20:30 +02:00
if ( ! physDev - > bitmap - > glxpixmap ) {
WARN ( " Couldn't create glxpixmap for pixel format %d \n " , iPixelFormat ) ;
return FALSE ;
}
}
else {
2007-10-11 18:33:32 +02:00
FIXME ( " called on a non-window, non-bitmap object? \n " ) ;
2007-10-03 18:20:30 +02:00
}
2007-09-15 22:02:32 +02:00
2008-04-23 22:40:43 +02:00
physDev - > current_pf = iPixelFormat ;
2006-08-29 16:56:57 +02:00
2008-04-23 22:40:43 +02:00
if ( TRACE_ON ( wgl ) ) {
int gl_test = 0 ;
2006-08-16 16:42:23 +02:00
2008-05-28 17:02:07 +02:00
wine_tsx11_lock ( ) ;
2008-04-23 22:40:43 +02:00
gl_test = pglXGetFBConfigAttrib ( gdi_display , fmt - > fbconfig , GLX_FBCONFIG_ID , & value ) ;
if ( gl_test ) {
ERR ( " Failed to retrieve FBCONFIG_ID from GLXFBConfig, expect problems. \n " ) ;
} else {
TRACE ( " FBConfig have : \n " ) ;
TRACE ( " - FBCONFIG_ID 0x%x \n " , value ) ;
pglXGetFBConfigAttrib ( gdi_display , fmt - > fbconfig , GLX_VISUAL_ID , & value ) ;
TRACE ( " - VISUAL_ID 0x%x \n " , value ) ;
pglXGetFBConfigAttrib ( gdi_display , fmt - > fbconfig , GLX_DRAWABLE_TYPE , & value ) ;
TRACE ( " - DRAWABLE_TYPE 0x%x \n " , value ) ;
}
2008-05-28 17:02:07 +02:00
wine_tsx11_unlock ( ) ;
2005-11-11 11:52:14 +01:00
}
2008-04-23 22:40:43 +02:00
return TRUE ;
}
/**
* X11DRV_SetPixelFormat
*
* Set the pixel - format id used by this DC
*/
2008-12-16 14:18:49 +01:00
BOOL CDECL X11DRV_SetPixelFormat ( X11DRV_PDEVICE * physDev ,
2008-04-23 22:40:43 +02:00
int iPixelFormat ,
const PIXELFORMATDESCRIPTOR * ppfd ) {
TRACE ( " (%p,%d,%p) \n " , physDev , iPixelFormat , ppfd ) ;
2008-06-23 22:56:10 +02:00
if ( ! has_opengl ( ) ) return FALSE ;
2008-04-23 22:40:43 +02:00
if ( physDev - > current_pf ) /* cannot change it if already set */
return ( physDev - > current_pf = = iPixelFormat ) ;
return internal_SetPixelFormat ( physDev , iPixelFormat , ppfd ) ;
2000-05-12 22:18:14 +02:00
}
2007-11-11 21:32:12 +01:00
/**
* X11DRV_wglCopyContext
*
* For OpenGL32 wglCopyContext .
*/
2008-12-16 14:18:49 +01:00
BOOL CDECL X11DRV_wglCopyContext ( HGLRC hglrcSrc , HGLRC hglrcDst , UINT mask ) {
2007-11-11 21:32:12 +01:00
Wine_GLContext * src = ( Wine_GLContext * ) hglrcSrc ;
Wine_GLContext * dst = ( Wine_GLContext * ) hglrcDst ;
TRACE ( " hglrcSrc: (%p), hglrcDst: (%p), mask: %#x \n " , hglrcSrc , hglrcDst , mask ) ;
/* There is a slight difference in the way GL contexts share display lists in WGL and GLX.
* In case of GLX you need to specify this at context creation time but in case of WGL you
* do this using wglShareLists which you can call after creating the context .
* To emulate WGL we try to delay the creation of the context until wglShareLists or wglMakeCurrent .
2007-12-07 01:03:54 +01:00
* Up to now that works fine .
2007-11-11 21:32:12 +01:00
*
* The delayed GLX context creation could cause issues for wglCopyContext as it might get called
2008-02-25 21:23:48 +01:00
* when there is no GLX context yet . The chance this will cause problems is small as at the time of
* writing Wine has had OpenGL support for more than 7 years and this function has remained a stub
* ever since then .
2007-11-11 21:32:12 +01:00
*/
if ( ! src - > ctx | | ! dst - > ctx ) {
2008-02-25 21:23:48 +01:00
/* NOTE: As a special case, if both GLX contexts are NULL, that means
* neither WGL context was made current . In that case , both contexts
* are in a default state , so any copy would no - op .
*/
if ( ! src - > ctx & & ! dst - > ctx ) {
TRACE ( " No source or destination contexts set. No-op. \n " ) ;
return TRUE ;
}
if ( ! src - > ctx ) {
wine_tsx11_lock ( ) ;
2009-05-14 17:05:20 +02:00
src - > ctx = create_glxcontext ( gdi_display , src , NULL ) ;
2008-02-25 21:23:48 +01:00
TRACE ( " created a delayed OpenGL context (%p) \n " , src - > ctx ) ;
}
else if ( ! dst - > ctx ) {
wine_tsx11_lock ( ) ;
2009-05-14 17:05:20 +02:00
dst - > ctx = create_glxcontext ( gdi_display , dst , NULL ) ;
2008-02-25 21:23:48 +01:00
TRACE ( " created a delayed OpenGL context (%p) \n " , dst - > ctx ) ;
}
2007-11-11 21:32:12 +01:00
}
2008-02-25 21:23:48 +01:00
else
wine_tsx11_lock ( ) ;
2007-11-11 21:32:12 +01:00
pglXCopyContext ( gdi_display , src - > ctx , dst - > ctx , mask ) ;
2008-02-25 21:23:48 +01:00
wine_tsx11_unlock ( ) ;
2007-11-11 21:32:12 +01:00
/* As opposed to wglCopyContext, glXCopyContext doesn't return anything, so hopefully we passed */
return TRUE ;
}
2006-11-12 20:23:38 +01:00
/**
* X11DRV_wglCreateContext
*
* For OpenGL32 wglCreateContext .
*/
2008-12-16 14:18:49 +01:00
HGLRC CDECL X11DRV_wglCreateContext ( X11DRV_PDEVICE * physDev )
2006-08-29 16:56:57 +02:00
{
Wine_GLContext * ret ;
2007-07-26 19:23:39 +02:00
WineGLPixelFormat * fmt ;
2006-12-10 19:17:03 +01:00
int hdcPF = physDev - > current_pf ;
int fmt_count = 0 ;
2006-10-03 19:52:17 +02:00
HDC hdc = physDev - > hdc ;
2006-08-29 16:56:57 +02:00
TRACE ( " (%p)->(PF:%d) \n " , hdc , hdcPF ) ;
2008-06-23 22:56:10 +02:00
if ( ! has_opengl ( ) ) return 0 ;
2006-11-02 22:23:42 +01:00
2007-07-26 20:32:22 +02:00
fmt = ConvertPixelFormatWGLtoGLX ( gdi_display , hdcPF , TRUE /* Offscreen */ , & fmt_count ) ;
/* We can render using the iPixelFormat (1) of Wine's Main visual AND using some offscreen formats.
* Note that standard WGL - calls don ' t recognize offscreen - only formats . For that reason pbuffers
* use a sort of ' proxy ' HDC ( wglGetPbufferDCARB ) .
* If this fails something is very wrong on the system . */
2007-07-26 19:23:39 +02:00
if ( ! fmt ) {
2007-07-26 20:32:22 +02:00
ERR ( " Cannot get FB Config for iPixelFormat %d, expect problems! \n " , hdcPF ) ;
2006-08-29 16:56:57 +02:00
SetLastError ( ERROR_INVALID_PIXEL_FORMAT ) ;
return NULL ;
}
/* The context will be allocated in the wglMakeCurrent call */
wine_tsx11_lock ( ) ;
ret = alloc_context ( ) ;
wine_tsx11_unlock ( ) ;
ret - > hdc = hdc ;
2007-07-28 18:56:12 +02:00
ret - > fmt = fmt ;
2006-08-29 16:56:57 +02:00
/*ret->vis = vis;*/
2007-07-26 19:23:39 +02:00
ret - > vis = pglXGetVisualFromFBConfig ( gdi_display , fmt - > fbconfig ) ;
2006-08-29 16:56:57 +02:00
TRACE ( " creating context %p (GL context creation delayed) \n " , ret ) ;
return ( HGLRC ) ret ;
}
2006-11-12 20:23:38 +01:00
/**
* X11DRV_wglDeleteContext
*
* For OpenGL32 wglDeleteContext .
*/
2008-12-16 14:18:49 +01:00
BOOL CDECL X11DRV_wglDeleteContext ( HGLRC hglrc )
2006-08-29 16:56:57 +02:00
{
Wine_GLContext * ctx = ( Wine_GLContext * ) hglrc ;
BOOL ret = TRUE ;
TRACE ( " (%p) \n " , hglrc ) ;
2008-06-23 22:56:10 +02:00
if ( ! has_opengl ( ) ) return 0 ;
2006-11-02 22:23:42 +01:00
2006-08-29 16:56:57 +02:00
wine_tsx11_lock ( ) ;
/* A game (Half Life not to name it) deletes twice the same context,
* so make sure it is valid first */
if ( is_valid_context ( ctx ) )
{
2006-12-12 18:23:34 +01:00
if ( ctx - > ctx ) pglXDestroyContext ( gdi_display , ctx - > ctx ) ;
2006-08-29 16:56:57 +02:00
free_context ( ctx ) ;
}
else
{
WARN ( " Error deleting context ! \n " ) ;
SetLastError ( ERROR_INVALID_HANDLE ) ;
ret = FALSE ;
}
wine_tsx11_unlock ( ) ;
return ret ;
}
2006-11-12 20:23:38 +01:00
/**
* X11DRV_wglGetCurrentReadDCARB
*
* For OpenGL32 wglGetCurrentReadDCARB .
*/
2006-09-25 23:03:27 +02:00
static HDC WINAPI X11DRV_wglGetCurrentReadDCARB ( void )
2006-08-29 16:56:57 +02:00
{
2007-08-22 19:47:32 +02:00
HDC ret = 0 ;
Wine_GLContext * ctx = NtCurrentTeb ( ) - > glContext ;
2006-08-29 16:56:57 +02:00
2007-10-10 17:38:51 +02:00
if ( ctx ) ret = ctx - > read_hdc ;
2006-08-29 16:56:57 +02:00
2007-10-10 17:38:51 +02:00
TRACE ( " returning %p (GL drawable %lu) \n " , ret , ctx ? ctx - > drawables [ 1 ] : 0 ) ;
2006-08-29 16:56:57 +02:00
return ret ;
}
2006-11-12 20:23:38 +01:00
/**
* X11DRV_wglGetProcAddress
*
* For OpenGL32 wglGetProcAddress .
*/
2008-12-16 14:18:49 +01:00
PROC CDECL X11DRV_wglGetProcAddress ( LPCSTR lpszProc )
2006-09-11 21:28:32 +02:00
{
int i , j ;
2006-09-12 11:50:36 +02:00
const WineGLExtension * ext ;
2006-09-11 21:28:32 +02:00
int padding = 32 - strlen ( lpszProc ) ;
if ( padding < 0 )
padding = 0 ;
2008-06-23 22:56:10 +02:00
if ( ! has_opengl ( ) ) return NULL ;
2006-11-02 22:23:42 +01:00
2006-10-26 23:11:07 +02:00
/* Check the table of WGL extensions to see if we need to return a WGL extension
* or a function pointer to a native OpenGL function . */
if ( strncmp ( lpszProc , " wgl " , 3 ) ! = 0 ) {
2006-11-25 19:25:15 +01:00
return pglXGetProcAddressARB ( ( const GLubyte * ) lpszProc ) ;
2006-10-26 23:11:07 +02:00
} else {
TRACE ( " ('%s'):%*s " , lpszProc , padding , " " ) ;
for ( i = 0 ; i < WineGLExtensionListSize ; + + i ) {
ext = WineGLExtensionList [ i ] ;
for ( j = 0 ; ext - > extEntryPoints [ j ] . funcName ; + + j ) {
if ( strcmp ( ext - > extEntryPoints [ j ] . funcName , lpszProc ) = = 0 ) {
TRACE ( " (%p) - WineGL \n " , ext - > extEntryPoints [ j ] . funcAddress ) ;
return ext - > extEntryPoints [ j ] . funcAddress ;
}
2006-09-11 21:28:32 +02:00
}
}
}
2007-08-29 00:44:15 +02:00
WARN ( " (%s) - not found \n " , lpszProc ) ;
2006-09-11 21:28:32 +02:00
return NULL ;
}
2006-11-12 20:23:38 +01:00
/**
* X11DRV_wglMakeCurrent
*
* For OpenGL32 wglMakeCurrent .
*/
2008-12-16 14:18:49 +01:00
BOOL CDECL X11DRV_wglMakeCurrent ( X11DRV_PDEVICE * physDev , HGLRC hglrc ) {
2006-08-29 16:58:49 +02:00
BOOL ret ;
2006-10-03 19:52:17 +02:00
HDC hdc = physDev - > hdc ;
2006-08-29 16:58:49 +02:00
DWORD type = GetObjectType ( hdc ) ;
2008-06-18 20:10:47 +02:00
Wine_GLContext * ctx = ( Wine_GLContext * ) hglrc ;
2006-08-29 16:58:49 +02:00
TRACE ( " (%p,%p) \n " , hdc , hglrc ) ;
2008-06-23 22:56:10 +02:00
if ( ! has_opengl ( ) ) return FALSE ;
2006-11-02 22:23:42 +01:00
2006-08-29 16:58:49 +02:00
wine_tsx11_lock ( ) ;
if ( hglrc = = NULL ) {
ret = pglXMakeCurrent ( gdi_display , None , NULL ) ;
NtCurrentTeb ( ) - > glContext = NULL ;
2008-06-18 20:10:47 +02:00
} else if ( ctx - > fmt - > iPixelFormat ! = physDev - > current_pf ) {
WARN ( " mismatched pixel format hdc %p %u ctx %p %u \n " ,
hdc , physDev - > current_pf , ctx , ctx - > fmt - > iPixelFormat ) ;
SetLastError ( ERROR_INVALID_PIXEL_FORMAT ) ;
ret = FALSE ;
2006-08-29 16:58:49 +02:00
} else {
2007-06-14 17:02:50 +02:00
Drawable drawable = get_glxdrawable ( physDev ) ;
2006-08-29 16:58:49 +02:00
if ( ctx - > ctx = = NULL ) {
2006-12-05 23:12:24 +01:00
/* The describe lines below are for debugging purposes only */
if ( TRACE_ON ( wgl ) ) {
describeDrawable ( ctx , drawable ) ;
describeContext ( ctx ) ;
2006-08-29 16:58:49 +02:00
}
2006-12-05 23:12:24 +01:00
/* Create a GLX context using the same visual as chosen earlier in wglCreateContext.
* We are certain that the drawable and context are compatible as we only allow compatible formats .
*/
TRACE ( " Creating GLX Context \n " ) ;
2009-05-14 17:05:20 +02:00
ctx - > ctx = create_glxcontext ( gdi_display , ctx , NULL ) ;
2006-08-29 16:58:49 +02:00
TRACE ( " created a delayed OpenGL context (%p) \n " , ctx - > ctx ) ;
}
2006-12-12 18:23:34 +01:00
TRACE ( " make current for dis %p, drawable %p, ctx %p \n " , gdi_display , ( void * ) drawable , ctx - > ctx ) ;
ret = pglXMakeCurrent ( gdi_display , drawable , ctx - > ctx ) ;
2006-08-29 16:58:49 +02:00
NtCurrentTeb ( ) - > glContext = ctx ;
2006-12-07 16:45:58 +01:00
if ( ret )
2006-08-29 16:58:49 +02:00
{
2007-08-23 12:50:29 +02:00
ctx - > hdc = hdc ;
2007-10-10 17:38:51 +02:00
ctx - > read_hdc = hdc ;
2007-09-26 16:15:52 +02:00
ctx - > drawables [ 0 ] = drawable ;
ctx - > drawables [ 1 ] = drawable ;
ctx - > refresh_drawables = FALSE ;
2006-12-07 16:45:58 +01:00
if ( type = = OBJ_MEMDC )
{
ctx - > do_escape = TRUE ;
pglDrawBuffer ( GL_FRONT_LEFT ) ;
}
2006-08-29 16:58:49 +02:00
}
}
wine_tsx11_unlock ( ) ;
TRACE ( " returning %s \n " , ( ret ? " True " : " False " ) ) ;
return ret ;
}
2006-11-12 20:23:38 +01:00
/**
* X11DRV_wglMakeContextCurrentARB
*
* For OpenGL32 wglMakeContextCurrentARB
*/
2008-12-16 14:18:49 +01:00
BOOL CDECL X11DRV_wglMakeContextCurrentARB ( X11DRV_PDEVICE * pDrawDev , X11DRV_PDEVICE * pReadDev , HGLRC hglrc )
2006-08-29 16:58:49 +02:00
{
BOOL ret ;
2007-09-27 18:02:26 +02:00
2007-08-22 19:47:32 +02:00
TRACE ( " (%p,%p,%p) \n " , pDrawDev , pReadDev , hglrc ) ;
2006-08-29 16:58:49 +02:00
2008-06-23 22:56:10 +02:00
if ( ! has_opengl ( ) ) return 0 ;
2006-11-02 22:23:42 +01:00
2006-08-29 16:58:49 +02:00
wine_tsx11_lock ( ) ;
if ( hglrc = = NULL ) {
ret = pglXMakeCurrent ( gdi_display , None , NULL ) ;
2006-10-14 12:56:07 +02:00
NtCurrentTeb ( ) - > glContext = NULL ;
2006-08-29 16:58:49 +02:00
} else {
if ( NULL = = pglXMakeContextCurrent ) {
ret = FALSE ;
} else {
Wine_GLContext * ctx = ( Wine_GLContext * ) hglrc ;
2007-08-22 19:47:32 +02:00
Drawable d_draw = get_glxdrawable ( pDrawDev ) ;
Drawable d_read = get_glxdrawable ( pReadDev ) ;
2006-08-29 16:58:49 +02:00
if ( ctx - > ctx = = NULL ) {
2009-05-14 17:05:20 +02:00
ctx - > ctx = create_glxcontext ( gdi_display , ctx , NULL ) ;
2006-08-29 16:58:49 +02:00
TRACE ( " created a delayed OpenGL context (%p) \n " , ctx - > ctx ) ;
}
2007-08-23 12:50:29 +02:00
ctx - > hdc = pDrawDev - > hdc ;
2007-10-10 17:38:51 +02:00
ctx - > read_hdc = pReadDev - > hdc ;
2007-09-26 16:15:52 +02:00
ctx - > drawables [ 0 ] = d_draw ;
ctx - > drawables [ 1 ] = d_read ;
ctx - > refresh_drawables = FALSE ;
2006-12-12 18:23:34 +01:00
ret = pglXMakeContextCurrent ( gdi_display , d_draw , d_read , ctx - > ctx ) ;
2006-10-14 12:56:07 +02:00
NtCurrentTeb ( ) - > glContext = ctx ;
2006-08-29 16:58:49 +02:00
}
}
wine_tsx11_unlock ( ) ;
TRACE ( " returning %s \n " , ( ret ? " True " : " False " ) ) ;
return ret ;
}
2006-11-12 20:23:38 +01:00
/**
* X11DRV_wglShareLists
*
2008-07-01 22:08:30 +02:00
* For OpenGL32 wglShareLists .
2006-11-12 20:23:38 +01:00
*/
2008-12-16 14:18:49 +01:00
BOOL CDECL X11DRV_wglShareLists ( HGLRC hglrc1 , HGLRC hglrc2 ) {
2006-08-29 16:58:49 +02:00
Wine_GLContext * org = ( Wine_GLContext * ) hglrc1 ;
Wine_GLContext * dest = ( Wine_GLContext * ) hglrc2 ;
TRACE ( " (%p, %p) \n " , org , dest ) ;
2008-06-23 22:56:10 +02:00
if ( ! has_opengl ( ) ) return FALSE ;
2006-11-02 22:23:42 +01:00
2006-08-29 16:58:49 +02:00
if ( NULL ! = dest & & dest - > ctx ! = NULL ) {
ERR ( " Could not share display lists, context already created ! \n " ) ;
return FALSE ;
} else {
2009-05-14 17:05:20 +02:00
if ( org & & dest & & ( GetObjectType ( org - > hdc ) = = OBJ_MEMDC ) ^ ( GetObjectType ( dest - > hdc ) = = OBJ_MEMDC ) ) {
WARN ( " Attempting to share a context between a direct and indirect rendering context, expect issues! \n " ) ;
}
2006-08-29 16:58:49 +02:00
if ( org - > ctx = = NULL ) {
wine_tsx11_lock ( ) ;
describeContext ( org ) ;
2007-07-26 20:32:22 +02:00
2009-05-14 17:05:20 +02:00
org - > ctx = create_glxcontext ( gdi_display , org , NULL ) ;
2006-08-29 16:58:49 +02:00
wine_tsx11_unlock ( ) ;
TRACE ( " created a delayed OpenGL context (%p) for Wine context %p \n " , org - > ctx , org ) ;
}
if ( NULL ! = dest ) {
wine_tsx11_lock ( ) ;
describeContext ( dest ) ;
2009-05-14 17:05:20 +02:00
dest - > ctx = create_glxcontext ( gdi_display , dest , org - > ctx ) ;
2006-08-29 16:58:49 +02:00
wine_tsx11_unlock ( ) ;
TRACE ( " created a delayed OpenGL context (%p) for Wine context %p sharing lists with OpenGL ctx %p \n " , dest - > ctx , dest , org - > ctx ) ;
return TRUE ;
}
}
return FALSE ;
}
2006-09-29 14:43:59 +02:00
static BOOL internal_wglUseFontBitmaps ( HDC hdc , DWORD first , DWORD count , DWORD listBase , DWORD ( WINAPI * GetGlyphOutline_ptr ) ( HDC , UINT , UINT , LPGLYPHMETRICS , DWORD , LPVOID , const MAT2 * ) )
2006-09-20 23:23:17 +02:00
{
/* We are running using client-side rendering fonts... */
GLYPHMETRICS gm ;
2008-12-06 14:18:43 +01:00
unsigned int glyph , size = 0 ;
2006-09-20 23:23:17 +02:00
void * bitmap = NULL , * gl_bitmap = NULL ;
int org_alignment ;
wine_tsx11_lock ( ) ;
pglGetIntegerv ( GL_UNPACK_ALIGNMENT , & org_alignment ) ;
pglPixelStorei ( GL_UNPACK_ALIGNMENT , 4 ) ;
wine_tsx11_unlock ( ) ;
for ( glyph = first ; glyph < first + count ; glyph + + ) {
2009-02-03 10:54:48 +01:00
static const MAT2 identity = { { 0 , 1 } , { 0 , 0 } , { 0 , 0 } , { 0 , 1 } } ;
unsigned int needed_size = GetGlyphOutline_ptr ( hdc , glyph , GGO_BITMAP , & gm , 0 , NULL , & identity ) ;
2008-12-06 14:18:43 +01:00
unsigned int height , width_int ;
2006-09-20 23:23:17 +02:00
2006-10-08 01:34:01 +02:00
TRACE ( " Glyph : %3d / List : %d \n " , glyph , listBase ) ;
2006-09-20 23:23:17 +02:00
if ( needed_size = = GDI_ERROR ) {
TRACE ( " - needed size : %d (GDI_ERROR) \n " , needed_size ) ;
goto error ;
} else {
TRACE ( " - needed size : %d \n " , needed_size ) ;
}
if ( needed_size > size ) {
size = needed_size ;
HeapFree ( GetProcessHeap ( ) , 0 , bitmap ) ;
HeapFree ( GetProcessHeap ( ) , 0 , gl_bitmap ) ;
bitmap = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , size ) ;
gl_bitmap = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , size ) ;
}
2009-02-03 10:54:48 +01:00
if ( GetGlyphOutline_ptr ( hdc , glyph , GGO_BITMAP , & gm , size , bitmap , & identity ) = = GDI_ERROR )
goto error ;
2008-03-31 00:21:03 +02:00
if ( TRACE_ON ( wgl ) ) {
2006-09-20 23:23:17 +02:00
unsigned int height , width , bitmask ;
2009-01-19 10:23:40 +01:00
unsigned char * bitmap_ = bitmap ;
2006-09-20 23:23:17 +02:00
TRACE ( " - bbox : %d x %d \n " , gm . gmBlackBoxX , gm . gmBlackBoxY ) ;
2006-10-08 01:34:01 +02:00
TRACE ( " - origin : (%d , %d) \n " , gm . gmptGlyphOrigin . x , gm . gmptGlyphOrigin . y ) ;
2006-09-20 23:23:17 +02:00
TRACE ( " - increment : %d - %d \n " , gm . gmCellIncX , gm . gmCellIncY ) ;
if ( needed_size ! = 0 ) {
TRACE ( " - bitmap : \n " ) ;
for ( height = 0 ; height < gm . gmBlackBoxY ; height + + ) {
TRACE ( " " ) ;
for ( width = 0 , bitmask = 0x80 ; width < gm . gmBlackBoxX ; width + + , bitmask > > = 1 ) {
if ( bitmask = = 0 ) {
bitmap_ + = 1 ;
bitmask = 0x80 ;
}
if ( * bitmap_ & bitmask )
TRACE ( " * " ) ;
else
TRACE ( " " ) ;
}
bitmap_ + = ( 4 - ( ( UINT_PTR ) bitmap_ & 0x03 ) ) ;
TRACE ( " \n " ) ;
}
}
}
/* In OpenGL, the bitmap is drawn from the bottom to the top... So we need to invert the
* glyph for it to be drawn properly .
*/
if ( needed_size ! = 0 ) {
width_int = ( gm . gmBlackBoxX + 31 ) / 32 ;
for ( height = 0 ; height < gm . gmBlackBoxY ; height + + ) {
2008-12-06 14:18:43 +01:00
unsigned int width ;
2006-09-20 23:23:17 +02:00
for ( width = 0 ; width < width_int ; width + + ) {
( ( int * ) gl_bitmap ) [ ( gm . gmBlackBoxY - height - 1 ) * width_int + width ] =
( ( int * ) bitmap ) [ height * width_int + width ] ;
}
}
}
wine_tsx11_lock ( ) ;
pglNewList ( listBase + + , GL_COMPILE ) ;
if ( needed_size ! = 0 ) {
pglBitmap ( gm . gmBlackBoxX , gm . gmBlackBoxY ,
2008-02-02 18:27:19 +01:00
0 - gm . gmptGlyphOrigin . x , ( int ) gm . gmBlackBoxY - gm . gmptGlyphOrigin . y ,
2006-09-20 23:23:17 +02:00
gm . gmCellIncX , gm . gmCellIncY ,
gl_bitmap ) ;
} else {
/* This is the case of 'empty' glyphs like the space character */
pglBitmap ( 0 , 0 , 0 , 0 , gm . gmCellIncX , gm . gmCellIncY , NULL ) ;
}
pglEndList ( ) ;
wine_tsx11_unlock ( ) ;
}
wine_tsx11_lock ( ) ;
pglPixelStorei ( GL_UNPACK_ALIGNMENT , org_alignment ) ;
wine_tsx11_unlock ( ) ;
HeapFree ( GetProcessHeap ( ) , 0 , bitmap ) ;
HeapFree ( GetProcessHeap ( ) , 0 , gl_bitmap ) ;
return TRUE ;
error :
wine_tsx11_lock ( ) ;
pglPixelStorei ( GL_UNPACK_ALIGNMENT , org_alignment ) ;
wine_tsx11_unlock ( ) ;
HeapFree ( GetProcessHeap ( ) , 0 , bitmap ) ;
HeapFree ( GetProcessHeap ( ) , 0 , gl_bitmap ) ;
return FALSE ;
}
2006-11-12 20:23:38 +01:00
/**
* X11DRV_wglUseFontBitmapsA
*
* For OpenGL32 wglUseFontBitmapsA .
*/
2008-12-16 14:18:49 +01:00
BOOL CDECL X11DRV_wglUseFontBitmapsA ( X11DRV_PDEVICE * physDev , DWORD first , DWORD count , DWORD listBase )
2006-09-20 23:23:17 +02:00
{
2006-10-03 21:22:22 +02:00
Font fid = physDev - > font ;
2006-09-20 23:23:17 +02:00
2006-10-08 01:34:01 +02:00
TRACE ( " (%p, %d, %d, %d) using font %ld \n " , physDev - > hdc , first , count , listBase , fid ) ;
2006-09-20 23:23:17 +02:00
2008-06-23 22:56:10 +02:00
if ( ! has_opengl ( ) ) return FALSE ;
2006-11-02 22:23:42 +01:00
2006-09-20 23:23:17 +02:00
if ( fid = = 0 ) {
2006-10-03 21:22:22 +02:00
return internal_wglUseFontBitmaps ( physDev - > hdc , first , count , listBase , GetGlyphOutlineA ) ;
2006-09-20 23:23:17 +02:00
}
wine_tsx11_lock ( ) ;
/* I assume that the glyphs are at the same position for X and for Windows */
pglXUseXFont ( fid , first , count , listBase ) ;
wine_tsx11_unlock ( ) ;
return TRUE ;
}
2006-11-12 20:23:38 +01:00
/**
* X11DRV_wglUseFontBitmapsW
*
* For OpenGL32 wglUseFontBitmapsW .
*/
2008-12-16 14:18:49 +01:00
BOOL CDECL X11DRV_wglUseFontBitmapsW ( X11DRV_PDEVICE * physDev , DWORD first , DWORD count , DWORD listBase )
2006-09-20 23:23:17 +02:00
{
2006-10-03 21:22:22 +02:00
Font fid = physDev - > font ;
2006-09-20 23:23:17 +02:00
2006-10-08 01:34:01 +02:00
TRACE ( " (%p, %d, %d, %d) using font %ld \n " , physDev - > hdc , first , count , listBase , fid ) ;
2006-09-20 23:23:17 +02:00
2008-06-23 22:56:10 +02:00
if ( ! has_opengl ( ) ) return FALSE ;
2006-11-02 22:23:42 +01:00
2006-09-20 23:23:17 +02:00
if ( fid = = 0 ) {
2006-10-03 21:22:22 +02:00
return internal_wglUseFontBitmaps ( physDev - > hdc , first , count , listBase , GetGlyphOutlineW ) ;
2006-09-20 23:23:17 +02:00
}
WARN ( " Using the glX API for the WCHAR variant - some characters may come out incorrectly ! \n " ) ;
wine_tsx11_lock ( ) ;
/* I assume that the glyphs are at the same position for X and for Windows */
pglXUseXFont ( fid , first , count , listBase ) ;
wine_tsx11_unlock ( ) ;
return TRUE ;
}
2006-08-29 16:58:49 +02:00
2006-12-07 16:45:58 +01:00
/* WGL helper function which handles differences in glGetIntegerv from WGL and GLX */
2006-12-12 18:21:01 +01:00
static void WINAPI X11DRV_wglGetIntegerv ( GLenum pname , GLint * params )
{
wine_tsx11_lock ( ) ;
switch ( pname )
{
case GL_DEPTH_BITS :
{
2007-08-23 12:52:57 +02:00
Wine_GLContext * ctx = NtCurrentTeb ( ) - > glContext ;
2006-12-12 18:21:01 +01:00
pglGetIntegerv ( pname , params ) ;
/**
* if we cannot find a Wine Context
* we only have the default wine desktop context ,
* so if we have only a 24 depth say we have 32
*/
2007-08-23 12:52:57 +02:00
if ( ! ctx & & * params = = 24 ) {
2006-12-12 18:21:01 +01:00
* params = 32 ;
}
TRACE ( " returns GL_DEPTH_BITS as '%d' \n " , * params ) ;
break ;
2006-08-29 16:56:57 +02:00
}
2006-12-12 18:21:01 +01:00
case GL_ALPHA_BITS :
{
2007-08-23 12:52:57 +02:00
Wine_GLContext * ctx = NtCurrentTeb ( ) - > glContext ;
2006-12-12 18:21:01 +01:00
2007-08-23 12:52:57 +02:00
pglXGetFBConfigAttrib ( gdi_display , ctx - > fmt - > fbconfig , GLX_ALPHA_SIZE , params ) ;
2006-12-12 18:21:01 +01:00
TRACE ( " returns GL_ALPHA_BITS as '%d' \n " , * params ) ;
break ;
}
default :
pglGetIntegerv ( pname , params ) ;
break ;
2006-08-29 16:56:57 +02:00
}
2006-12-12 18:21:01 +01:00
wine_tsx11_unlock ( ) ;
2006-08-29 16:56:57 +02:00
}
2007-10-10 17:33:35 +02:00
void flush_gl_drawable ( X11DRV_PDEVICE * physDev )
2007-09-26 07:43:38 +02:00
{
int w , h ;
2008-05-28 17:52:06 +02:00
if ( ! physDev - > gl_copy )
2007-09-26 07:43:38 +02:00
return ;
w = physDev - > dc_rect . right - physDev - > dc_rect . left ;
h = physDev - > dc_rect . bottom - physDev - > dc_rect . top ;
if ( w > 0 & & h > 0 ) {
2007-09-26 17:17:13 +02:00
Drawable src = physDev - > pixmap ;
if ( ! src ) src = physDev - > gl_drawable ;
2007-09-26 07:43:38 +02:00
/* The GL drawable may be lagged behind if we don't flush first, so
* flush the display make sure we copy up - to - date data */
2007-10-10 17:33:35 +02:00
wine_tsx11_lock ( ) ;
2007-09-26 07:43:38 +02:00
XFlush ( gdi_display ) ;
2008-09-30 09:02:54 +02:00
XSetFunction ( gdi_display , physDev - > gc , GXcopy ) ;
2007-09-26 17:17:13 +02:00
XCopyArea ( gdi_display , src , physDev - > drawable , physDev - > gc , 0 , 0 , w , h ,
physDev - > dc_rect . left , physDev - > dc_rect . top ) ;
2007-10-10 17:33:35 +02:00
wine_tsx11_unlock ( ) ;
2007-09-26 07:43:38 +02:00
}
}
2007-09-23 05:45:27 +02:00
static void WINAPI X11DRV_wglFinish ( void )
{
2007-09-26 16:15:52 +02:00
Wine_GLContext * ctx = NtCurrentTeb ( ) - > glContext ;
2007-10-10 17:33:35 +02:00
enum x11drv_escape_codes code = X11DRV_FLUSH_GL_DRAWABLE ;
2007-09-26 16:15:52 +02:00
2007-09-23 05:45:27 +02:00
wine_tsx11_lock ( ) ;
2007-09-26 16:15:52 +02:00
sync_context ( ctx ) ;
2007-09-23 05:45:27 +02:00
pglFinish ( ) ;
wine_tsx11_unlock ( ) ;
2008-05-14 12:46:25 +02:00
if ( ctx ) ExtEscape ( ctx - > hdc , X11DRV_ESCAPE , sizeof ( code ) , ( LPSTR ) & code , 0 , NULL ) ;
2007-09-23 05:45:27 +02:00
}
static void WINAPI X11DRV_wglFlush ( void )
{
2007-09-26 16:15:52 +02:00
Wine_GLContext * ctx = NtCurrentTeb ( ) - > glContext ;
2007-10-10 17:33:35 +02:00
enum x11drv_escape_codes code = X11DRV_FLUSH_GL_DRAWABLE ;
2007-09-26 16:15:52 +02:00
2007-09-23 05:45:27 +02:00
wine_tsx11_lock ( ) ;
2007-09-26 16:15:52 +02:00
sync_context ( ctx ) ;
2007-09-23 05:45:27 +02:00
pglFlush ( ) ;
wine_tsx11_unlock ( ) ;
2008-05-14 12:46:25 +02:00
if ( ctx ) ExtEscape ( ctx - > hdc , X11DRV_ESCAPE , sizeof ( code ) , ( LPSTR ) & code , 0 , NULL ) ;
2007-09-23 05:45:27 +02:00
}
2006-11-12 20:23:38 +01:00
/**
* X11DRV_wglGetExtensionsStringARB
*
* WGL_ARB_extensions_string : wglGetExtensionsStringARB
*/
2006-09-11 21:28:32 +02:00
static const char * WINAPI X11DRV_wglGetExtensionsStringARB ( HDC hdc ) {
TRACE ( " () returning \" %s \" \n " , WineGLInfo . wglExtensions ) ;
return WineGLInfo . wglExtensions ;
}
2006-11-12 20:23:38 +01:00
/**
* X11DRV_wglCreatePbufferARB
*
* WGL_ARB_pbuffer : wglCreatePbufferARB
*/
2006-09-11 21:28:32 +02:00
static HPBUFFERARB WINAPI X11DRV_wglCreatePbufferARB ( HDC hdc , int iPixelFormat , int iWidth , int iHeight , const int * piAttribList )
{
Wine_GLPBuffer * object = NULL ;
2007-07-26 19:23:39 +02:00
WineGLPixelFormat * fmt = NULL ;
2006-09-11 21:28:32 +02:00
int nCfgs = 0 ;
int attribs [ 256 ] ;
2007-02-03 23:39:18 +01:00
int nAttribs = 0 ;
2006-09-11 21:28:32 +02:00
TRACE ( " (%p, %d, %d, %d, %p) \n " , hdc , iPixelFormat , iWidth , iHeight , piAttribList ) ;
if ( 0 > = iPixelFormat ) {
ERR ( " (%p): unexpected iPixelFormat(%d) <= 0, returns NULL \n " , hdc , iPixelFormat ) ;
SetLastError ( ERROR_INVALID_PIXEL_FORMAT ) ;
return NULL ; /* unexpected error */
}
/* Convert the WGL pixelformat to a GLX format, if it fails then the format is invalid */
2007-07-26 20:32:22 +02:00
fmt = ConvertPixelFormatWGLtoGLX ( gdi_display , iPixelFormat , TRUE /* Offscreen */ , & nCfgs ) ;
2007-07-26 19:23:39 +02:00
if ( ! fmt ) {
2006-09-11 21:28:32 +02:00
ERR ( " (%p): unexpected iPixelFormat(%d) > nFormats(%d), returns NULL \n " , hdc , iPixelFormat , nCfgs ) ;
SetLastError ( ERROR_INVALID_PIXEL_FORMAT ) ;
goto create_failed ; /* unexpected error */
}
object = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , sizeof ( Wine_GLPBuffer ) ) ;
if ( NULL = = object ) {
SetLastError ( ERROR_NO_SYSTEM_RESOURCES ) ;
goto create_failed ; /* unexpected error */
}
object - > hdc = hdc ;
object - > display = gdi_display ;
object - > width = iWidth ;
object - > height = iHeight ;
2007-07-27 15:19:46 +02:00
object - > fmt = fmt ;
2006-09-11 21:28:32 +02:00
PUSH2 ( attribs , GLX_PBUFFER_WIDTH , iWidth ) ;
PUSH2 ( attribs , GLX_PBUFFER_HEIGHT , iHeight ) ;
2007-01-04 00:15:54 +01:00
while ( piAttribList & & 0 ! = * piAttribList ) {
2006-09-11 21:28:32 +02:00
int attr_v ;
switch ( * piAttribList ) {
2007-08-02 22:52:22 +02:00
case WGL_PBUFFER_LARGEST_ARB : {
+ + piAttribList ;
attr_v = * piAttribList ;
TRACE ( " WGL_LARGEST_PBUFFER_ARB = %d \n " , attr_v ) ;
PUSH2 ( attribs , GLX_LARGEST_PBUFFER , attr_v ) ;
break ;
}
2006-09-11 21:28:32 +02:00
case WGL_TEXTURE_FORMAT_ARB : {
+ + piAttribList ;
attr_v = * piAttribList ;
TRACE ( " WGL_render_texture Attribute: WGL_TEXTURE_FORMAT_ARB as %x \n " , attr_v ) ;
if ( use_render_texture_ati ) {
int type = 0 ;
switch ( attr_v ) {
case WGL_NO_TEXTURE_ARB : type = GLX_NO_TEXTURE_ATI ; break ;
case WGL_TEXTURE_RGB_ARB : type = GLX_TEXTURE_RGB_ATI ; break ;
case WGL_TEXTURE_RGBA_ARB : type = GLX_TEXTURE_RGBA_ATI ; break ;
default :
SetLastError ( ERROR_INVALID_DATA ) ;
goto create_failed ;
}
object - > use_render_texture = 1 ;
PUSH2 ( attribs , GLX_TEXTURE_FORMAT_ATI , type ) ;
} else {
if ( WGL_NO_TEXTURE_ARB = = attr_v ) {
object - > use_render_texture = 0 ;
} else {
if ( ! use_render_texture_emulation ) {
SetLastError ( ERROR_INVALID_DATA ) ;
goto create_failed ;
}
switch ( attr_v ) {
case WGL_TEXTURE_RGB_ARB :
object - > use_render_texture = GL_RGB ;
2007-07-28 00:20:44 +02:00
object - > texture_bpp = 3 ;
object - > texture_format = GL_RGB ;
object - > texture_type = GL_UNSIGNED_BYTE ;
2006-09-11 21:28:32 +02:00
break ;
case WGL_TEXTURE_RGBA_ARB :
object - > use_render_texture = GL_RGBA ;
2007-07-28 00:20:44 +02:00
object - > texture_bpp = 4 ;
object - > texture_format = GL_RGBA ;
object - > texture_type = GL_UNSIGNED_BYTE ;
2006-09-11 21:28:32 +02:00
break ;
2007-07-27 15:01:52 +02:00
/* WGL_FLOAT_COMPONENTS_NV */
case WGL_TEXTURE_FLOAT_R_NV :
object - > use_render_texture = GL_FLOAT_R_NV ;
2007-07-28 00:20:44 +02:00
object - > texture_bpp = 4 ;
object - > texture_format = GL_RED ;
object - > texture_type = GL_FLOAT ;
2007-07-27 15:01:52 +02:00
break ;
case WGL_TEXTURE_FLOAT_RG_NV :
object - > use_render_texture = GL_FLOAT_RG_NV ;
2007-07-28 00:20:44 +02:00
object - > texture_bpp = 8 ;
object - > texture_format = GL_LUMINANCE_ALPHA ;
object - > texture_type = GL_FLOAT ;
2007-07-27 15:01:52 +02:00
break ;
case WGL_TEXTURE_FLOAT_RGB_NV :
object - > use_render_texture = GL_FLOAT_RGB_NV ;
2007-07-28 00:20:44 +02:00
object - > texture_bpp = 12 ;
object - > texture_format = GL_RGB ;
object - > texture_type = GL_FLOAT ;
2007-07-27 15:01:52 +02:00
break ;
case WGL_TEXTURE_FLOAT_RGBA_NV :
object - > use_render_texture = GL_FLOAT_RGBA_NV ;
2007-07-28 00:20:44 +02:00
object - > texture_bpp = 16 ;
object - > texture_format = GL_RGBA ;
object - > texture_type = GL_FLOAT ;
2007-07-27 15:01:52 +02:00
break ;
2006-09-11 21:28:32 +02:00
default :
2007-07-27 15:01:52 +02:00
ERR ( " Unknown texture format: %x \n " , attr_v ) ;
2006-09-11 21:28:32 +02:00
SetLastError ( ERROR_INVALID_DATA ) ;
goto create_failed ;
}
}
}
break ;
}
case WGL_TEXTURE_TARGET_ARB : {
+ + piAttribList ;
attr_v = * piAttribList ;
TRACE ( " WGL_render_texture Attribute: WGL_TEXTURE_TARGET_ARB as %x \n " , attr_v ) ;
if ( use_render_texture_ati ) {
int type = 0 ;
switch ( attr_v ) {
case WGL_NO_TEXTURE_ARB : type = GLX_NO_TEXTURE_ATI ; break ;
case WGL_TEXTURE_CUBE_MAP_ARB : type = GLX_TEXTURE_CUBE_MAP_ATI ; break ;
case WGL_TEXTURE_1D_ARB : type = GLX_TEXTURE_1D_ATI ; break ;
case WGL_TEXTURE_2D_ARB : type = GLX_TEXTURE_2D_ATI ; break ;
default :
SetLastError ( ERROR_INVALID_DATA ) ;
goto create_failed ;
}
PUSH2 ( attribs , GLX_TEXTURE_TARGET_ATI , type ) ;
} else {
if ( WGL_NO_TEXTURE_ARB = = attr_v ) {
object - > texture_target = 0 ;
} else {
if ( ! use_render_texture_emulation ) {
SetLastError ( ERROR_INVALID_DATA ) ;
goto create_failed ;
}
switch ( attr_v ) {
case WGL_TEXTURE_CUBE_MAP_ARB : {
if ( iWidth ! = iHeight ) {
SetLastError ( ERROR_INVALID_DATA ) ;
goto create_failed ;
}
object - > texture_target = GL_TEXTURE_CUBE_MAP ;
2007-07-29 14:13:45 +02:00
object - > texture_bind_target = GL_TEXTURE_BINDING_CUBE_MAP ;
2006-09-11 21:28:32 +02:00
break ;
}
case WGL_TEXTURE_1D_ARB : {
if ( 1 ! = iHeight ) {
SetLastError ( ERROR_INVALID_DATA ) ;
goto create_failed ;
}
object - > texture_target = GL_TEXTURE_1D ;
2007-07-29 14:13:45 +02:00
object - > texture_bind_target = GL_TEXTURE_BINDING_1D ;
2006-09-11 21:28:32 +02:00
break ;
}
case WGL_TEXTURE_2D_ARB : {
object - > texture_target = GL_TEXTURE_2D ;
2007-07-29 14:13:45 +02:00
object - > texture_bind_target = GL_TEXTURE_BINDING_2D ;
2006-09-11 21:28:32 +02:00
break ;
}
2007-07-27 15:01:52 +02:00
case WGL_TEXTURE_RECTANGLE_NV : {
object - > texture_target = GL_TEXTURE_RECTANGLE_NV ;
object - > texture_bind_target = GL_TEXTURE_BINDING_RECTANGLE_NV ;
break ;
}
2006-09-11 21:28:32 +02:00
default :
2007-07-27 15:01:52 +02:00
ERR ( " Unknown texture target: %x \n " , attr_v ) ;
2006-09-11 21:28:32 +02:00
SetLastError ( ERROR_INVALID_DATA ) ;
goto create_failed ;
}
}
}
break ;
}
case WGL_MIPMAP_TEXTURE_ARB : {
+ + piAttribList ;
attr_v = * piAttribList ;
TRACE ( " WGL_render_texture Attribute: WGL_MIPMAP_TEXTURE_ARB as %x \n " , attr_v ) ;
if ( use_render_texture_ati ) {
PUSH2 ( attribs , GLX_MIPMAP_TEXTURE_ATI , attr_v ) ;
} else {
if ( ! use_render_texture_emulation ) {
SetLastError ( ERROR_INVALID_DATA ) ;
goto create_failed ;
}
}
break ;
}
}
+ + piAttribList ;
}
PUSH1 ( attribs , None ) ;
2008-05-28 17:02:07 +02:00
wine_tsx11_lock ( ) ;
2007-07-26 19:23:39 +02:00
object - > drawable = pglXCreatePbuffer ( gdi_display , fmt - > fbconfig , attribs ) ;
2008-05-28 17:02:07 +02:00
wine_tsx11_unlock ( ) ;
2006-09-11 21:28:32 +02:00
TRACE ( " new Pbuffer drawable as %p \n " , ( void * ) object - > drawable ) ;
if ( ! object - > drawable ) {
SetLastError ( ERROR_NO_SYSTEM_RESOURCES ) ;
goto create_failed ; /* unexpected error */
}
TRACE ( " ->(%p) \n " , object ) ;
2008-12-01 02:09:52 +01:00
return object ;
2006-09-11 21:28:32 +02:00
create_failed :
HeapFree ( GetProcessHeap ( ) , 0 , object ) ;
TRACE ( " ->(FAILED) \n " ) ;
2008-02-02 18:27:19 +01:00
return NULL ;
2006-09-11 21:28:32 +02:00
}
2006-11-12 20:23:38 +01:00
/**
* X11DRV_wglDestroyPbufferARB
*
* WGL_ARB_pbuffer : wglDestroyPbufferARB
*/
2006-09-11 21:28:32 +02:00
static GLboolean WINAPI X11DRV_wglDestroyPbufferARB ( HPBUFFERARB hPbuffer )
{
2009-01-19 10:23:40 +01:00
Wine_GLPBuffer * object = hPbuffer ;
2006-09-11 21:28:32 +02:00
TRACE ( " (%p) \n " , hPbuffer ) ;
if ( NULL = = object ) {
SetLastError ( ERROR_INVALID_HANDLE ) ;
return GL_FALSE ;
}
2008-05-28 17:02:07 +02:00
wine_tsx11_lock ( ) ;
2006-09-11 21:28:32 +02:00
pglXDestroyPbuffer ( object - > display , object - > drawable ) ;
2008-05-28 17:02:07 +02:00
wine_tsx11_unlock ( ) ;
2006-09-11 21:28:32 +02:00
HeapFree ( GetProcessHeap ( ) , 0 , object ) ;
return GL_TRUE ;
}
2006-11-12 20:23:38 +01:00
/**
* X11DRV_wglGetPbufferDCARB
*
* WGL_ARB_pbuffer : wglGetPbufferDCARB
2006-11-04 22:23:15 +01:00
* The function wglGetPbufferDCARB returns a device context for a pbuffer .
* Gdi32 implements the part of this function which creates a device context .
* This part associates the physDev with the X drawable of the pbuffer .
*/
2008-12-16 14:18:49 +01:00
HDC CDECL X11DRV_wglGetPbufferDCARB ( X11DRV_PDEVICE * physDev , HPBUFFERARB hPbuffer )
2006-09-11 21:28:32 +02:00
{
2009-01-19 10:23:40 +01:00
Wine_GLPBuffer * object = hPbuffer ;
2006-09-11 21:28:32 +02:00
if ( NULL = = object ) {
SetLastError ( ERROR_INVALID_HANDLE ) ;
return NULL ;
}
/* The function wglGetPbufferDCARB returns a DC to which the pbuffer can be connected.
2006-12-10 19:17:03 +01:00
* All formats in our pixelformat list are compatible with each other and the main drawable . */
2007-07-27 15:19:46 +02:00
physDev - > current_pf = object - > fmt - > iPixelFormat ;
2006-11-04 22:23:15 +01:00
physDev - > drawable = object - > drawable ;
2007-07-25 23:18:50 +02:00
SetRect ( & physDev - > drawable_rect , 0 , 0 , object - > width , object - > height ) ;
physDev - > dc_rect = physDev - > drawable_rect ;
2006-11-04 22:23:15 +01:00
TRACE ( " (%p)->(%p) \n " , hPbuffer , physDev - > hdc ) ;
return physDev - > hdc ;
2006-09-11 21:28:32 +02:00
}
2006-11-12 20:23:38 +01:00
/**
* X11DRV_wglQueryPbufferARB
*
* WGL_ARB_pbuffer : wglQueryPbufferARB
*/
2006-09-11 21:28:32 +02:00
static GLboolean WINAPI X11DRV_wglQueryPbufferARB ( HPBUFFERARB hPbuffer , int iAttribute , int * piValue )
{
2009-01-19 10:23:40 +01:00
Wine_GLPBuffer * object = hPbuffer ;
2006-09-11 21:28:32 +02:00
TRACE ( " (%p, 0x%x, %p) \n " , hPbuffer , iAttribute , piValue ) ;
if ( NULL = = object ) {
SetLastError ( ERROR_INVALID_HANDLE ) ;
return GL_FALSE ;
}
switch ( iAttribute ) {
case WGL_PBUFFER_WIDTH_ARB :
2008-05-28 17:02:07 +02:00
wine_tsx11_lock ( ) ;
2006-09-11 21:28:32 +02:00
pglXQueryDrawable ( object - > display , object - > drawable , GLX_WIDTH , ( unsigned int * ) piValue ) ;
2008-05-28 17:02:07 +02:00
wine_tsx11_unlock ( ) ;
2006-09-11 21:28:32 +02:00
break ;
case WGL_PBUFFER_HEIGHT_ARB :
2008-05-28 17:02:07 +02:00
wine_tsx11_lock ( ) ;
2006-09-11 21:28:32 +02:00
pglXQueryDrawable ( object - > display , object - > drawable , GLX_HEIGHT , ( unsigned int * ) piValue ) ;
2008-05-28 17:02:07 +02:00
wine_tsx11_unlock ( ) ;
2006-09-11 21:28:32 +02:00
break ;
case WGL_PBUFFER_LOST_ARB :
2007-08-04 20:12:36 +02:00
/* GLX Pbuffers cannot be lost by default. We can support this by
* setting GLX_PRESERVED_CONTENTS to False and using glXSelectEvent
* to receive pixel buffer clobber events , however that may or may
* not give any benefit */
* piValue = GL_FALSE ;
2006-09-11 21:28:32 +02:00
break ;
case WGL_TEXTURE_FORMAT_ARB :
if ( use_render_texture_ati ) {
unsigned int tmp ;
int type = WGL_NO_TEXTURE_ARB ;
2008-05-28 17:02:07 +02:00
wine_tsx11_lock ( ) ;
2006-09-11 21:28:32 +02:00
pglXQueryDrawable ( object - > display , object - > drawable , GLX_TEXTURE_FORMAT_ATI , & tmp ) ;
2008-05-28 17:02:07 +02:00
wine_tsx11_unlock ( ) ;
2006-09-11 21:28:32 +02:00
switch ( tmp ) {
case GLX_NO_TEXTURE_ATI : type = WGL_NO_TEXTURE_ARB ; break ;
case GLX_TEXTURE_RGB_ATI : type = WGL_TEXTURE_RGB_ARB ; break ;
case GLX_TEXTURE_RGBA_ATI : type = WGL_TEXTURE_RGBA_ARB ; break ;
}
* piValue = type ;
} else {
if ( ! object - > use_render_texture ) {
* piValue = WGL_NO_TEXTURE_ARB ;
} else {
if ( ! use_render_texture_emulation ) {
SetLastError ( ERROR_INVALID_HANDLE ) ;
return GL_FALSE ;
}
2007-07-27 15:01:52 +02:00
switch ( object - > use_render_texture ) {
case GL_RGB :
* piValue = WGL_TEXTURE_RGB_ARB ;
break ;
case GL_RGBA :
* piValue = WGL_TEXTURE_RGBA_ARB ;
break ;
/* WGL_FLOAT_COMPONENTS_NV */
case GL_FLOAT_R_NV :
* piValue = WGL_TEXTURE_FLOAT_R_NV ;
break ;
case GL_FLOAT_RG_NV :
* piValue = WGL_TEXTURE_FLOAT_RG_NV ;
break ;
case GL_FLOAT_RGB_NV :
* piValue = WGL_TEXTURE_FLOAT_RGB_NV ;
break ;
case GL_FLOAT_RGBA_NV :
* piValue = WGL_TEXTURE_FLOAT_RGBA_NV ;
break ;
default :
ERR ( " Unknown texture format: %x \n " , object - > use_render_texture ) ;
2006-09-11 21:28:32 +02:00
}
}
}
break ;
case WGL_TEXTURE_TARGET_ARB :
if ( use_render_texture_ati ) {
unsigned int tmp ;
int type = WGL_NO_TEXTURE_ARB ;
2008-05-28 17:02:07 +02:00
wine_tsx11_lock ( ) ;
2006-09-11 21:28:32 +02:00
pglXQueryDrawable ( object - > display , object - > drawable , GLX_TEXTURE_TARGET_ATI , & tmp ) ;
2008-05-28 17:02:07 +02:00
wine_tsx11_unlock ( ) ;
2006-09-11 21:28:32 +02:00
switch ( tmp ) {
case GLX_NO_TEXTURE_ATI : type = WGL_NO_TEXTURE_ARB ; break ;
case GLX_TEXTURE_CUBE_MAP_ATI : type = WGL_TEXTURE_CUBE_MAP_ARB ; break ;
case GLX_TEXTURE_1D_ATI : type = WGL_TEXTURE_1D_ARB ; break ;
case GLX_TEXTURE_2D_ATI : type = WGL_TEXTURE_2D_ARB ; break ;
}
* piValue = type ;
} else {
if ( ! object - > texture_target ) {
* piValue = WGL_NO_TEXTURE_ARB ;
} else {
if ( ! use_render_texture_emulation ) {
SetLastError ( ERROR_INVALID_DATA ) ;
return GL_FALSE ;
}
switch ( object - > texture_target ) {
2007-07-27 11:00:19 +02:00
case GL_TEXTURE_1D : * piValue = WGL_TEXTURE_1D_ARB ; break ;
case GL_TEXTURE_2D : * piValue = WGL_TEXTURE_2D_ARB ; break ;
case GL_TEXTURE_CUBE_MAP : * piValue = WGL_TEXTURE_CUBE_MAP_ARB ; break ;
2007-07-27 15:01:52 +02:00
case GL_TEXTURE_RECTANGLE_NV : * piValue = WGL_TEXTURE_RECTANGLE_NV ; break ;
2006-09-11 21:28:32 +02:00
}
}
}
break ;
case WGL_MIPMAP_TEXTURE_ARB :
if ( use_render_texture_ati ) {
2008-05-28 17:02:07 +02:00
wine_tsx11_lock ( ) ;
2006-09-11 21:28:32 +02:00
pglXQueryDrawable ( object - > display , object - > drawable , GLX_MIPMAP_TEXTURE_ATI , ( unsigned int * ) piValue ) ;
2008-05-28 17:02:07 +02:00
wine_tsx11_unlock ( ) ;
2006-09-11 21:28:32 +02:00
} else {
* piValue = GL_FALSE ; /** don't support that */
FIXME ( " unsupported WGL_ARB_render_texture attribute query for 0x%x \n " , iAttribute ) ;
}
break ;
default :
FIXME ( " unexpected attribute %x \n " , iAttribute ) ;
break ;
}
return GL_TRUE ;
}
2006-11-12 20:23:38 +01:00
/**
* X11DRV_wglReleasePbufferDCARB
*
* WGL_ARB_pbuffer : wglReleasePbufferDCARB
*/
2006-09-11 21:28:32 +02:00
static int WINAPI X11DRV_wglReleasePbufferDCARB ( HPBUFFERARB hPbuffer , HDC hdc )
{
TRACE ( " (%p, %p) \n " , hPbuffer , hdc ) ;
2008-03-22 13:36:20 +01:00
return DeleteDC ( hdc ) ;
2006-09-11 21:28:32 +02:00
}
2006-11-12 20:23:38 +01:00
/**
* X11DRV_wglSetPbufferAttribARB
*
* WGL_ARB_pbuffer : wglSetPbufferAttribARB
*/
2006-09-11 21:28:32 +02:00
static GLboolean WINAPI X11DRV_wglSetPbufferAttribARB ( HPBUFFERARB hPbuffer , const int * piAttribList )
{
2009-01-19 10:23:40 +01:00
Wine_GLPBuffer * object = hPbuffer ;
2008-05-28 17:02:07 +02:00
GLboolean ret = GL_FALSE ;
2006-09-11 21:28:32 +02:00
WARN ( " (%p, %p): alpha-testing, report any problem \n " , hPbuffer , piAttribList ) ;
if ( NULL = = object ) {
SetLastError ( ERROR_INVALID_HANDLE ) ;
return GL_FALSE ;
}
if ( ! object - > use_render_texture ) {
SetLastError ( ERROR_INVALID_HANDLE ) ;
return GL_FALSE ;
}
if ( ! use_render_texture_ati & & 1 = = use_render_texture_emulation ) {
return GL_TRUE ;
}
2007-08-12 17:31:25 +02:00
if ( NULL ! = pglXDrawableAttribATI ) {
2006-09-11 21:28:32 +02:00
if ( use_render_texture_ati ) {
FIXME ( " Need conversion for GLX_ATI_render_texture \n " ) ;
}
2008-05-28 17:02:07 +02:00
wine_tsx11_lock ( ) ;
ret = pglXDrawableAttribATI ( object - > display , object - > drawable , piAttribList ) ;
wine_tsx11_unlock ( ) ;
2006-09-11 21:28:32 +02:00
}
2008-05-28 17:02:07 +02:00
return ret ;
2006-09-11 21:28:32 +02:00
}
2006-11-12 20:23:38 +01:00
/**
* X11DRV_wglChoosePixelFormatARB
*
* WGL_ARB_pixel_format : wglChoosePixelFormatARB
*/
2006-10-31 21:41:02 +01:00
static GLboolean WINAPI X11DRV_wglChoosePixelFormatARB ( HDC hdc , const int * piAttribIList , const FLOAT * pfAttribFList , UINT nMaxFormats , int * piFormats , UINT * nNumFormats )
2006-09-11 21:28:32 +02:00
{
int gl_test = 0 ;
int attribs [ 256 ] ;
int nAttribs = 0 ;
GLXFBConfig * cfgs = NULL ;
int nCfgs = 0 ;
2008-12-06 14:18:43 +01:00
int it ;
2006-09-11 21:28:32 +02:00
int fmt_id ;
2007-08-10 15:35:02 +02:00
WineGLPixelFormat * fmt ;
2008-12-06 14:18:43 +01:00
UINT pfmt_it = 0 ;
2007-08-10 15:35:02 +02:00
int run ;
2009-05-16 21:50:58 +02:00
int i ;
DWORD dwFlags = 0 ;
2006-09-11 21:28:32 +02:00
TRACE ( " (%p, %p, %p, %d, %p, %p): hackish \n " , hdc , piAttribIList , pfAttribFList , nMaxFormats , piFormats , nNumFormats ) ;
if ( NULL ! = pfAttribFList ) {
FIXME ( " unused pfAttribFList \n " ) ;
}
nAttribs = ConvertAttribWGLtoGLX ( piAttribIList , attribs , NULL ) ;
if ( - 1 = = nAttribs ) {
WARN ( " Cannot convert WGL to GLX attributes \n " ) ;
return GL_FALSE ;
}
PUSH1 ( attribs , None ) ;
2009-05-16 21:50:58 +02:00
/* There is no 1:1 mapping between GLX and WGL formats because we duplicate some GLX formats for bitmap rendering (see get_formats).
* Flags like PFD_SUPPORT_GDI , PFD_DRAW_TO_BITMAP and others are a property of the WineGLPixelFormat . We don ' t query these attributes
* using glXChooseFBConfig but we filter the result of glXChooseFBConfig later on by passing a dwFlags to ' ConvertPixelFormatGLXtoWGL ' . */
for ( i = 0 ; piAttribIList [ i ] ! = 0 ; i + = 2 )
{
2009-05-17 21:50:56 +02:00
switch ( piAttribIList [ i ] )
2009-05-16 21:50:58 +02:00
{
2009-05-17 21:50:56 +02:00
case WGL_DRAW_TO_BITMAP_ARB :
if ( piAttribIList [ i + 1 ] )
dwFlags | = PFD_DRAW_TO_BITMAP ;
break ;
2009-05-19 00:23:05 +02:00
case WGL_ACCELERATION_ARB :
switch ( piAttribIList [ i + 1 ] )
{
case WGL_NO_ACCELERATION_ARB :
dwFlags | = PFD_GENERIC_FORMAT ;
break ;
case WGL_GENERIC_ACCELERATION_ARB :
dwFlags | = PFD_GENERIC_ACCELERATED ;
break ;
case WGL_FULL_ACCELERATION_ARB :
/* Nothing to do */
break ;
}
break ;
2009-05-17 21:50:56 +02:00
case WGL_SUPPORT_GDI_ARB :
if ( piAttribIList [ i + 1 ] )
dwFlags | = PFD_SUPPORT_GDI ;
break ;
2009-05-16 21:50:58 +02:00
}
}
2006-09-11 21:28:32 +02:00
/* Search for FB configurations matching the requirements in attribs */
2008-05-28 17:02:07 +02:00
wine_tsx11_lock ( ) ;
2006-09-11 21:28:32 +02:00
cfgs = pglXChooseFBConfig ( gdi_display , DefaultScreen ( gdi_display ) , attribs , & nCfgs ) ;
if ( NULL = = cfgs ) {
2008-05-28 17:02:07 +02:00
wine_tsx11_unlock ( ) ;
2006-09-11 21:28:32 +02:00
WARN ( " Compatible Pixel Format not found \n " ) ;
return GL_FALSE ;
}
/* Loop through all matching formats and check if they are suitable.
* Note that this function should at max return nMaxFormats different formats */
2007-08-10 15:35:02 +02:00
for ( run = 0 ; run < 2 ; run + + )
{
for ( it = 0 ; it < nCfgs ; + + it ) {
gl_test = pglXGetFBConfigAttrib ( gdi_display , cfgs [ it ] , GLX_FBCONFIG_ID , & fmt_id ) ;
if ( gl_test ) {
ERR ( " Failed to retrieve FBCONFIG_ID from GLXFBConfig, expect problems. \n " ) ;
continue ;
}
2006-09-11 21:28:32 +02:00
2007-08-10 15:35:02 +02:00
/* Search for the format in our list of compatible formats */
2009-05-16 21:50:58 +02:00
fmt = ConvertPixelFormatGLXtoWGL ( gdi_display , fmt_id , dwFlags ) ;
2007-08-10 15:35:02 +02:00
if ( ! fmt )
continue ;
2006-09-11 21:28:32 +02:00
2007-08-10 15:35:02 +02:00
/* During the first run we only want onscreen formats and during the second only offscreen 'XOR' */
if ( ( ( run = = 0 ) & & fmt - > offscreenOnly ) | | ( ( run = = 1 ) & & ! fmt - > offscreenOnly ) )
continue ;
if ( pfmt_it < nMaxFormats ) {
piFormats [ pfmt_it ] = fmt - > iPixelFormat ;
TRACE ( " at %d/%d found FBCONFIG_ID 0x%x (%d) \n " , it + 1 , nCfgs , fmt_id , piFormats [ pfmt_it ] ) ;
}
pfmt_it + + ;
2007-08-01 23:20:54 +02:00
}
2006-09-11 21:28:32 +02:00
}
* nNumFormats = pfmt_it ;
/** free list */
XFree ( cfgs ) ;
2008-05-28 17:02:07 +02:00
wine_tsx11_unlock ( ) ;
2006-09-11 21:28:32 +02:00
return GL_TRUE ;
}
2006-11-12 20:23:38 +01:00
/**
* X11DRV_wglGetPixelFormatAttribivARB
*
* WGL_ARB_pixel_format : wglGetPixelFormatAttribivARB
*/
2006-10-31 21:41:02 +01:00
static GLboolean WINAPI X11DRV_wglGetPixelFormatAttribivARB ( HDC hdc , int iPixelFormat , int iLayerPlane , UINT nAttributes , const int * piAttributes , int * piValues )
2006-09-11 21:28:32 +02:00
{
UINT i ;
2007-07-26 19:23:39 +02:00
WineGLPixelFormat * fmt = NULL ;
2006-09-11 21:28:32 +02:00
int hTest ;
int tmp ;
int curGLXAttr = 0 ;
int nWGLFormats = 0 ;
TRACE ( " (%p, %d, %d, %d, %p, %p) \n " , hdc , iPixelFormat , iLayerPlane , nAttributes , piAttributes , piValues ) ;
if ( 0 < iLayerPlane ) {
FIXME ( " unsupported iLayerPlane(%d) > 0, returns FALSE \n " , iLayerPlane ) ;
return GL_FALSE ;
}
2008-01-04 20:37:14 +01:00
/* Convert the WGL pixelformat to a GLX one, if this fails then most likely the iPixelFormat isn't supported.
* We don ' t have to fail yet as a program can specify an invalid iPixelFormat ( lets say 0 ) if it wants to query
2006-09-11 21:28:32 +02:00
* the number of supported WGL formats . Whether the iPixelFormat is valid is handled in the for - loop below . */
2007-07-26 20:32:22 +02:00
fmt = ConvertPixelFormatWGLtoGLX ( gdi_display , iPixelFormat , TRUE /* Offscreen */ , & nWGLFormats ) ;
2007-07-26 19:23:39 +02:00
if ( ! fmt ) {
2006-12-03 03:06:42 +01:00
WARN ( " Unable to convert iPixelFormat %d to a GLX one! \n " , iPixelFormat ) ;
2006-09-11 21:28:32 +02:00
}
2008-05-28 17:02:07 +02:00
wine_tsx11_lock ( ) ;
2006-09-11 21:28:32 +02:00
for ( i = 0 ; i < nAttributes ; + + i ) {
const int curWGLAttr = piAttributes [ i ] ;
TRACE ( " pAttr[%d] = %x \n " , i , curWGLAttr ) ;
switch ( curWGLAttr ) {
case WGL_NUMBER_PIXEL_FORMATS_ARB :
piValues [ i ] = nWGLFormats ;
continue ;
case WGL_SUPPORT_OPENGL_ARB :
piValues [ i ] = GL_TRUE ;
continue ;
case WGL_ACCELERATION_ARB :
curGLXAttr = GLX_CONFIG_CAVEAT ;
2007-07-26 19:23:39 +02:00
if ( ! fmt ) goto pix_error ;
2009-05-19 00:23:05 +02:00
if ( fmt - > dwFlags & PFD_GENERIC_FORMAT )
piValues [ i ] = WGL_NO_ACCELERATION_ARB ;
else if ( fmt - > dwFlags & PFD_GENERIC_ACCELERATED )
piValues [ i ] = WGL_GENERIC_ACCELERATION_ARB ;
else
piValues [ i ] = WGL_FULL_ACCELERATION_ARB ;
2006-09-11 21:28:32 +02:00
continue ;
case WGL_TRANSPARENT_ARB :
curGLXAttr = GLX_TRANSPARENT_TYPE ;
2007-07-26 19:23:39 +02:00
if ( ! fmt ) goto pix_error ;
hTest = pglXGetFBConfigAttrib ( gdi_display , fmt - > fbconfig , curGLXAttr , & tmp ) ;
2006-09-11 21:28:32 +02:00
if ( hTest ) goto get_error ;
piValues [ i ] = GL_FALSE ;
if ( GLX_NONE ! = tmp ) piValues [ i ] = GL_TRUE ;
continue ;
case WGL_PIXEL_TYPE_ARB :
curGLXAttr = GLX_RENDER_TYPE ;
2007-07-26 19:23:39 +02:00
if ( ! fmt ) goto pix_error ;
hTest = pglXGetFBConfigAttrib ( gdi_display , fmt - > fbconfig , curGLXAttr , & tmp ) ;
2006-09-11 21:28:32 +02:00
if ( hTest ) goto get_error ;
TRACE ( " WGL_PIXEL_TYPE_ARB: GLX_RENDER_TYPE = 0x%x \n " , tmp ) ;
if ( tmp & GLX_RGBA_BIT ) { piValues [ i ] = WGL_TYPE_RGBA_ARB ; }
else if ( tmp & GLX_COLOR_INDEX_BIT ) { piValues [ i ] = WGL_TYPE_COLORINDEX_ARB ; }
else if ( tmp & GLX_RGBA_FLOAT_BIT ) { piValues [ i ] = WGL_TYPE_RGBA_FLOAT_ATI ; }
else if ( tmp & GLX_RGBA_FLOAT_ATI_BIT ) { piValues [ i ] = WGL_TYPE_RGBA_FLOAT_ATI ; }
2009-04-20 22:57:19 +02:00
else if ( tmp & GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT ) { piValues [ i ] = WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT ; }
2006-09-11 21:28:32 +02:00
else {
ERR ( " unexpected RenderType(%x) \n " , tmp ) ;
piValues [ i ] = WGL_TYPE_RGBA_ARB ;
}
continue ;
case WGL_COLOR_BITS_ARB :
2007-08-03 04:03:12 +02:00
curGLXAttr = GLX_BUFFER_SIZE ;
break ;
2006-09-11 21:28:32 +02:00
case WGL_BIND_TO_TEXTURE_RGB_ARB :
if ( use_render_texture_ati ) {
curGLXAttr = GLX_BIND_TO_TEXTURE_RGB_ATI ;
break ;
}
case WGL_BIND_TO_TEXTURE_RGBA_ARB :
if ( use_render_texture_ati ) {
curGLXAttr = GLX_BIND_TO_TEXTURE_RGBA_ATI ;
break ;
}
if ( ! use_render_texture_emulation ) {
piValues [ i ] = GL_FALSE ;
continue ;
}
curGLXAttr = GLX_RENDER_TYPE ;
2007-07-26 19:23:39 +02:00
if ( ! fmt ) goto pix_error ;
hTest = pglXGetFBConfigAttrib ( gdi_display , fmt - > fbconfig , curGLXAttr , & tmp ) ;
2006-09-11 21:28:32 +02:00
if ( hTest ) goto get_error ;
if ( GLX_COLOR_INDEX_BIT = = tmp ) {
piValues [ i ] = GL_FALSE ;
continue ;
}
2007-07-26 19:23:39 +02:00
hTest = pglXGetFBConfigAttrib ( gdi_display , fmt - > fbconfig , GLX_DRAWABLE_TYPE , & tmp ) ;
2006-09-11 21:28:32 +02:00
if ( hTest ) goto get_error ;
2008-05-28 17:02:07 +02:00
piValues [ i ] = ( tmp & GLX_PBUFFER_BIT ) ? GL_TRUE : GL_FALSE ;
2006-09-11 21:28:32 +02:00
continue ;
case WGL_BLUE_BITS_ARB :
curGLXAttr = GLX_BLUE_SIZE ;
break ;
case WGL_RED_BITS_ARB :
curGLXAttr = GLX_RED_SIZE ;
break ;
case WGL_GREEN_BITS_ARB :
curGLXAttr = GLX_GREEN_SIZE ;
break ;
case WGL_ALPHA_BITS_ARB :
curGLXAttr = GLX_ALPHA_SIZE ;
break ;
case WGL_DEPTH_BITS_ARB :
curGLXAttr = GLX_DEPTH_SIZE ;
break ;
case WGL_STENCIL_BITS_ARB :
curGLXAttr = GLX_STENCIL_SIZE ;
break ;
case WGL_DOUBLE_BUFFER_ARB :
curGLXAttr = GLX_DOUBLEBUFFER ;
break ;
case WGL_STEREO_ARB :
curGLXAttr = GLX_STEREO ;
break ;
case WGL_AUX_BUFFERS_ARB :
curGLXAttr = GLX_AUX_BUFFERS ;
break ;
2007-08-01 13:37:03 +02:00
2006-09-11 21:28:32 +02:00
case WGL_SUPPORT_GDI_ARB :
2007-08-14 03:36:46 +02:00
if ( ! fmt ) goto pix_error ;
2009-05-16 21:50:58 +02:00
piValues [ i ] = ( fmt - > dwFlags & PFD_SUPPORT_GDI ) ? TRUE : FALSE ;
continue ;
2007-08-01 13:37:03 +02:00
2006-09-11 21:28:32 +02:00
case WGL_DRAW_TO_BITMAP_ARB :
2009-05-17 21:50:56 +02:00
if ( ! fmt ) goto pix_error ;
piValues [ i ] = ( fmt - > dwFlags & PFD_DRAW_TO_BITMAP ) ? TRUE : FALSE ;
continue ;
case WGL_DRAW_TO_WINDOW_ARB :
2006-09-11 21:28:32 +02:00
case WGL_DRAW_TO_PBUFFER_ARB :
2007-08-01 13:37:03 +02:00
if ( ! fmt ) goto pix_error ;
2007-07-26 19:23:39 +02:00
hTest = pglXGetFBConfigAttrib ( gdi_display , fmt - > fbconfig , GLX_DRAWABLE_TYPE , & tmp ) ;
2006-11-30 23:55:08 +01:00
if ( hTest ) goto get_error ;
2007-08-01 13:37:03 +02:00
if ( ( curWGLAttr = = WGL_DRAW_TO_WINDOW_ARB & & ( tmp & GLX_WINDOW_BIT ) ) | |
( curWGLAttr = = WGL_DRAW_TO_PBUFFER_ARB & & ( tmp & GLX_PBUFFER_BIT ) ) )
piValues [ i ] = GL_TRUE ;
else
piValues [ i ] = GL_FALSE ;
2006-11-30 23:55:08 +01:00
continue ;
2006-09-11 21:28:32 +02:00
2009-05-16 00:00:24 +02:00
case WGL_SWAP_METHOD_ARB :
/* For now return SWAP_EXCHANGE_ARB which is the best type of buffer switch available.
* Later on we can also use GLX_OML_swap_method on drivers which support this . At this
* point only ATI offers this .
*/
piValues [ i ] = WGL_SWAP_EXCHANGE_ARB ;
break ;
2006-09-11 21:28:32 +02:00
case WGL_PBUFFER_LARGEST_ARB :
curGLXAttr = GLX_LARGEST_PBUFFER ;
break ;
case WGL_SAMPLE_BUFFERS_ARB :
curGLXAttr = GLX_SAMPLE_BUFFERS_ARB ;
break ;
case WGL_SAMPLES_ARB :
curGLXAttr = GLX_SAMPLES_ARB ;
break ;
2007-08-01 22:15:10 +02:00
case WGL_FLOAT_COMPONENTS_NV :
curGLXAttr = GLX_FLOAT_COMPONENTS_NV ;
break ;
2008-04-30 00:42:09 +02:00
case WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT :
curGLXAttr = GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT ;
break ;
2009-04-20 22:57:19 +02:00
case WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT :
curGLXAttr = GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT ;
break ;
2007-08-02 21:20:56 +02:00
case WGL_ACCUM_RED_BITS_ARB :
curGLXAttr = GLX_ACCUM_RED_SIZE ;
break ;
case WGL_ACCUM_GREEN_BITS_ARB :
curGLXAttr = GLX_ACCUM_GREEN_SIZE ;
break ;
case WGL_ACCUM_BLUE_BITS_ARB :
curGLXAttr = GLX_ACCUM_BLUE_SIZE ;
break ;
case WGL_ACCUM_ALPHA_BITS_ARB :
curGLXAttr = GLX_ACCUM_ALPHA_SIZE ;
break ;
case WGL_ACCUM_BITS_ARB :
if ( ! fmt ) goto pix_error ;
hTest = pglXGetFBConfigAttrib ( gdi_display , fmt - > fbconfig , GLX_ACCUM_RED_SIZE , & tmp ) ;
if ( hTest ) goto get_error ;
piValues [ i ] = tmp ;
hTest = pglXGetFBConfigAttrib ( gdi_display , fmt - > fbconfig , GLX_ACCUM_GREEN_SIZE , & tmp ) ;
if ( hTest ) goto get_error ;
piValues [ i ] + = tmp ;
hTest = pglXGetFBConfigAttrib ( gdi_display , fmt - > fbconfig , GLX_ACCUM_BLUE_SIZE , & tmp ) ;
if ( hTest ) goto get_error ;
piValues [ i ] + = tmp ;
hTest = pglXGetFBConfigAttrib ( gdi_display , fmt - > fbconfig , GLX_ACCUM_ALPHA_SIZE , & tmp ) ;
if ( hTest ) goto get_error ;
piValues [ i ] + = tmp ;
continue ;
2006-09-11 21:28:32 +02:00
default :
FIXME ( " unsupported %x WGL Attribute \n " , curWGLAttr ) ;
}
2006-12-27 22:01:37 +01:00
/* Retrieve a GLX FBConfigAttrib when the attribute to query is valid and
* iPixelFormat ! = 0. When iPixelFormat is 0 the only value which makes
* sense to query is WGL_NUMBER_PIXEL_FORMATS_ARB .
*
* TODO : properly test the behavior of wglGetPixelFormatAttrib * v on Windows
* and check which options can work using iPixelFormat = 0 and which not .
* A problem would be that this function is an extension . This would
* mean that the behavior could differ between different vendors ( ATI , Nvidia , . . ) .
*/
if ( 0 ! = curGLXAttr & & iPixelFormat ! = 0 ) {
2007-07-26 19:23:39 +02:00
if ( ! fmt ) goto pix_error ;
hTest = pglXGetFBConfigAttrib ( gdi_display , fmt - > fbconfig , curGLXAttr , piValues + i ) ;
2006-09-11 21:28:32 +02:00
if ( hTest ) goto get_error ;
2006-12-10 09:00:47 +01:00
curGLXAttr = 0 ;
2006-09-11 21:28:32 +02:00
} else {
piValues [ i ] = GL_FALSE ;
}
}
2008-05-28 17:02:07 +02:00
wine_tsx11_unlock ( ) ;
2006-09-11 21:28:32 +02:00
return GL_TRUE ;
get_error :
2008-05-28 17:02:07 +02:00
wine_tsx11_unlock ( ) ;
2006-09-11 21:28:32 +02:00
ERR ( " (%p): unexpected failure on GetFBConfigAttrib(%x) returns FALSE \n " , hdc , curGLXAttr ) ;
return GL_FALSE ;
pix_error :
2008-05-28 17:02:07 +02:00
wine_tsx11_unlock ( ) ;
2007-07-26 19:23:39 +02:00
ERR ( " (%p): unexpected iPixelFormat(%d) vs nFormats(%d), returns FALSE \n " , hdc , iPixelFormat , nWGLFormats ) ;
2006-09-11 21:28:32 +02:00
return GL_FALSE ;
}
2006-12-06 02:46:30 +01:00
/**
* X11DRV_wglGetPixelFormatAttribfvARB
*
* WGL_ARB_pixel_format : wglGetPixelFormatAttribfvARB
*/
static GLboolean WINAPI X11DRV_wglGetPixelFormatAttribfvARB ( HDC hdc , int iPixelFormat , int iLayerPlane , UINT nAttributes , const int * piAttributes , FLOAT * pfValues )
{
int * attr ;
int ret ;
2008-12-06 14:18:43 +01:00
UINT i ;
2006-12-06 02:46:30 +01:00
TRACE ( " (%p, %d, %d, %d, %p, %p) \n " , hdc , iPixelFormat , iLayerPlane , nAttributes , piAttributes , pfValues ) ;
/* Allocate a temporary array to store integer values */
attr = HeapAlloc ( GetProcessHeap ( ) , 0 , nAttributes * sizeof ( int ) ) ;
if ( ! attr ) {
ERR ( " couldn't allocate %d array \n " , nAttributes ) ;
return GL_FALSE ;
}
/* Piggy-back on wglGetPixelFormatAttribivARB */
ret = X11DRV_wglGetPixelFormatAttribivARB ( hdc , iPixelFormat , iLayerPlane , nAttributes , piAttributes , attr ) ;
if ( ret ) {
/* Convert integer values to float. Should also check for attributes
that can give decimal values here */
for ( i = 0 ; i < nAttributes ; i + + ) {
pfValues [ i ] = attr [ i ] ;
}
}
HeapFree ( GetProcessHeap ( ) , 0 , attr ) ;
return ret ;
}
2006-11-12 20:23:38 +01:00
/**
* X11DRV_wglBindTexImageARB
*
* WGL_ARB_render_texture : wglBindTexImageARB
*/
2006-09-11 21:28:32 +02:00
static GLboolean WINAPI X11DRV_wglBindTexImageARB ( HPBUFFERARB hPbuffer , int iBuffer )
{
2009-01-19 10:23:40 +01:00
Wine_GLPBuffer * object = hPbuffer ;
2008-05-28 17:02:07 +02:00
GLboolean ret = GL_FALSE ;
2006-09-11 21:28:32 +02:00
TRACE ( " (%p, %d) \n " , hPbuffer , iBuffer ) ;
if ( NULL = = object ) {
SetLastError ( ERROR_INVALID_HANDLE ) ;
return GL_FALSE ;
}
if ( ! object - > use_render_texture ) {
SetLastError ( ERROR_INVALID_HANDLE ) ;
return GL_FALSE ;
}
2007-07-25 22:32:07 +02:00
2006-09-11 21:28:32 +02:00
if ( ! use_render_texture_ati & & 1 = = use_render_texture_emulation ) {
2007-07-25 22:32:07 +02:00
static int init = 0 ;
2007-07-29 14:13:45 +02:00
int prev_binded_texture = 0 ;
2008-05-28 17:02:07 +02:00
GLXContext prev_context ;
Drawable prev_drawable ;
2007-07-27 15:19:46 +02:00
GLXContext tmp_context ;
2007-07-25 22:32:07 +02:00
2008-05-28 17:02:07 +02:00
wine_tsx11_lock ( ) ;
prev_context = pglXGetCurrentContext ( ) ;
prev_drawable = pglXGetCurrentDrawable ( ) ;
2007-07-25 22:32:07 +02:00
/* Our render_texture emulation is basic and lacks some features (1D/Cube support).
This is mostly due to lack of demos / games using them . Further the use of glReadPixels
isn ' t ideal performance wise but I wasn ' t able to get other ways working .
*/
if ( ! init ) {
init = 1 ; /* Only show the FIXME once for performance reasons */
FIXME ( " partial stub! \n " ) ;
2006-09-11 21:28:32 +02:00
}
2007-07-25 22:32:07 +02:00
2007-07-27 15:19:46 +02:00
TRACE ( " drawable=%p, context=%p \n " , ( void * ) object - > drawable , prev_context ) ;
2007-07-29 14:13:45 +02:00
tmp_context = pglXCreateNewContext ( gdi_display , object - > fmt - > fbconfig , object - > fmt - > render_type , prev_context , True ) ;
pglGetIntegerv ( object - > texture_bind_target , & prev_binded_texture ) ;
2007-07-27 15:19:46 +02:00
2007-07-29 14:13:45 +02:00
/* Switch to our pbuffer */
2007-07-27 15:19:46 +02:00
pglXMakeCurrent ( gdi_display , object - > drawable , tmp_context ) ;
2007-07-29 14:13:45 +02:00
/* Make sure that the prev_binded_texture is set as the current texture state isn't shared between contexts.
* After that upload the pbuffer texture data . */
pglBindTexture ( object - > texture_target , prev_binded_texture ) ;
pglCopyTexImage2D ( object - > texture_target , 0 , object - > use_render_texture , 0 , 0 , object - > width , object - > height , 0 ) ;
2007-07-25 22:32:07 +02:00
/* Switch back to the original drawable and upload the pbuffer-texture */
pglXMakeCurrent ( object - > display , prev_drawable , prev_context ) ;
2007-07-27 15:19:46 +02:00
pglXDestroyContext ( gdi_display , tmp_context ) ;
2008-05-28 17:02:07 +02:00
wine_tsx11_unlock ( ) ;
2007-07-28 23:21:57 +02:00
return GL_TRUE ;
2006-09-11 21:28:32 +02:00
}
2007-07-25 22:32:07 +02:00
2007-08-12 17:31:25 +02:00
if ( NULL ! = pglXBindTexImageATI ) {
int buffer ;
switch ( iBuffer )
{
case WGL_FRONT_LEFT_ARB :
buffer = GLX_FRONT_LEFT_ATI ;
break ;
case WGL_FRONT_RIGHT_ARB :
buffer = GLX_FRONT_RIGHT_ATI ;
break ;
case WGL_BACK_LEFT_ARB :
buffer = GLX_BACK_LEFT_ATI ;
break ;
case WGL_BACK_RIGHT_ARB :
buffer = GLX_BACK_RIGHT_ATI ;
break ;
default :
ERR ( " Unknown iBuffer=%#x \n " , iBuffer ) ;
return FALSE ;
}
/* In the sample 'ogl_offscreen_rendering_3' from codesampler.net I get garbage on the screen.
* I ' m not sure if that ' s a bug in the ATI extension or in the program . I think that the program
* expected a single buffering format since it didn ' t ask for double buffering . A buffer swap
* fixed the program . I don ' t know what the correct behavior is . On the other hand that demo
* works fine using our pbuffer emulation path .
*/
2008-05-28 17:02:07 +02:00
wine_tsx11_lock ( ) ;
ret = pglXBindTexImageATI ( object - > display , object - > drawable , buffer ) ;
wine_tsx11_unlock ( ) ;
2006-09-11 21:28:32 +02:00
}
2008-05-28 17:02:07 +02:00
return ret ;
2006-09-11 21:28:32 +02:00
}
2006-11-12 20:23:38 +01:00
/**
* X11DRV_wglReleaseTexImageARB
*
* WGL_ARB_render_texture : wglReleaseTexImageARB
*/
2006-09-11 21:28:32 +02:00
static GLboolean WINAPI X11DRV_wglReleaseTexImageARB ( HPBUFFERARB hPbuffer , int iBuffer )
{
2009-01-19 10:23:40 +01:00
Wine_GLPBuffer * object = hPbuffer ;
2008-05-28 17:02:07 +02:00
GLboolean ret = GL_FALSE ;
2006-09-11 21:28:32 +02:00
TRACE ( " (%p, %d) \n " , hPbuffer , iBuffer ) ;
if ( NULL = = object ) {
SetLastError ( ERROR_INVALID_HANDLE ) ;
return GL_FALSE ;
}
if ( ! object - > use_render_texture ) {
SetLastError ( ERROR_INVALID_HANDLE ) ;
return GL_FALSE ;
}
if ( ! use_render_texture_ati & & 1 = = use_render_texture_emulation ) {
return GL_TRUE ;
}
2007-08-12 17:31:25 +02:00
if ( NULL ! = pglXReleaseTexImageATI ) {
int buffer ;
switch ( iBuffer )
{
case WGL_FRONT_LEFT_ARB :
buffer = GLX_FRONT_LEFT_ATI ;
break ;
case WGL_FRONT_RIGHT_ARB :
buffer = GLX_FRONT_RIGHT_ATI ;
break ;
case WGL_BACK_LEFT_ARB :
buffer = GLX_BACK_LEFT_ATI ;
break ;
case WGL_BACK_RIGHT_ARB :
buffer = GLX_BACK_RIGHT_ATI ;
break ;
default :
ERR ( " Unknown iBuffer=%#x \n " , iBuffer ) ;
return FALSE ;
}
2008-05-28 17:02:07 +02:00
wine_tsx11_lock ( ) ;
ret = pglXReleaseTexImageATI ( object - > display , object - > drawable , buffer ) ;
wine_tsx11_unlock ( ) ;
2006-09-11 21:28:32 +02:00
}
2008-05-28 17:02:07 +02:00
return ret ;
2006-09-11 21:28:32 +02:00
}
2006-11-12 20:23:38 +01:00
/**
* X11DRV_wglGetExtensionsStringEXT
*
* WGL_EXT_extensions_string : wglGetExtensionsStringEXT
*/
2006-10-31 21:41:02 +01:00
static const char * WINAPI X11DRV_wglGetExtensionsStringEXT ( void ) {
2006-09-11 21:28:32 +02:00
TRACE ( " () returning \" %s \" \n " , WineGLInfo . wglExtensions ) ;
return WineGLInfo . wglExtensions ;
}
2006-11-12 20:23:38 +01:00
/**
* X11DRV_wglGetSwapIntervalEXT
*
* WGL_EXT_swap_control : wglGetSwapIntervalEXT
*/
2006-10-31 21:41:02 +01:00
static int WINAPI X11DRV_wglGetSwapIntervalEXT ( VOID ) {
2006-09-11 21:28:32 +02:00
FIXME ( " (),stub! \n " ) ;
return swap_interval ;
}
2006-11-12 20:23:38 +01:00
/**
* X11DRV_wglSwapIntervalEXT
*
* WGL_EXT_swap_control : wglSwapIntervalEXT
*/
2006-10-31 21:41:02 +01:00
static BOOL WINAPI X11DRV_wglSwapIntervalEXT ( int interval ) {
2008-05-28 17:02:07 +02:00
BOOL ret = TRUE ;
2006-09-11 21:28:32 +02:00
TRACE ( " (%d) \n " , interval ) ;
swap_interval = interval ;
if ( NULL ! = pglXSwapIntervalSGI ) {
2008-05-28 17:02:07 +02:00
wine_tsx11_lock ( ) ;
ret = ! pglXSwapIntervalSGI ( interval ) ;
wine_tsx11_unlock ( ) ;
2006-09-11 21:28:32 +02:00
}
2008-05-28 17:02:07 +02:00
else WARN ( " () : GLX_SGI_swap_control extension seems not supported \ n " ) ;
return ret ;
2006-09-11 21:28:32 +02:00
}
2006-12-03 22:40:24 +01:00
/**
* X11DRV_wglAllocateMemoryNV
*
* WGL_NV_vertex_array_range : wglAllocateMemoryNV
*/
static void * WINAPI X11DRV_wglAllocateMemoryNV ( GLsizei size , GLfloat readfreq , GLfloat writefreq , GLfloat priority ) {
2008-05-28 17:02:07 +02:00
void * ret = NULL ;
2006-12-03 22:40:24 +01:00
TRACE ( " (%d, %f, %f, %f) \n " , size , readfreq , writefreq , priority ) ;
2008-05-28 17:02:07 +02:00
if ( pglXAllocateMemoryNV )
{
wine_tsx11_lock ( ) ;
ret = pglXAllocateMemoryNV ( size , readfreq , writefreq , priority ) ;
wine_tsx11_unlock ( ) ;
}
return ret ;
2006-12-03 22:40:24 +01:00
}
/**
* X11DRV_wglFreeMemoryNV
*
* WGL_NV_vertex_array_range : wglFreeMemoryNV
*/
static void WINAPI X11DRV_wglFreeMemoryNV ( GLvoid * pointer ) {
TRACE ( " (%p) \n " , pointer ) ;
if ( pglXFreeMemoryNV = = NULL )
return ;
2008-05-28 17:02:07 +02:00
wine_tsx11_lock ( ) ;
2006-12-03 22:40:24 +01:00
pglXFreeMemoryNV ( pointer ) ;
2008-05-28 17:02:07 +02:00
wine_tsx11_unlock ( ) ;
2006-12-03 22:40:24 +01:00
}
2008-04-23 00:15:15 +02:00
/**
* X11DRV_wglSetPixelFormatWINE
*
* WGL_WINE_pixel_format_passthrough : wglSetPixelFormatWINE
* This is a WINE - specific wglSetPixelFormat which can set the pixel format multiple times .
*/
2008-12-16 14:18:49 +01:00
BOOL CDECL X11DRV_wglSetPixelFormatWINE ( X11DRV_PDEVICE * physDev , int iPixelFormat , const PIXELFORMATDESCRIPTOR * ppfd )
2008-04-23 00:15:15 +02:00
{
TRACE ( " (%p,%d,%p) \n " , physDev , iPixelFormat , ppfd ) ;
2008-06-23 22:56:10 +02:00
if ( ! has_opengl ( ) ) return FALSE ;
2008-04-23 00:15:15 +02:00
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 ) ;
}
2006-11-12 20:23:38 +01:00
/**
* glxRequireVersion ( internal )
*
* Check if the supported GLX version matches requiredVersion .
*/
2006-09-11 21:28:32 +02:00
static BOOL glxRequireVersion ( int requiredVersion )
{
/* Both requiredVersion and glXVersion[1] contains the minor GLX version */
if ( requiredVersion < = WineGLInfo . glxVersion [ 1 ] )
return TRUE ;
return FALSE ;
}
static BOOL glxRequireExtension ( const char * requiredExtension )
{
2007-08-08 16:40:34 +02:00
if ( strstr ( WineGLInfo . glxExtensions , requiredExtension ) = = NULL ) {
2006-09-11 21:28:32 +02:00
return FALSE ;
}
return TRUE ;
}
2007-07-27 15:01:52 +02:00
static void register_extension_string ( const char * ext )
{
2007-08-10 03:18:48 +02:00
if ( WineGLInfo . wglExtensions [ 0 ] )
strcat ( WineGLInfo . wglExtensions , " " ) ;
2007-07-27 15:01:52 +02:00
strcat ( WineGLInfo . wglExtensions , ext ) ;
TRACE ( " '%s' \n " , ext ) ;
}
2006-09-12 11:50:36 +02:00
static BOOL register_extension ( const WineGLExtension * ext )
2006-09-11 21:28:32 +02:00
{
int i ;
2006-09-12 11:50:36 +02:00
assert ( WineGLExtensionListSize < MAX_EXTENSIONS ) ;
WineGLExtensionList [ WineGLExtensionListSize + + ] = ext ;
2006-09-11 21:28:32 +02:00
2007-08-10 03:18:48 +02:00
register_extension_string ( ext - > extName ) ;
2006-09-11 21:28:32 +02:00
2006-09-12 11:50:36 +02:00
for ( i = 0 ; ext - > extEntryPoints [ i ] . funcName ; + + i )
2006-09-11 21:28:32 +02:00
TRACE ( " - '%s' \n " , ext - > extEntryPoints [ i ] . funcName ) ;
return TRUE ;
}
2006-10-26 23:11:07 +02:00
static const WineGLExtension WGL_internal_functions =
{
" " ,
{
{ " wglGetIntegerv " , X11DRV_wglGetIntegerv } ,
2007-09-23 05:45:27 +02:00
{ " wglFinish " , X11DRV_wglFinish } ,
{ " wglFlush " , X11DRV_wglFlush } ,
2006-10-26 23:11:07 +02:00
}
} ;
2006-09-11 21:28:32 +02:00
static const WineGLExtension WGL_ARB_extensions_string =
{
" WGL_ARB_extensions_string " ,
{
{ " wglGetExtensionsStringARB " , X11DRV_wglGetExtensionsStringARB } ,
}
} ;
static const WineGLExtension WGL_ARB_make_current_read =
{
" WGL_ARB_make_current_read " ,
{
{ " wglGetCurrentReadDCARB " , X11DRV_wglGetCurrentReadDCARB } ,
{ " wglMakeContextCurrentARB " , X11DRV_wglMakeContextCurrentARB } ,
}
} ;
static const WineGLExtension WGL_ARB_multisample =
{
" WGL_ARB_multisample " ,
} ;
static const WineGLExtension WGL_ARB_pbuffer =
{
" WGL_ARB_pbuffer " ,
{
{ " wglCreatePbufferARB " , X11DRV_wglCreatePbufferARB } ,
{ " wglDestroyPbufferARB " , X11DRV_wglDestroyPbufferARB } ,
{ " wglGetPbufferDCARB " , X11DRV_wglGetPbufferDCARB } ,
{ " wglQueryPbufferARB " , X11DRV_wglQueryPbufferARB } ,
{ " wglReleasePbufferDCARB " , X11DRV_wglReleasePbufferDCARB } ,
{ " wglSetPbufferAttribARB " , X11DRV_wglSetPbufferAttribARB } ,
}
} ;
static const WineGLExtension WGL_ARB_pixel_format =
{
" WGL_ARB_pixel_format " ,
{
{ " wglChoosePixelFormatARB " , X11DRV_wglChoosePixelFormatARB } ,
{ " wglGetPixelFormatAttribfvARB " , X11DRV_wglGetPixelFormatAttribfvARB } ,
{ " wglGetPixelFormatAttribivARB " , X11DRV_wglGetPixelFormatAttribivARB } ,
}
} ;
static const WineGLExtension WGL_ARB_render_texture =
{
" WGL_ARB_render_texture " ,
{
{ " wglBindTexImageARB " , X11DRV_wglBindTexImageARB } ,
{ " wglReleaseTexImageARB " , X11DRV_wglReleaseTexImageARB } ,
}
} ;
static const WineGLExtension WGL_EXT_extensions_string =
{
" WGL_EXT_extensions_string " ,
{
{ " wglGetExtensionsStringEXT " , X11DRV_wglGetExtensionsStringEXT } ,
}
} ;
static const WineGLExtension WGL_EXT_swap_control =
{
" WGL_EXT_swap_control " ,
{
{ " wglSwapIntervalEXT " , X11DRV_wglSwapIntervalEXT } ,
{ " wglGetSwapIntervalEXT " , X11DRV_wglGetSwapIntervalEXT } ,
}
} ;
2006-12-03 22:40:24 +01:00
static const WineGLExtension WGL_NV_vertex_array_range =
{
" WGL_NV_vertex_array_range " ,
{
{ " wglAllocateMemoryNV " , X11DRV_wglAllocateMemoryNV } ,
{ " wglFreeMemoryNV " , X11DRV_wglFreeMemoryNV } ,
}
} ;
2006-09-11 21:28:32 +02:00
2008-04-23 00:15:15 +02:00
static const WineGLExtension WGL_WINE_pixel_format_passthrough =
{
" WGL_WINE_pixel_format_passthrough " ,
{
{ " wglSetPixelFormatWINE " , X11DRV_wglSetPixelFormatWINE } ,
}
} ;
2006-09-11 21:28:32 +02:00
/**
* X11DRV_WineGL_LoadExtensions
*/
2006-09-12 11:50:36 +02:00
static void X11DRV_WineGL_LoadExtensions ( void )
2006-09-11 21:28:32 +02:00
{
WineGLInfo . wglExtensions [ 0 ] = 0 ;
2006-09-12 11:50:36 +02:00
2006-10-26 23:11:07 +02:00
/* Load Wine internal functions */
register_extension ( & WGL_internal_functions ) ;
2006-09-11 21:28:32 +02:00
/* ARB Extensions */
2006-09-12 11:50:36 +02:00
2007-07-28 18:56:12 +02:00
if ( glxRequireExtension ( " GLX_ARB_fbconfig_float " ) )
{
register_extension_string ( " WGL_ARB_pixel_format_float " ) ;
register_extension_string ( " WGL_ATI_pixel_format_float " ) ;
}
2006-09-12 11:50:36 +02:00
register_extension ( & WGL_ARB_extensions_string ) ;
if ( glxRequireVersion ( 3 ) )
register_extension ( & WGL_ARB_make_current_read ) ;
if ( glxRequireExtension ( " GLX_ARB_multisample " ) )
register_extension ( & WGL_ARB_multisample ) ;
2006-12-19 20:24:25 +01:00
/* In general pbuffer functionality requires support in the X-server. The functionality is
* available either when the GLX_SGIX_pbuffer is present or when the GLX server version is 1.3 .
* All display drivers except for Nvidia ' s use the GLX module from Xfree86 / Xorg which only
* supports GLX 1.2 . The endresult is that only Nvidia ' s drivers support pbuffers .
*
* The only other drive which has pbuffer support is Ati ' s FGLRX driver . They provide clientside GLX 1.3 support
* without support in the X - server ( which other Mesa based drivers require ) .
*
* Support pbuffers when the GLX version is 1.3 and GLX_SGIX_pbuffer is available . Further pbuffers can
* also be supported when GLX_ATI_render_texture is available . This extension depends on pbuffers , so when it
* is available pbuffers must be available too . */
if ( ( glxRequireVersion ( 3 ) & & glxRequireExtension ( " GLX_SGIX_pbuffer " ) ) | | glxRequireExtension ( " GLX_ATI_render_texture " ) )
2006-09-12 11:50:36 +02:00
register_extension ( & WGL_ARB_pbuffer ) ;
register_extension ( & WGL_ARB_pixel_format ) ;
2007-07-25 22:32:07 +02:00
/* Support WGL_ARB_render_texture when there's support or pbuffer based emulation */
2006-09-12 11:50:36 +02:00
if ( glxRequireExtension ( " GLX_ATI_render_texture " ) | |
2007-07-25 22:32:07 +02:00
glxRequireExtension ( " GLX_ARB_render_texture " ) | |
( glxRequireVersion ( 3 ) & & glxRequireExtension ( " GLX_SGIX_pbuffer " ) & & use_render_texture_emulation ) )
2007-07-27 15:01:52 +02:00
{
2006-09-12 11:50:36 +02:00
register_extension ( & WGL_ARB_render_texture ) ;
2006-09-11 21:28:32 +02:00
2007-07-27 15:01:52 +02:00
/* The WGL version of GLX_NV_float_buffer requires render_texture */
if ( glxRequireExtension ( " GLX_NV_float_buffer " ) )
register_extension_string ( " WGL_NV_float_buffer " ) ;
/* Again there's no GLX equivalent for this extension, so depend on the required GL extension */
if ( strstr ( WineGLInfo . glExtensions , " GL_NV_texture_rectangle " ) ! = NULL )
register_extension_string ( " WGL_NV_texture_rectangle " ) ;
}
2006-09-11 21:28:32 +02:00
/* EXT Extensions */
2006-09-12 11:50:36 +02:00
register_extension ( & WGL_EXT_extensions_string ) ;
2007-07-28 00:32:32 +02:00
/* Load this extension even when it isn't backed by a GLX extension because it is has been around for ages.
* Games like Call of Duty and K . O . T . O . R . rely on it . Further our emulation is good enough . */
register_extension ( & WGL_EXT_swap_control ) ;
2006-12-03 22:40:24 +01:00
2008-04-30 00:42:09 +02:00
if ( glxRequireExtension ( " GLX_EXT_framebuffer_sRGB " ) )
register_extension_string ( " WGL_EXT_framebuffer_sRGB " ) ;
2009-04-20 22:57:19 +02:00
if ( glxRequireExtension ( " GLX_EXT_fbconfig_packed_float " ) )
register_extension_string ( " WGL_EXT_pixel_format_packed_float " ) ;
2006-12-03 22:40:24 +01:00
/* 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 ) ;
2008-04-23 00:15:15 +02:00
/* 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 ) ;
2006-09-11 21:28:32 +02:00
}
2006-06-23 13:13:55 +02:00
Drawable get_glxdrawable ( X11DRV_PDEVICE * physDev )
{
Drawable ret ;
if ( physDev - > bitmap )
{
if ( physDev - > bitmap - > hbitmap = = BITMAP_stock_phys_bitmap . hbitmap )
ret = physDev - > drawable ; /* PBuffer */
else
ret = physDev - > bitmap - > glxpixmap ;
}
2007-09-25 19:20:58 +02:00
else if ( physDev - > gl_drawable )
ret = physDev - > gl_drawable ;
2006-06-23 13:13:55 +02:00
else
ret = physDev - > drawable ;
return ret ;
}
2007-09-26 10:03:39 +02:00
BOOL destroy_glxpixmap ( Display * display , XID glxpixmap )
2006-06-23 13:13:55 +02:00
{
wine_tsx11_lock ( ) ;
2007-09-26 10:03:39 +02:00
pglXDestroyGLXPixmap ( display , glxpixmap ) ;
2006-06-23 13:13:55 +02:00
wine_tsx11_unlock ( ) ;
return TRUE ;
}
2005-05-06 16:33:02 +02:00
/**
* X11DRV_SwapBuffers
*
* Swap the buffers of this DC
*/
2008-12-16 14:18:49 +01:00
BOOL CDECL X11DRV_SwapBuffers ( X11DRV_PDEVICE * physDev )
2006-06-23 13:13:55 +02:00
{
GLXDrawable drawable ;
2007-09-26 16:15:52 +02:00
Wine_GLContext * ctx = NtCurrentTeb ( ) - > glContext ;
2008-06-23 22:56:10 +02:00
if ( ! has_opengl ( ) ) return FALSE ;
2008-04-21 20:33:49 +02:00
TRACE ( " (%p) \n " , physDev ) ;
2000-05-12 22:18:14 +02:00
2006-06-23 13:13:55 +02:00
drawable = get_glxdrawable ( physDev ) ;
2007-09-26 16:15:52 +02:00
2002-09-25 02:29:56 +02:00
wine_tsx11_lock ( ) ;
2007-09-26 16:15:52 +02:00
sync_context ( ctx ) ;
2007-09-26 20:01:07 +02:00
if ( physDev - > pixmap ) {
if ( pglXCopySubBufferMESA ) {
int w = physDev - > dc_rect . right - physDev - > dc_rect . left ;
int h = physDev - > dc_rect . bottom - physDev - > dc_rect . top ;
/* (glX)SwapBuffers has an implicit glFlush effect, however
* GLX_MESA_copy_sub_buffer doesn ' t . Make sure GL is flushed before
* copying */
pglFlush ( ) ;
if ( w > 0 & & h > 0 )
pglXCopySubBufferMESA ( gdi_display , drawable , 0 , 0 , w , h ) ;
}
else
pglXSwapBuffers ( gdi_display , drawable ) ;
}
else
pglXSwapBuffers ( gdi_display , drawable ) ;
2007-10-10 17:33:35 +02:00
flush_gl_drawable ( physDev ) ;
2002-09-25 02:29:56 +02:00
wine_tsx11_unlock ( ) ;
2002-06-01 01:06:46 +02:00
2006-07-05 18:35:21 +02:00
/* FPS support */
if ( TRACE_ON ( fps ) )
{
2008-08-25 05:45:21 +02:00
static long prev_time , start_time ;
static unsigned long frames , frames_total ;
2006-07-05 18:35:21 +02:00
DWORD time = GetTickCount ( ) ;
frames + + ;
2008-08-25 05:45:21 +02:00
frames_total + + ;
2006-07-05 18:35:21 +02:00
/* every 1.5 seconds */
if ( time - prev_time > 1500 ) {
2008-08-25 05:45:21 +02:00
TRACE_ ( fps ) ( " @ approx %.2ffps, total %.2ffps \n " ,
1000.0 * frames / ( time - prev_time ) , 1000.0 * frames_total / ( time - start_time ) ) ;
2006-07-05 18:35:21 +02:00
prev_time = time ;
frames = 0 ;
2008-08-25 05:45:21 +02:00
if ( start_time = = 0 ) start_time = time ;
2006-07-05 18:35:21 +02:00
}
}
2000-05-12 22:18:14 +02:00
return TRUE ;
}
2007-09-26 07:43:38 +02:00
XVisualInfo * visual_from_fbconfig_id ( XID fbconfig_id )
{
WineGLPixelFormat * fmt ;
2008-05-28 17:02:07 +02:00
XVisualInfo * ret ;
2007-09-26 07:43:38 +02:00
2009-05-16 21:50:58 +02:00
fmt = ConvertPixelFormatGLXtoWGL ( gdi_display , fbconfig_id , 0 /* no flags */ ) ;
2007-09-26 07:43:38 +02:00
if ( fmt = = NULL )
return NULL ;
2008-05-28 17:02:07 +02:00
wine_tsx11_lock ( ) ;
ret = pglXGetVisualFromFBConfig ( gdi_display , fmt - > fbconfig ) ;
wine_tsx11_unlock ( ) ;
return ret ;
2007-09-26 07:43:38 +02:00
}
2002-11-15 05:16:38 +01:00
# else /* no OpenGL includes */
2000-05-12 22:18:14 +02:00
2009-05-26 22:48:17 +02:00
void X11DRV_OpenGL_Cleanup ( void )
{
}
2008-06-23 22:56:10 +02:00
static inline void opengl_error ( void )
{
static int warned ;
if ( ! warned + + ) ERR ( " No OpenGL support compiled in. \n " ) ;
}
2007-09-15 22:02:32 +02:00
int pixelformat_from_fbconfig_id ( XID fbconfig_id )
{
return 0 ;
}
2007-09-26 16:15:52 +02:00
void mark_drawable_dirty ( Drawable old , Drawable new )
{
}
2007-10-10 17:33:35 +02:00
void flush_gl_drawable ( X11DRV_PDEVICE * physDev )
{
}
2007-09-26 17:17:13 +02:00
Drawable create_glxpixmap ( Display * display , XVisualInfo * vis , Pixmap parent )
{
return 0 ;
}
2002-11-27 21:21:24 +01:00
/***********************************************************************
* ChoosePixelFormat ( X11DRV . @ )
*/
2008-12-16 14:18:49 +01:00
int CDECL X11DRV_ChoosePixelFormat ( X11DRV_PDEVICE * physDev ,
const PIXELFORMATDESCRIPTOR * ppfd ) {
2008-06-23 22:56:10 +02:00
opengl_error ( ) ;
2000-05-12 22:18:14 +02:00
return 0 ;
}
2002-11-27 21:21:24 +01:00
/***********************************************************************
* DescribePixelFormat ( X11DRV . @ )
*/
2008-12-16 14:18:49 +01:00
int CDECL X11DRV_DescribePixelFormat ( X11DRV_PDEVICE * physDev ,
int iPixelFormat ,
UINT nBytes ,
PIXELFORMATDESCRIPTOR * ppfd ) {
2008-06-23 22:56:10 +02:00
opengl_error ( ) ;
2000-05-12 22:18:14 +02:00
return 0 ;
}
2002-11-27 21:21:24 +01:00
/***********************************************************************
* GetPixelFormat ( X11DRV . @ )
*/
2008-12-16 14:18:49 +01:00
int CDECL X11DRV_GetPixelFormat ( X11DRV_PDEVICE * physDev ) {
2008-06-23 22:56:10 +02:00
opengl_error ( ) ;
2000-05-12 22:18:14 +02:00
return 0 ;
}
2002-11-27 21:21:24 +01:00
/***********************************************************************
* SetPixelFormat ( X11DRV . @ )
*/
2008-12-16 14:18:49 +01:00
BOOL CDECL X11DRV_SetPixelFormat ( X11DRV_PDEVICE * physDev ,
int iPixelFormat ,
const PIXELFORMATDESCRIPTOR * ppfd ) {
2008-06-23 22:56:10 +02:00
opengl_error ( ) ;
2000-05-12 22:18:14 +02:00
return FALSE ;
}
2002-11-27 21:21:24 +01:00
/***********************************************************************
* SwapBuffers ( X11DRV . @ )
*/
2008-12-16 14:18:49 +01:00
BOOL CDECL X11DRV_SwapBuffers ( X11DRV_PDEVICE * physDev ) {
2008-06-23 22:56:10 +02:00
opengl_error ( ) ;
2000-05-12 22:18:14 +02:00
return FALSE ;
}
2007-11-11 21:32:12 +01:00
/**
* X11DRV_wglCopyContext
*
* For OpenGL32 wglCopyContext .
*/
2008-12-16 14:18:49 +01:00
BOOL CDECL X11DRV_wglCopyContext ( HGLRC hglrcSrc , HGLRC hglrcDst , UINT mask ) {
2008-06-23 22:56:10 +02:00
opengl_error ( ) ;
2007-11-11 21:32:12 +01:00
return FALSE ;
}
2006-11-12 20:23:38 +01:00
/**
* X11DRV_wglCreateContext
*
* For OpenGL32 wglCreateContext .
*/
2008-12-16 14:18:49 +01:00
HGLRC CDECL X11DRV_wglCreateContext ( X11DRV_PDEVICE * physDev ) {
2008-06-23 22:56:10 +02:00
opengl_error ( ) ;
2006-08-29 16:56:57 +02:00
return NULL ;
}
2006-11-12 20:23:38 +01:00
/**
* X11DRV_wglDeleteContext
*
* For OpenGL32 wglDeleteContext .
*/
2008-12-16 14:18:49 +01:00
BOOL CDECL X11DRV_wglDeleteContext ( HGLRC hglrc ) {
2008-06-23 22:56:10 +02:00
opengl_error ( ) ;
2006-08-29 16:56:57 +02:00
return FALSE ;
}
2006-11-12 20:23:38 +01:00
/**
* X11DRV_wglGetProcAddress
*
* For OpenGL32 wglGetProcAddress .
*/
2008-12-16 14:18:49 +01:00
PROC CDECL X11DRV_wglGetProcAddress ( LPCSTR lpszProc ) {
2008-06-23 22:56:10 +02:00
opengl_error ( ) ;
2006-09-11 21:28:32 +02:00
return NULL ;
}
2008-12-16 14:18:49 +01:00
HDC CDECL X11DRV_wglGetPbufferDCARB ( X11DRV_PDEVICE * hDevice , void * hPbuffer )
2006-11-04 22:23:15 +01:00
{
2008-06-23 22:56:10 +02:00
opengl_error ( ) ;
2006-11-04 22:23:15 +01:00
return NULL ;
}
2008-12-16 14:18:49 +01:00
BOOL CDECL X11DRV_wglMakeContextCurrentARB ( X11DRV_PDEVICE * hDrawDev , X11DRV_PDEVICE * hReadDev , HGLRC hglrc ) {
2008-06-23 22:56:10 +02:00
opengl_error ( ) ;
2006-10-31 21:41:02 +01:00
return FALSE ;
}
2006-11-12 20:23:38 +01:00
/**
* X11DRV_wglMakeCurrent
*
* For OpenGL32 wglMakeCurrent .
*/
2008-12-16 14:18:49 +01:00
BOOL CDECL X11DRV_wglMakeCurrent ( X11DRV_PDEVICE * physDev , HGLRC hglrc ) {
2008-06-23 22:56:10 +02:00
opengl_error ( ) ;
2006-08-29 16:58:49 +02:00
return FALSE ;
}
2006-11-12 20:23:38 +01:00
/**
* X11DRV_wglShareLists
*
2008-07-01 22:08:30 +02:00
* For OpenGL32 wglShareLists .
2006-11-12 20:23:38 +01:00
*/
2008-12-16 14:18:49 +01:00
BOOL CDECL X11DRV_wglShareLists ( HGLRC hglrc1 , HGLRC hglrc2 ) {
2008-06-23 22:56:10 +02:00
opengl_error ( ) ;
2006-08-29 16:58:49 +02:00
return FALSE ;
}
2006-11-12 20:23:38 +01:00
/**
* X11DRV_wglUseFontBitmapsA
*
* For OpenGL32 wglUseFontBitmapsA .
*/
2008-12-16 14:18:49 +01:00
BOOL CDECL X11DRV_wglUseFontBitmapsA ( X11DRV_PDEVICE * physDev , DWORD first , DWORD count , DWORD listBase )
2006-09-20 23:23:17 +02:00
{
2008-06-23 22:56:10 +02:00
opengl_error ( ) ;
2006-09-20 23:23:17 +02:00
return FALSE ;
}
2006-11-12 20:23:38 +01:00
/**
* X11DRV_wglUseFontBitmapsW
*
* For OpenGL32 wglUseFontBitmapsW .
*/
2008-12-16 14:18:49 +01:00
BOOL CDECL X11DRV_wglUseFontBitmapsW ( X11DRV_PDEVICE * physDev , DWORD first , DWORD count , DWORD listBase )
2006-09-20 23:23:17 +02:00
{
2008-06-23 22:56:10 +02:00
opengl_error ( ) ;
2006-09-20 23:23:17 +02:00
return FALSE ;
}
2008-04-23 00:15:15 +02:00
/**
* X11DRV_wglSetPixelFormatWINE
*
* WGL_WINE_pixel_format_passthrough : wglSetPixelFormatWINE
* This is a WINE - specific wglSetPixelFormat which can set the pixel format multiple times .
*/
2008-12-16 14:18:49 +01:00
BOOL CDECL X11DRV_wglSetPixelFormatWINE ( X11DRV_PDEVICE * physDev , int iPixelFormat , const PIXELFORMATDESCRIPTOR * ppfd )
2008-04-23 00:15:15 +02:00
{
2008-06-23 22:56:10 +02:00
opengl_error ( ) ;
2008-04-23 00:15:15 +02:00
return FALSE ;
}
2006-06-23 13:13:55 +02:00
Drawable get_glxdrawable ( X11DRV_PDEVICE * physDev )
2005-09-26 13:04:12 +02:00
{
2005-09-28 20:11:17 +02:00
return 0 ;
2005-09-26 13:04:12 +02:00
}
2007-09-26 10:03:39 +02:00
BOOL destroy_glxpixmap ( Display * display , XID glxpixmap )
2005-09-26 13:04:12 +02:00
{
return FALSE ;
}
2007-09-26 07:43:38 +02:00
XVisualInfo * visual_from_fbconfig_id ( XID fbconfig_id )
{
return NULL ;
}
2000-05-12 22:18:14 +02:00
# endif /* defined(HAVE_OPENGL) */