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
2012-06-28 14:13:24 +02:00
* Copyright 2012 Alexandre Julliard
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>
2009-12-03 21:12:26 +01:00
# ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
# endif
# ifdef HAVE_SYS_UN_H
# include <sys/un.h>
# endif
2000-05-12 22:18:14 +02:00
# include "x11drv.h"
2012-08-31 12:22:03 +02:00
# include "xcomposite.h"
2006-08-29 16:58:49 +02:00
# include "winternl.h"
2021-02-24 15:04:53 +01:00
# include "wine/heap.h"
2002-09-25 02:29:56 +02:00
# include "wine/debug.h"
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
2017-02-20 15:28:25 +01:00
WINE_DEFAULT_DEBUG_CHANNEL ( wgl ) ;
2011-10-27 20:17:34 +02:00
WINE_DECLARE_DEBUG_CHANNEL ( winediag ) ;
2012-11-07 17:20:57 +01:00
# include "wine/wgl.h"
2012-07-23 18:40:09 +02:00
# include "wine/wgl_driver.h"
2012-06-26 21:57:46 +02:00
2012-11-07 17:20:57 +01:00
typedef struct __GLXcontextRec * GLXContext ;
typedef struct __GLXFBConfigRec * GLXFBConfig ;
typedef XID GLXPixmap ;
typedef XID GLXDrawable ;
typedef XID GLXFBConfigID ;
typedef XID GLXContextID ;
typedef XID GLXWindow ;
typedef XID GLXPbuffer ;
# define GLX_USE_GL 1
# define GLX_BUFFER_SIZE 2
# define GLX_LEVEL 3
# define GLX_RGBA 4
# define GLX_DOUBLEBUFFER 5
# define GLX_STEREO 6
# define GLX_AUX_BUFFERS 7
# define GLX_RED_SIZE 8
# define GLX_GREEN_SIZE 9
# define GLX_BLUE_SIZE 10
# define GLX_ALPHA_SIZE 11
# define GLX_DEPTH_SIZE 12
# define GLX_STENCIL_SIZE 13
# define GLX_ACCUM_RED_SIZE 14
# define GLX_ACCUM_GREEN_SIZE 15
# define GLX_ACCUM_BLUE_SIZE 16
# define GLX_ACCUM_ALPHA_SIZE 17
# define GLX_BAD_SCREEN 1
# define GLX_BAD_ATTRIBUTE 2
# define GLX_NO_EXTENSION 3
# define GLX_BAD_VISUAL 4
# define GLX_BAD_CONTEXT 5
# define GLX_BAD_VALUE 6
# define GLX_BAD_ENUM 7
# define GLX_VENDOR 1
# define GLX_VERSION 2
# define GLX_EXTENSIONS 3
# define GLX_CONFIG_CAVEAT 0x20
# define GLX_DONT_CARE 0xFFFFFFFF
# define GLX_X_VISUAL_TYPE 0x22
# define GLX_TRANSPARENT_TYPE 0x23
# define GLX_TRANSPARENT_INDEX_VALUE 0x24
# define GLX_TRANSPARENT_RED_VALUE 0x25
# define GLX_TRANSPARENT_GREEN_VALUE 0x26
# define GLX_TRANSPARENT_BLUE_VALUE 0x27
# define GLX_TRANSPARENT_ALPHA_VALUE 0x28
# define GLX_WINDOW_BIT 0x00000001
# define GLX_PIXMAP_BIT 0x00000002
# define GLX_PBUFFER_BIT 0x00000004
# define GLX_AUX_BUFFERS_BIT 0x00000010
# define GLX_FRONT_LEFT_BUFFER_BIT 0x00000001
# define GLX_FRONT_RIGHT_BUFFER_BIT 0x00000002
# define GLX_BACK_LEFT_BUFFER_BIT 0x00000004
# define GLX_BACK_RIGHT_BUFFER_BIT 0x00000008
# define GLX_DEPTH_BUFFER_BIT 0x00000020
# define GLX_STENCIL_BUFFER_BIT 0x00000040
# define GLX_ACCUM_BUFFER_BIT 0x00000080
# define GLX_NONE 0x8000
# define GLX_SLOW_CONFIG 0x8001
# define GLX_TRUE_COLOR 0x8002
# define GLX_DIRECT_COLOR 0x8003
# define GLX_PSEUDO_COLOR 0x8004
# define GLX_STATIC_COLOR 0x8005
# define GLX_GRAY_SCALE 0x8006
# define GLX_STATIC_GRAY 0x8007
# define GLX_TRANSPARENT_RGB 0x8008
# define GLX_TRANSPARENT_INDEX 0x8009
# define GLX_VISUAL_ID 0x800B
# define GLX_SCREEN 0x800C
# define GLX_NON_CONFORMANT_CONFIG 0x800D
# define GLX_DRAWABLE_TYPE 0x8010
# define GLX_RENDER_TYPE 0x8011
# define GLX_X_RENDERABLE 0x8012
# define GLX_FBCONFIG_ID 0x8013
# define GLX_RGBA_TYPE 0x8014
# define GLX_COLOR_INDEX_TYPE 0x8015
# define GLX_MAX_PBUFFER_WIDTH 0x8016
# define GLX_MAX_PBUFFER_HEIGHT 0x8017
# define GLX_MAX_PBUFFER_PIXELS 0x8018
# define GLX_PRESERVED_CONTENTS 0x801B
# define GLX_LARGEST_PBUFFER 0x801C
# define GLX_WIDTH 0x801D
# define GLX_HEIGHT 0x801E
# define GLX_EVENT_MASK 0x801F
# define GLX_DAMAGED 0x8020
# define GLX_SAVED 0x8021
# define GLX_WINDOW 0x8022
# define GLX_PBUFFER 0x8023
# define GLX_PBUFFER_HEIGHT 0x8040
# define GLX_PBUFFER_WIDTH 0x8041
2014-11-10 18:56:11 +01:00
# define GLX_SWAP_METHOD_OML 0x8060
# define GLX_SWAP_EXCHANGE_OML 0x8061
# define GLX_SWAP_COPY_OML 0x8062
# define GLX_SWAP_UNDEFINED_OML 0x8063
2012-11-07 17:20:57 +01:00
# define GLX_RGBA_BIT 0x00000001
# define GLX_COLOR_INDEX_BIT 0x00000002
# define GLX_PBUFFER_CLOBBER_MASK 0x08000000
/** GLX_ARB_multisample */
# define GLX_SAMPLE_BUFFERS_ARB 100000
# define GLX_SAMPLES_ARB 100001
/** GLX_ARB_framebuffer_sRGB */
# define GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20B2
/** GLX_EXT_fbconfig_packed_float */
# define GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT 0x20B1
# define GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT 0x00000008
/** GLX_ARB_create_context */
# define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
# define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
# define GLX_CONTEXT_FLAGS_ARB 0x2094
2018-01-24 17:33:22 +01:00
/** GLX_ARB_create_context_no_error */
# define GLX_CONTEXT_OPENGL_NO_ERROR_ARB 0x31B3
2012-11-07 17:20:57 +01:00
/** GLX_ARB_create_context_profile */
# define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126
2012-06-26 21:57:46 +02:00
/** GLX_ATI_pixel_format_float */
# define GLX_RGBA_FLOAT_ATI_BIT 0x00000100
/** GLX_ARB_pixel_format_float */
# define GLX_RGBA_FLOAT_BIT 0x00000004
# define GLX_RGBA_FLOAT_TYPE 0x20B9
2016-03-15 16:55:13 +01:00
/** GLX_MESA_query_renderer */
# define GLX_RENDERER_ID_MESA 0x818E
2012-06-26 21:57:46 +02:00
/** GLX_NV_float_buffer */
# define GLX_FLOAT_COMPONENTS_NV 0x20B0
2006-09-11 21:28:32 +02:00
2002-09-25 02:29:56 +02:00
2018-02-12 16:06:01 +01:00
static char * glExtensions ;
static const char * glxExtensions ;
static char wglExtensions [ 4096 ] ;
static int glxVersion [ 2 ] ;
2019-05-06 18:46:31 +02:00
static int glx_opcode ;
2006-09-11 21:28:32 +02:00
2012-08-15 15:38:05 +02:00
struct wgl_pixel_format
{
2007-07-26 19:23:39 +02:00
GLXFBConfig fbconfig ;
2018-02-09 09:42:53 +01:00
XVisualInfo * visual ;
2007-07-26 19:23:39 +02:00
int fmt_id ;
2007-07-28 18:56:12 +02:00
int render_type ;
2009-05-14 17:05:20 +02:00
DWORD dwFlags ; /* We store some PFD_* flags in here for emulated bitmap formats */
2012-08-15 15:38:05 +02:00
} ;
2006-11-18 23:29:48 +01:00
2012-06-29 12:29:55 +02:00
struct wgl_context
{
2007-07-28 18:56:12 +02:00
HDC hdc ;
2009-11-15 12:09:08 +01:00
BOOL has_been_current ;
BOOL sharing ;
2009-11-16 23:24:24 +01:00
BOOL gl3_context ;
2012-08-15 15:38:05 +02:00
const struct wgl_pixel_format * fmt ;
2009-11-16 23:24:24 +01:00
int numAttribs ; /* This is needed for delaying wglCreateContextAttribsARB */
int attribList [ 16 ] ; /* This is needed for delaying wglCreateContextAttribsARB */
2007-07-28 18:56:12 +02:00
GLXContext ctx ;
2018-02-12 15:41:45 +01:00
struct gl_drawable * drawables [ 2 ] ;
struct gl_drawable * new_drawables [ 2 ] ;
2007-09-26 16:15:52 +02:00
BOOL refresh_drawables ;
2012-05-07 12:57:29 +02:00
struct list entry ;
2012-06-29 12:29:55 +02:00
} ;
2007-07-28 18:56:12 +02:00
2012-07-20 12:25:01 +02:00
struct wgl_pbuffer
{
2007-07-27 15:19:46 +02:00
Drawable drawable ;
2012-08-15 15:38:05 +02:00
const struct wgl_pixel_format * fmt ;
2007-07-27 15:19:46 +02:00
int width ;
int height ;
int * attribList ;
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 ;
2016-03-15 18:58:26 +01:00
GLXContext tmp_context ;
GLXContext prev_context ;
struct list entry ;
2012-07-20 12:25:01 +02:00
} ;
2007-07-27 15:19:46 +02:00
2012-08-31 12:22:03 +02:00
enum dc_gl_type
{
DC_GL_NONE , /* no GL support (pixel format not set yet) */
DC_GL_WINDOW , /* normal top-level window */
DC_GL_CHILD_WIN , /* child window using XComposite */
DC_GL_PIXMAP_WIN , /* child window using intermediate pixmap */
DC_GL_PBUFFER /* pseudo memory DC using a PBuffer */
} ;
struct gl_drawable
{
2018-02-12 15:34:28 +01:00
LONG ref ; /* reference count */
2012-09-07 15:36:57 +02:00
enum dc_gl_type type ; /* type of GL surface */
2016-05-26 23:43:14 +02:00
GLXDrawable drawable ; /* drawable for rendering with GL */
Window window ; /* window if drawable is a GLXWindow */
2012-09-07 15:36:57 +02:00
Pixmap pixmap ; /* base pixmap if drawable is a GLXPixmap */
const struct wgl_pixel_format * format ; /* pixel format for the drawable */
2018-02-09 13:08:04 +01:00
SIZE pixmap_size ; /* pixmap size for GLXPixmap drawables */
2013-05-12 02:55:18 +02:00
int swap_interval ;
2014-04-01 04:46:48 +02:00
BOOL refresh_swap_interval ;
2021-04-20 19:43:50 +02:00
BOOL mutable_pf ;
2012-08-31 12:22:03 +02:00
} ;
2013-09-02 06:58:53 +02:00
enum glx_swap_control_method
{
GLX_SWAP_CONTROL_NONE ,
GLX_SWAP_CONTROL_EXT ,
2013-09-15 04:57:39 +02:00
GLX_SWAP_CONTROL_SGI ,
GLX_SWAP_CONTROL_MESA
2013-09-02 06:58:53 +02:00
} ;
2012-08-31 12:22:03 +02:00
/* X context to associate a struct gl_drawable to an hwnd */
2012-09-07 15:23:15 +02:00
static XContext gl_hwnd_context ;
/* X context to associate a struct gl_drawable to a pbuffer hdc */
static XContext gl_pbuffer_context ;
2012-08-31 12:22:03 +02:00
2012-05-07 12:57:29 +02:00
static struct list context_list = LIST_INIT ( context_list ) ;
2016-03-15 18:58:26 +01:00
static struct list pbuffer_list = LIST_INIT ( pbuffer_list ) ;
2012-08-15 15:38:05 +02:00
static struct wgl_pixel_format * pixel_formats ;
2012-08-15 15:32:24 +02:00
static int nb_pixel_formats , nb_onscreen_formats ;
2013-10-09 00:06:15 +02:00
static BOOL use_render_texture_emulation = TRUE ;
2013-09-02 06:58:53 +02:00
/* Selects the preferred GLX swap control method for use by wglSwapIntervalEXT */
static enum glx_swap_control_method swap_control_method = GLX_SWAP_CONTROL_NONE ;
2013-09-02 06:58:54 +02:00
/* Set when GLX_EXT_swap_control_tear is supported, requires GLX_SWAP_CONTROL_EXT */
static BOOL has_swap_control_tear = FALSE ;
2014-11-10 18:56:11 +01:00
static BOOL has_swap_method = FALSE ;
2006-09-11 21:28:32 +02:00
2012-08-14 14:54:39 +02:00
static CRITICAL_SECTION context_section ;
static CRITICAL_SECTION_DEBUG critsect_debug =
{
0 , 0 , & context_section ,
{ & critsect_debug . ProcessLocksList , & critsect_debug . ProcessLocksList } ,
0 , 0 , { ( DWORD_PTR ) ( __FILE__ " : context_section " ) }
} ;
static CRITICAL_SECTION context_section = { & critsect_debug , - 1 , 0 , 0 , 0 , 0 } ;
2013-06-26 03:52:02 +02:00
static const BOOL is_win64 = sizeof ( void * ) > sizeof ( int ) ;
2012-07-16 23:26:50 +02:00
static struct opengl_funcs opengl_funcs ;
# define USE_GL_FUNC(name) #name,
static const char * opengl_func_names [ ] = { ALL_WGL_FUNCS } ;
# undef USE_GL_FUNC
2006-09-12 11:50:36 +02:00
static void X11DRV_WineGL_LoadExtensions ( void ) ;
2012-08-15 15:32:24 +02:00
static void init_pixel_formats ( Display * display ) ;
2007-08-08 16:40:34 +02:00
static BOOL glxRequireVersion ( int requiredVersion ) ;
2006-08-29 16:56:57 +02:00
2004-11-30 22:38:57 +01:00
static void dump_PIXELFORMATDESCRIPTOR ( const PIXELFORMATDESCRIPTOR * ppfd ) {
2018-09-13 16:17:37 +02:00
TRACE ( " size %u version %u flags %u type %u color %u %u,%u,%u,%u "
" accum %u depth %u stencil %u aux %u " ,
ppfd - > nSize , ppfd - > nVersion , ppfd - > dwFlags , ppfd - > iPixelType ,
ppfd - > cColorBits , ppfd - > cRedBits , ppfd - > cGreenBits , ppfd - > cBlueBits , ppfd - > cAlphaBits ,
ppfd - > cAccumBits , ppfd - > cDepthBits , ppfd - > cStencilBits , ppfd - > cAuxBuffers ) ;
2005-09-25 17:23:21 +02:00
# 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 " ) ;
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)
/* GLX 1.0 */
2012-11-07 17:20:57 +01:00
static XVisualInfo * ( * pglXChooseVisual ) ( Display * dpy , int screen , int * attribList ) ;
static GLXContext ( * pglXCreateContext ) ( Display * dpy , XVisualInfo * vis , GLXContext shareList , Bool direct ) ;
static void ( * pglXDestroyContext ) ( Display * dpy , GLXContext ctx ) ;
static Bool ( * pglXMakeCurrent ) ( Display * dpy , GLXDrawable drawable , GLXContext ctx ) ;
static void ( * pglXCopyContext ) ( Display * dpy , GLXContext src , GLXContext dst , unsigned long mask ) ;
static void ( * pglXSwapBuffers ) ( Display * dpy , GLXDrawable drawable ) ;
static Bool ( * pglXQueryVersion ) ( Display * dpy , int * maj , int * min ) ;
static Bool ( * pglXIsDirect ) ( Display * dpy , GLXContext ctx ) ;
static GLXContext ( * pglXGetCurrentContext ) ( void ) ;
static GLXDrawable ( * pglXGetCurrentDrawable ) ( void ) ;
2006-09-11 21:28:32 +02:00
/* GLX 1.1 */
2012-11-07 17:20:57 +01:00
static const char * ( * pglXQueryExtensionsString ) ( Display * dpy , int screen ) ;
static const char * ( * pglXQueryServerString ) ( Display * dpy , int screen , int name ) ;
static const char * ( * pglXGetClientString ) ( Display * dpy , int name ) ;
2005-04-28 20:29:12 +02:00
2006-09-11 21:28:32 +02:00
/* GLX 1.3 */
2012-11-07 17:20:57 +01:00
static GLXFBConfig * ( * pglXChooseFBConfig ) ( Display * dpy , int screen , const int * attribList , int * nitems ) ;
static int ( * pglXGetFBConfigAttrib ) ( Display * dpy , GLXFBConfig config , int attribute , int * value ) ;
static GLXFBConfig * ( * pglXGetFBConfigs ) ( Display * dpy , int screen , int * nelements ) ;
static XVisualInfo * ( * pglXGetVisualFromFBConfig ) ( Display * dpy , GLXFBConfig config ) ;
static GLXPbuffer ( * pglXCreatePbuffer ) ( Display * dpy , GLXFBConfig config , const int * attribList ) ;
static void ( * pglXDestroyPbuffer ) ( Display * dpy , GLXPbuffer pbuf ) ;
static void ( * pglXQueryDrawable ) ( Display * dpy , GLXDrawable draw , int attribute , unsigned int * value ) ;
static GLXContext ( * pglXCreateNewContext ) ( Display * dpy , GLXFBConfig config , int renderType , GLXContext shareList , Bool direct ) ;
static Bool ( * pglXMakeContextCurrent ) ( Display * dpy , GLXDrawable draw , GLXDrawable read , GLXContext ctx ) ;
2016-05-26 23:43:13 +02:00
static GLXPixmap ( * pglXCreatePixmap ) ( Display * dpy , GLXFBConfig config , Pixmap pixmap , const int * attrib_list ) ;
static void ( * pglXDestroyPixmap ) ( Display * dpy , GLXPixmap pixmap ) ;
2016-05-26 23:43:14 +02:00
static GLXWindow ( * pglXCreateWindow ) ( Display * dpy , GLXFBConfig config , Window win , const int * attrib_list ) ;
static void ( * pglXDestroyWindow ) ( Display * dpy , GLXWindow win ) ;
2006-08-29 16:58:49 +02:00
2006-09-11 21:28:32 +02:00
/* GLX Extensions */
2009-11-16 23:24:24 +01:00
static GLXContext ( * pglXCreateContextAttribsARB ) ( Display * dpy , GLXFBConfig config , GLXContext share_context , Bool direct , const int * attrib_list ) ;
2006-09-11 21:28:32 +02:00
static void * ( * pglXGetProcAddressARB ) ( const GLubyte * ) ;
2013-09-02 06:58:53 +02:00
static void ( * pglXSwapIntervalEXT ) ( Display * dpy , GLXDrawable drawable , int interval ) ;
2006-09-11 21:28:32 +02:00
static int ( * pglXSwapIntervalSGI ) ( int ) ;
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 ) ;
2013-09-15 04:57:39 +02:00
static int ( * pglXSwapIntervalMESA ) ( unsigned int interval ) ;
2016-03-15 16:55:13 +01:00
static Bool ( * pglXQueryCurrentRendererIntegerMESA ) ( int attribute , unsigned int * value ) ;
static const char * ( * pglXQueryCurrentRendererStringMESA ) ( int attribute ) ;
static Bool ( * pglXQueryRendererIntegerMESA ) ( Display * dpy , int screen , int renderer , int attribute , unsigned int * value ) ;
static const char * ( * pglXQueryRendererStringMESA ) ( Display * dpy , int screen , int renderer , int attribute ) ;
2007-09-26 20:01:07 +02:00
2017-03-23 23:58:10 +01:00
/* OpenML GLX Extensions */
static Bool ( * pglXWaitForSbcOML ) ( Display * dpy , GLXDrawable drawable ,
INT64 target_sbc , INT64 * ust , INT64 * msc , INT64 * sbc ) ;
static INT64 ( * pglXSwapBuffersMscOML ) ( Display * dpy , GLXDrawable drawable ,
INT64 target_msc , INT64 divisor , INT64 remainder ) ;
2006-09-11 21:28:32 +02:00
/* Standard OpenGL */
2012-07-16 23:56:55 +02:00
static void ( * pglFinish ) ( void ) ;
static void ( * pglFlush ) ( void ) ;
2013-08-12 23:07:05 +02:00
static const GLubyte * ( * pglGetString ) ( GLenum name ) ;
2012-07-16 23:56:55 +02:00
static void wglFinish ( void ) ;
static void wglFlush ( void ) ;
2013-08-12 23:07:05 +02:00
static const GLubyte * wglGetString ( GLenum name ) ;
2012-07-16 23:56:55 +02:00
2012-07-24 17:37:39 +02:00
/* check if the extension is present in the list */
static BOOL has_extension ( const char * list , const char * ext )
{
size_t len = strlen ( ext ) ;
while ( list )
{
while ( * list = = ' ' ) list + + ;
if ( ! strncmp ( list , ext , len ) & & ( ! list [ len ] | | list [ len ] = = ' ' ) ) return TRUE ;
list = strchr ( list , ' ' ) ;
}
return FALSE ;
}
2009-11-16 23:24:24 +01:00
static int GLXErrorHandler ( Display * dpy , XErrorEvent * event , void * arg )
{
/* In the future we might want to find the exact X or GLX error to report back to the app */
2019-05-06 18:46:31 +02:00
if ( event - > request_code ! = glx_opcode )
return 0 ;
2009-11-16 23:24:24 +01:00
return 1 ;
}
2006-10-31 21:41:02 +01:00
static BOOL X11DRV_WineGL_InitOpenglInfo ( void )
2006-09-11 21:28:32 +02:00
{
2013-08-12 23:07:05 +02:00
static const char legacy_extensions [ ] = " WGL_EXT_extensions_string WGL_EXT_swap_control " ;
2006-09-11 21:28:32 +02:00
int screen = DefaultScreen ( gdi_display ) ;
2010-05-06 14:57:44 +02:00
Window win = 0 , root = 0 ;
2018-02-12 16:06:01 +01:00
const char * gl_version ;
2011-10-09 19:01:20 +02:00
const char * gl_renderer ;
2009-05-26 00:52:05 +02:00
const char * str ;
2018-02-12 16:06:01 +01:00
BOOL glx_direct ;
2006-09-11 21:28:32 +02:00
XVisualInfo * vis ;
GLXContext ctx = NULL ;
2010-05-06 14:57:44 +02:00
XSetWindowAttributes attr ;
BOOL ret = FALSE ;
2009-07-31 22:50:36 +02:00
int attribList [ ] = { GLX_RGBA , GLX_DOUBLEBUFFER , None } ;
2006-09-11 21:28:32 +02:00
2010-05-06 14:57:44 +02:00
attr . override_redirect = True ;
attr . colormap = None ;
2011-02-15 05:28:18 +01:00
attr . border_pixel = 0 ;
2010-05-06 14:57:44 +02:00
2009-07-31 22:50:36 +02:00
vis = pglXChooseVisual ( gdi_display , screen , attribList ) ;
2006-09-11 21:28:32 +02:00
if ( vis ) {
2009-12-24 12:58:51 +01:00
# ifdef __i386__
2020-04-03 10:47:00 +02:00
WORD old_fs , new_fs ;
__asm__ ( " mov %%fs,%0 " : " =r " ( old_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 ) ;
2020-04-03 10:47:00 +02:00
__asm__ ( " mov %%fs,%0 " : " =r " ( new_fs ) ) ;
__asm__ ( " mov %0,%%fs " : : " r " ( old_fs ) ) ;
if ( old_fs ! = new_fs )
2007-02-14 18:18:07 +01:00
{
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 " ) ;
2010-05-06 14:57:44 +02:00
goto done ;
2007-02-14 18:18:07 +01:00
}
2009-12-24 12:58:51 +01:00
# else
ctx = pglXCreateContext ( gdi_display , vis , None , GL_TRUE ) ;
# endif
2006-09-11 21:28:32 +02:00
}
2010-05-06 14:57:44 +02:00
if ( ! ctx ) goto done ;
root = RootWindow ( gdi_display , vis - > screen ) ;
if ( vis - > visual ! = DefaultVisual ( gdi_display , vis - > screen ) )
attr . colormap = XCreateColormap ( gdi_display , root , vis - > visual , AllocNone ) ;
if ( ( win = XCreateWindow ( gdi_display , root , - 1 , - 1 , 1 , 1 , 0 , vis - > depth , InputOutput ,
2011-02-15 05:28:18 +01:00
vis - > visual , CWBorderPixel | CWOverrideRedirect | CWColormap , & attr ) ) )
2010-05-06 14:57:44 +02:00
XMapWindow ( gdi_display , win ) ;
else
win = root ;
2006-09-11 21:28:32 +02:00
2011-03-24 07:50:33 +01:00
if ( pglXMakeCurrent ( gdi_display , win , ctx ) = = 0 )
{
2013-06-26 03:52:02 +02:00
ERR_ ( winediag ) ( " Unable to activate OpenGL context, most likely your %s OpenGL drivers haven't been "
" installed correctly \n " , is_win64 ? " 64-bit " : " 32-bit " ) ;
2011-03-24 07:50:33 +01:00
goto done ;
}
2012-07-17 00:00:55 +02:00
gl_renderer = ( const char * ) opengl_funcs . gl . p_glGetString ( GL_RENDERER ) ;
2018-02-12 16:06:01 +01:00
gl_version = ( const char * ) opengl_funcs . gl . p_glGetString ( GL_VERSION ) ;
2012-07-17 00:00:55 +02:00
str = ( const char * ) opengl_funcs . gl . p_glGetString ( GL_EXTENSIONS ) ;
2018-02-12 16:06:01 +01:00
glExtensions = HeapAlloc ( GetProcessHeap ( ) , 0 , strlen ( str ) + sizeof ( legacy_extensions ) ) ;
strcpy ( glExtensions , str ) ;
strcat ( glExtensions , legacy_extensions ) ;
2006-09-11 21:28:32 +02:00
/* Get the common GLX version supported by GLX client and server ( major/minor) */
2018-02-12 16:06:01 +01:00
pglXQueryVersion ( gdi_display , & glxVersion [ 0 ] , & glxVersion [ 1 ] ) ;
2006-09-11 21:28:32 +02:00
2018-02-12 16:06:01 +01:00
glxExtensions = pglXQueryExtensionsString ( gdi_display , screen ) ;
glx_direct = pglXIsDirect ( gdi_display , ctx ) ;
2006-09-11 21:28:32 +02:00
2018-02-12 16:06:01 +01:00
TRACE ( " GL version : %s. \n " , gl_version ) ;
2011-10-09 19:01:20 +02:00
TRACE ( " GL renderer : %s. \n " , gl_renderer ) ;
2018-02-12 16:06:01 +01:00
TRACE ( " GLX version : %d.%d. \n " , glxVersion [ 0 ] , glxVersion [ 1 ] ) ;
TRACE ( " Server GLX version : %s. \n " , pglXQueryServerString ( gdi_display , screen , GLX_VERSION ) ) ;
TRACE ( " Server GLX vendor: : %s. \n " , pglXQueryServerString ( gdi_display , screen , GLX_VENDOR ) ) ;
TRACE ( " Client GLX version : %s. \n " , pglXGetClientString ( gdi_display , GLX_VERSION ) ) ;
TRACE ( " Client GLX vendor: : %s. \n " , pglXGetClientString ( gdi_display , GLX_VENDOR ) ) ;
TRACE ( " Direct rendering enabled: %s \n " , glx_direct ? " True " : " False " ) ;
2006-09-11 21:28:32 +02:00
2018-02-12 16:06:01 +01:00
if ( ! glx_direct )
2009-12-03 21:12:26 +01:00
{
int fd = ConnectionNumber ( gdi_display ) ;
struct sockaddr_un uaddr ;
unsigned int uaddrlen = sizeof ( struct sockaddr_un ) ;
/* In general indirect rendering on a local X11 server indicates a driver problem.
* Detect a local X11 server by checking whether the X11 socket is a Unix socket .
*/
2009-12-09 13:13:29 +01:00
if ( ! getsockname ( fd , ( struct sockaddr * ) & uaddr , & uaddrlen ) & & uaddr . sun_family = = AF_UNIX )
2013-06-26 03:52:02 +02:00
ERR_ ( winediag ) ( " Direct rendering is disabled, most likely your %s OpenGL drivers "
2011-10-09 19:01:20 +02:00
" haven't been installed correctly (using GL renderer %s, version %s). \n " ,
2013-06-26 03:52:02 +02:00
is_win64 ? " 64-bit " : " 32-bit " , debugstr_a ( gl_renderer ) ,
2018-02-12 16:06:01 +01:00
debugstr_a ( gl_version ) ) ;
2009-12-03 21:12:26 +01:00
}
2010-03-11 14:10:51 +01:00
else
{
/* In general you would expect that if direct rendering is returned, that you receive hardware
* accelerated OpenGL rendering . The definition of direct rendering is that rendering is performed
* client side without sending all GL commands to X using the GLX protocol . When Mesa falls back to
* software rendering , it shows direct rendering .
*
* Depending on the cause of software rendering a different rendering string is shown . In case Mesa fails
* to load a DRI module ' Software Rasterizer ' is returned . When Mesa is compiled as a OpenGL reference driver
* it shows ' Mesa X11 ' .
*/
if ( ! strcmp ( gl_renderer , " Software Rasterizer " ) | | ! strcmp ( gl_renderer , " Mesa X11 " ) )
2013-06-26 03:52:02 +02:00
ERR_ ( winediag ) ( " The Mesa OpenGL driver is using software rendering, most likely your %s OpenGL "
2011-10-09 19:01:20 +02:00
" drivers haven't been installed correctly (using GL renderer %s, version %s). \n " ,
2013-06-26 03:52:02 +02:00
is_win64 ? " 64-bit " : " 32-bit " , debugstr_a ( gl_renderer ) ,
2018-02-12 16:06:01 +01:00
debugstr_a ( gl_version ) ) ;
2010-03-11 14:10:51 +01:00
}
2010-05-06 14:57:44 +02:00
ret = TRUE ;
2009-12-03 21:12:26 +01:00
2010-05-06 14:57:44 +02:00
done :
2006-09-11 21:28:32 +02:00
if ( vis ) XFree ( vis ) ;
2006-09-18 20:13:21 +02:00
if ( ctx ) {
pglXMakeCurrent ( gdi_display , None , NULL ) ;
pglXDestroyContext ( gdi_display , ctx ) ;
}
2010-05-06 14:57:44 +02:00
if ( win ! = root ) XDestroyWindow ( gdi_display , win ) ;
if ( attr . colormap ) XFreeColormap ( gdi_display , attr . colormap ) ;
if ( ! ret ) ERR ( " couldn't initialize OpenGL, expect problems \n " ) ;
return ret ;
2006-09-11 21:28:32 +02:00
}
2016-04-13 16:31:07 +02:00
static void * opengl_handle ;
2005-06-29 21:28:06 +02:00
2016-04-13 16:31:07 +02:00
static BOOL WINAPI init_opengl ( INIT_ONCE * once , void * param , void * * context )
{
2002-11-15 05:16:38 +01:00
int error_base , event_base ;
2012-07-16 23:26:50 +02:00
unsigned int i ;
2002-11-15 05:16:38 +01:00
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 */
2020-04-06 22:43:15 +02:00
opengl_handle = dlopen ( SONAME_LIBGL , RTLD_NOW | RTLD_GLOBAL ) ;
2008-06-23 22:56:10 +02:00
if ( opengl_handle = = NULL )
{
2020-04-06 22:43:15 +02:00
ERR ( " Failed to load libGL: %s \n " , dlerror ( ) ) ;
2008-06-23 22:56:10 +02:00
ERR ( " OpenGL support is disabled. \n " ) ;
2016-04-13 16:31:07 +02:00
return TRUE ;
2006-09-11 21:28:32 +02:00
}
2018-09-19 21:01:10 +02:00
for ( i = 0 ; i < ARRAY_SIZE ( opengl_func_names ) ; i + + )
2012-07-16 23:26:50 +02:00
{
2020-04-06 22:43:15 +02:00
if ( ! ( ( ( void * * ) & opengl_funcs . gl ) [ i ] = dlsym ( opengl_handle , opengl_func_names [ i ] ) ) )
2012-07-16 23:26:50 +02:00
{
ERR ( " %s not found in libGL, disabling OpenGL. \n " , opengl_func_names [ i ] ) ;
goto failed ;
}
}
2012-07-16 23:56:55 +02:00
/* redirect some standard OpenGL functions */
# define REDIRECT(func) \
do { p # # func = opengl_funcs . gl . p_ # # func ; opengl_funcs . gl . p_ # # func = w # # func ; } while ( 0 )
REDIRECT ( glFinish ) ;
REDIRECT ( glFlush ) ;
2013-08-12 23:07:05 +02:00
REDIRECT ( glGetString ) ;
2012-07-16 23:56:55 +02:00
# undef REDIRECT
2020-04-06 22:43:15 +02:00
pglXGetProcAddressARB = dlsym ( opengl_handle , " glXGetProcAddressARB " ) ;
2008-06-23 22:56:10 +02:00
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 ( glXGetCurrentContext ) ;
LOAD_FUNCPTR ( glXGetCurrentDrawable ) ;
LOAD_FUNCPTR ( glXDestroyContext ) ;
LOAD_FUNCPTR ( glXIsDirect ) ;
LOAD_FUNCPTR ( glXMakeCurrent ) ;
LOAD_FUNCPTR ( glXSwapBuffers ) ;
LOAD_FUNCPTR ( glXQueryVersion ) ;
/* 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 ( glXGetFBConfigs ) ;
2016-05-26 23:43:13 +02:00
LOAD_FUNCPTR ( glXCreatePixmap ) ;
LOAD_FUNCPTR ( glXDestroyPixmap ) ;
2016-05-26 23:43:14 +02:00
LOAD_FUNCPTR ( glXCreateWindow ) ;
LOAD_FUNCPTR ( glXDestroyWindow ) ;
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 ) */
2010-12-27 13:44:11 +01:00
# define LOAD_FUNCPTR(f) p##f = pglXGetProcAddressARB((const GLubyte *)#f)
2009-11-16 23:24:24 +01:00
/* ARB GLX Extension */
LOAD_FUNCPTR ( glXCreateContextAttribsARB ) ;
2013-09-02 06:58:53 +02:00
/* EXT GLX Extension */
LOAD_FUNCPTR ( glXSwapIntervalEXT ) ;
2013-09-15 04:57:39 +02:00
/* MESA GLX Extension */
LOAD_FUNCPTR ( glXSwapIntervalMESA ) ;
2010-12-27 13:44:11 +01:00
/* SGI GLX Extension */
LOAD_FUNCPTR ( glXSwapIntervalSGI ) ;
2008-06-23 22:56:10 +02:00
/* 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
2019-05-06 18:46:31 +02:00
if ( XQueryExtension ( gdi_display , " GLX " , & glx_opcode , & event_base , & error_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
ERR ( " GLX extension is missing, disabling OpenGL. \n " ) ;
goto failed ;
2002-11-15 05:16:38 +01:00
}
2012-09-07 15:23:15 +02:00
gl_hwnd_context = XUniqueContext ( ) ;
gl_pbuffer_context = XUniqueContext ( ) ;
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 " ) ;
2018-02-12 16:06:01 +01:00
} else if ( has_extension ( glxExtensions , " 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 ;
2018-02-12 16:06:01 +01:00
} else if ( strcmp ( " ATI " , pglXGetClientString ( gdi_display , GLX_VENDOR ) ) = = 0 ) {
2007-08-08 16:40:34 +02:00
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 . */
2018-02-12 16:06:01 +01:00
glxExtensions = pglXGetClientString ( gdi_display , GLX_EXTENSIONS ) ;
2007-08-08 16:40:34 +02:00
} else {
2018-02-12 16:06:01 +01:00
ERR ( " glx_version is %s and GLX_SGIX_fbconfig extension is unsupported. Expect problems. \n " ,
pglXQueryServerString ( gdi_display , DefaultScreen ( gdi_display ) , GLX_VERSION ) ) ;
2007-08-08 16:40:34 +02:00
}
2006-08-29 16:58:49 +02:00
2018-02-12 16:06:01 +01:00
if ( has_extension ( glxExtensions , " 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
}
2018-02-12 16:06:01 +01:00
if ( has_extension ( glxExtensions , " GLX_MESA_query_renderer " ) )
2016-03-15 16:55:13 +01:00
{
pglXQueryCurrentRendererIntegerMESA = pglXGetProcAddressARB (
( const GLubyte * ) " glXQueryCurrentRendererIntegerMESA " ) ;
pglXQueryCurrentRendererStringMESA = pglXGetProcAddressARB (
( const GLubyte * ) " glXQueryCurrentRendererStringMESA " ) ;
pglXQueryRendererIntegerMESA = pglXGetProcAddressARB ( ( const GLubyte * ) " glXQueryRendererIntegerMESA " ) ;
pglXQueryRendererStringMESA = pglXGetProcAddressARB ( ( const GLubyte * ) " glXQueryRendererStringMESA " ) ;
}
2018-02-12 16:06:01 +01:00
if ( has_extension ( glxExtensions , " GLX_OML_sync_control " ) )
2017-03-23 23:58:10 +01:00
{
pglXWaitForSbcOML = pglXGetProcAddressARB ( ( const GLubyte * ) " glXWaitForSbcOML " ) ;
pglXSwapBuffersMscOML = pglXGetProcAddressARB ( ( const GLubyte * ) " glXSwapBuffersMscOML " ) ;
}
2006-09-11 21:28:32 +02:00
X11DRV_WineGL_LoadExtensions ( ) ;
2012-08-15 15:32:24 +02:00
init_pixel_formats ( gdi_display ) ;
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 :
2020-04-06 22:43:15 +02:00
dlclose ( opengl_handle ) ;
2002-11-15 05:16:38 +01:00
opengl_handle = NULL ;
2016-04-13 16:31:07 +02:00
return TRUE ;
}
static BOOL has_opengl ( void )
{
static INIT_ONCE init_once = INIT_ONCE_STATIC_INIT ;
InitOnceExecuteOnce ( & init_once , init_opengl , NULL , NULL ) ;
return opengl_handle ! = NULL ;
2002-11-15 05:16:38 +01:00
}
2015-11-18 15:05:20 +01:00
static const char * debugstr_fbconfig ( GLXFBConfig fbconfig )
{
int id , visual , drawable ;
if ( pglXGetFBConfigAttrib ( gdi_display , fbconfig , GLX_FBCONFIG_ID , & id ) )
return " *** invalid fbconfig " ;
pglXGetFBConfigAttrib ( gdi_display , fbconfig , GLX_VISUAL_ID , & visual ) ;
pglXGetFBConfigAttrib ( gdi_display , fbconfig , GLX_DRAWABLE_TYPE , & drawable ) ;
return wine_dbg_sprintf ( " fbconfig %#x visual id %#x drawable type %#x " , id , visual , drawable ) ;
2006-08-29 16:58:49 +02:00
}
2012-07-20 12:25:01 +02:00
static int ConvertAttribWGLtoGLX ( const int * iWGLAttr , int * oGLXAttr , struct wgl_pbuffer * pbuf ) {
2006-09-11 21:28:32 +02:00
int nAttribs = 0 ;
unsigned cur = 0 ;
2019-09-12 05:06:10 +02:00
int attr , 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 ;
2012-03-27 20:35:49 +02:00
int pixelattrib = GLX_DONT_CARE ;
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 ] ) {
2019-09-12 05:06:10 +02:00
attr = iWGLAttr [ cur ] ;
TRACE ( " pAttr[%d] = %x \n " , cur , attr ) ;
pop = iWGLAttr [ + + cur ] ;
2006-09-11 21:28:32 +02:00
2019-09-12 05:06:10 +02:00
switch ( attr ) {
2008-03-03 23:45:25 +01:00
case WGL_AUX_BUFFERS_ARB :
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 :
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 :
PUSH2 ( oGLXAttr , GLX_BLUE_SIZE , pop ) ;
TRACE ( " pAttr[%d] = GLX_BLUE_SIZE: %d \n " , cur , pop ) ;
break ;
case WGL_RED_BITS_ARB :
PUSH2 ( oGLXAttr , GLX_RED_SIZE , pop ) ;
TRACE ( " pAttr[%d] = GLX_RED_SIZE: %d \n " , cur , pop ) ;
break ;
case WGL_GREEN_BITS_ARB :
PUSH2 ( oGLXAttr , GLX_GREEN_SIZE , pop ) ;
TRACE ( " pAttr[%d] = GLX_GREEN_SIZE: %d \n " , cur , pop ) ;
break ;
case WGL_ALPHA_BITS_ARB :
PUSH2 ( oGLXAttr , GLX_ALPHA_SIZE , pop ) ;
TRACE ( " pAttr[%d] = GLX_ALPHA_SIZE: %d \n " , cur , pop ) ;
break ;
case WGL_DEPTH_BITS_ARB :
PUSH2 ( oGLXAttr , GLX_DEPTH_SIZE , pop ) ;
TRACE ( " pAttr[%d] = GLX_DEPTH_SIZE: %d \n " , cur , pop ) ;
break ;
case WGL_STENCIL_BITS_ARB :
PUSH2 ( oGLXAttr , GLX_STENCIL_SIZE , pop ) ;
TRACE ( " pAttr[%d] = GLX_STENCIL_SIZE: %d \n " , cur , pop ) ;
break ;
case WGL_DOUBLE_BUFFER_ARB :
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 :
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 :
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 ) ;
}
break ;
case WGL_SUPPORT_GDI_ARB :
2012-08-15 15:38:05 +02:00
/* This flag is set in a pixel format */
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 :
2012-08-15 15:38:05 +02:00
/* This flag is set in a pixel format */
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 :
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 :
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 :
2012-08-15 15:38:05 +02:00
/* This flag is set in a pixel format */
2009-05-19 00:23:05 +02:00
TRACE ( " pAttr[%d] = WGL_ACCELERATION_ARB: %d \n " , cur , pop ) ;
break ;
2006-09-11 21:28:32 +02:00
case WGL_SUPPORT_OPENGL_ARB :
/** 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 :
TRACE ( " pAttr[%d] = WGL_SWAP_METHOD_ARB: %#x \n " , cur , pop ) ;
2014-11-10 18:56:11 +01:00
if ( has_swap_method )
{
switch ( pop )
{
case WGL_SWAP_EXCHANGE_ARB :
pop = GLX_SWAP_EXCHANGE_OML ;
break ;
case WGL_SWAP_COPY_ARB :
pop = GLX_SWAP_COPY_OML ;
break ;
case WGL_SWAP_UNDEFINED_ARB :
pop = GLX_SWAP_UNDEFINED_OML ;
break ;
default :
ERR ( " Unexpected swap method %#x. \n " , pop ) ;
pop = GLX_DONT_CARE ;
}
PUSH2 ( oGLXAttr , GLX_SWAP_METHOD_OML , pop ) ;
}
else
{
WARN ( " GLX_OML_swap_method not supported, ignoring attribute. \n " ) ;
}
2009-05-16 00:00:24 +02:00
break ;
2006-09-11 21:28:32 +02:00
case WGL_PBUFFER_LARGEST_ARB :
PUSH2 ( oGLXAttr , GLX_LARGEST_PBUFFER , pop ) ;
TRACE ( " pAttr[%d] = GLX_LARGEST_PBUFFER: %x \n " , cur , pop ) ;
break ;
case WGL_SAMPLE_BUFFERS_ARB :
PUSH2 ( oGLXAttr , GLX_SAMPLE_BUFFERS_ARB , pop ) ;
TRACE ( " pAttr[%d] = GLX_SAMPLE_BUFFERS_ARB: %x \n " , cur , pop ) ;
break ;
case WGL_SAMPLES_ARB :
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 :
2019-09-12 05:06:10 +02:00
TRACE ( " WGL_render_texture Attributes: %x as %x \n " , iWGLAttr [ cur - 1 ] , iWGLAttr [ cur ] ) ;
2006-09-11 21:28:32 +02:00
if ( NULL = = pbuf ) {
ERR ( " trying to use GLX_Pbuffer Attributes without Pbuffer (was %x) \n " , iWGLAttr [ cur ] ) ;
}
2012-06-25 07:42:10 +02:00
if ( ! use_render_texture_emulation ) {
2006-09-11 21:28:32 +02:00
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 {
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 :
2019-09-12 05:06:10 +02:00
nvfloatattrib = pop ;
2007-08-01 23:20:54 +02:00
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
/** 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 :
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 :
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 :
2019-09-12 05:06:10 +02:00
FIXME ( " unsupported %x WGL Attribute \n " , attr ) ;
2006-09-11 21:28:32 +02:00
break ;
}
+ + cur ;
}
2009-11-13 12:28:48 +01:00
/* By default glXChooseFBConfig defaults to GLX_WINDOW_BIT. wglChoosePixelFormatARB searches through
2012-03-27 20:35:49 +02:00
* all formats . Unless drawattrib is set to a non - zero value override it with GLX_DONT_CARE , so that
* pixmap and pbuffer formats appear as well . */
if ( ! drawattrib ) drawattrib = GLX_DONT_CARE ;
2007-08-01 23:20:54 +02:00
PUSH2 ( oGLXAttr , GLX_DRAWABLE_TYPE , drawattrib ) ;
TRACE ( " pAttr[?] = GLX_DRAWABLE_TYPE: %#x \n " , drawattrib ) ;
2009-11-11 16:27:43 +01:00
/* By default glXChooseFBConfig uses GLX_RGBA_BIT as the default value. Since wglChoosePixelFormatARB
2012-03-27 20:35:49 +02:00
* searches in all formats we have to do the same . For this reason we set GLX_RENDER_TYPE to
* GLX_DONT_CARE unless it is overridden . */
2007-08-01 23:20:54 +02:00
PUSH2 ( oGLXAttr , GLX_RENDER_TYPE , pixelattrib ) ;
TRACE ( " pAttr[?] = GLX_RENDER_TYPE: %#x \n " , pixelattrib ) ;
/* Set GLX_FLOAT_COMPONENTS_NV all the time */
2018-02-12 16:06:01 +01:00
if ( has_extension ( glxExtensions , " GLX_NV_float_buffer " ) ) {
2007-08-01 23:20:54 +02:00
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 )
{
2015-11-04 06:15:15 +01:00
int render_type , render_type_bit ;
2007-07-28 18:56:12 +02:00
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 :
2010-05-06 14:57:44 +02:00
ERR ( " Unknown render_type: %x \n " , render_type_bit ) ;
2015-11-04 06:15:15 +01:00
render_type = 0 ;
2007-07-28 18:56:12 +02:00
}
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 ) ;
}
2012-08-15 15:32:24 +02:00
static void init_pixel_formats ( Display * display )
2006-11-18 23:29:48 +01:00
{
2012-08-15 15:38:05 +02:00
struct wgl_pixel_format * list ;
2012-08-15 15:32:24 +02:00
int size = 0 , onscreen_size = 0 ;
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
cfgs = pglXGetFBConfigs ( display , DefaultScreen ( display ) , & nCfgs ) ;
if ( NULL = = cfgs | | 0 = = nCfgs ) {
if ( cfgs ! = NULL ) XFree ( cfgs ) ;
2008-05-28 16:57:46 +02:00
ERR ( " glXChooseFBConfig returns NULL \n " ) ;
2012-08-15 15:32:24 +02:00
return ;
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 ) ;
2012-08-15 15:38:05 +02:00
list = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , ( nCfgs + bmp_formats ) * sizeof ( * list ) ) ;
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 . */
2012-09-25 15:51:03 +02:00
if ( visinfo - > depth ! = default_visual . depth )
2009-10-21 10:34:01 +02:00
{
XFree ( visinfo ) ;
2008-02-22 21:40:00 +01:00
continue ;
2009-10-21 10:34:01 +02:00
}
2008-02-22 21:40:00 +01:00
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 ] . fbconfig = cfgs [ i ] ;
2018-02-09 09:42:53 +01:00
list [ size ] . visual = visinfo ;
2008-05-28 16:57:46 +02:00
list [ size ] . fmt_id = fmt_id ;
list [ size ] . render_type = get_render_type_from_fbconfig ( display , cfgs [ i ] ) ;
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 ] . fbconfig = cfgs [ i ] ;
2018-02-09 09:42:53 +01:00
list [ size ] . visual = visinfo ;
2009-05-14 17:05:20 +02:00
list [ size ] . fmt_id = fmt_id ;
list [ size ] . render_type = get_render_type_from_fbconfig ( display , cfgs [ i ] ) ;
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
} else if ( run & & ! visinfo ) {
2010-04-20 12:13:25 +02:00
int window_drawable = 0 ;
pglXGetFBConfigAttrib ( gdi_display , cfgs [ i ] , GLX_DRAWABLE_TYPE , & window_drawable ) ;
/* Recent Nvidia drivers and DRI drivers offer window drawable formats without a visual.
* This are formats like 16 - bit rgb on a 24 - bit desktop . In order to support these formats
* onscreen we would have to use glXCreateWindow instead of XCreateWindow . Further it will
* likely make our child window opengl rendering more complicated since likely you can ' t use
* XCopyArea on a GLX Window .
* For now ignore fbconfigs which are window drawable but lack a visual . */
if ( window_drawable & GLX_WINDOW_BIT )
{
TRACE ( " Skipping FBCONFIG_ID 0x%x as an offscreen format because it is window_drawable \n " , fmt_id ) ;
continue ;
}
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 ] . fbconfig = cfgs [ i ] ;
list [ size ] . fmt_id = fmt_id ;
list [ size ] . render_type = get_render_type_from_fbconfig ( display , cfgs [ i ] ) ;
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
}
2018-02-09 09:42:53 +01:00
else if ( visinfo ) XFree ( visinfo ) ;
2007-07-26 18:13:08 +02:00
}
}
2010-05-18 01:31:10 +02:00
XFree ( cfgs ) ;
2006-11-18 23:29:48 +01:00
2012-08-15 15:32:24 +02:00
pixel_formats = list ;
nb_pixel_formats = size ;
nb_onscreen_formats = onscreen_size ;
}
static inline BOOL is_valid_pixel_format ( int format )
{
return format > 0 & & format < = nb_pixel_formats ;
}
static inline BOOL is_onscreen_pixel_format ( int format )
{
return format > 0 & & format < = nb_onscreen_formats ;
2006-11-18 23:29:48 +01:00
}
2012-10-03 23:01:19 +02:00
static inline int pixel_format_index ( const struct wgl_pixel_format * format )
{
return format - pixel_formats + 1 ;
}
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 ) .
2012-08-15 15:32:24 +02:00
* This function converts a WGL format to its corresponding GLX one .
2006-08-27 23:10:32 +02:00
*/
2012-08-15 15:38:05 +02:00
static const struct wgl_pixel_format * get_pixel_format ( Display * display , int iPixelFormat , BOOL AllowOffscreen )
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 .
*/
2012-08-15 15:32:24 +02:00
if ( is_valid_pixel_format ( iPixelFormat ) & &
( is_onscreen_pixel_format ( iPixelFormat ) | | AllowOffscreen ) ) {
TRACE ( " Returning fmt_id=%#x for iPixelFormat=%d \n " ,
pixel_formats [ iPixelFormat - 1 ] . fmt_id , iPixelFormat ) ;
return & pixel_formats [ iPixelFormat - 1 ] ;
2006-11-18 23:29:48 +01:00
}
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
2018-02-12 15:34:28 +01:00
static struct gl_drawable * grab_gl_drawable ( struct gl_drawable * gl )
{
InterlockedIncrement ( & gl - > ref ) ;
return gl ;
}
static void release_gl_drawable ( struct gl_drawable * gl )
{
if ( ! gl ) return ;
if ( InterlockedDecrement ( & gl - > ref ) ) return ;
switch ( gl - > type )
{
2018-02-12 15:41:45 +01:00
case DC_GL_WINDOW :
2018-02-12 15:34:28 +01:00
case DC_GL_CHILD_WIN :
2018-02-12 15:41:45 +01:00
TRACE ( " destroying %lx drawable %lx \n " , gl - > window , gl - > drawable ) ;
2018-02-12 15:34:28 +01:00
pglXDestroyWindow ( gdi_display , gl - > drawable ) ;
XDestroyWindow ( gdi_display , gl - > window ) ;
break ;
case DC_GL_PIXMAP_WIN :
2018-02-12 15:41:45 +01:00
TRACE ( " destroying pixmap %lx drawable %lx \n " , gl - > pixmap , gl - > drawable ) ;
2018-02-12 15:34:28 +01:00
pglXDestroyPixmap ( gdi_display , gl - > drawable ) ;
XFreePixmap ( gdi_display , gl - > pixmap ) ;
break ;
default :
break ;
}
HeapFree ( GetProcessHeap ( ) , 0 , gl ) ;
}
2007-09-26 16:15:52 +02:00
/* Mark any allocated context using the glx drawable 'old' to use 'new' */
2018-02-12 15:34:28 +01:00
static void mark_drawable_dirty ( struct gl_drawable * old , struct gl_drawable * new )
2007-09-26 16:15:52 +02:00
{
2012-06-29 12:29:55 +02:00
struct wgl_context * ctx ;
2012-08-14 14:54:39 +02:00
2018-02-12 15:34:28 +01:00
EnterCriticalSection ( & context_section ) ;
2012-06-29 12:29:55 +02:00
LIST_FOR_EACH_ENTRY ( ctx , & context_list , struct wgl_context , entry )
2012-05-07 12:57:29 +02:00
{
2018-02-12 15:41:45 +01:00
if ( old = = ctx - > drawables [ 0 ] | | old = = ctx - > new_drawables [ 0 ] )
{
release_gl_drawable ( ctx - > new_drawables [ 0 ] ) ;
ctx - > new_drawables [ 0 ] = grab_gl_drawable ( new ) ;
2007-09-26 16:15:52 +02:00
}
2018-02-12 15:41:45 +01:00
if ( old = = ctx - > drawables [ 1 ] | | old = = ctx - > new_drawables [ 1 ] )
{
release_gl_drawable ( ctx - > new_drawables [ 1 ] ) ;
ctx - > new_drawables [ 1 ] = grab_gl_drawable ( new ) ;
2007-09-26 16:15:52 +02:00
}
}
2018-02-12 15:34:28 +01:00
LeaveCriticalSection ( & context_section ) ;
2007-09-26 16:15:52 +02:00
}
/* Given the current context, make sure its drawable is sync'd */
2012-06-29 12:29:55 +02:00
static inline void sync_context ( struct wgl_context * context )
2007-09-26 16:15:52 +02:00
{
2018-02-12 15:41:45 +01:00
BOOL refresh = FALSE ;
2018-02-12 15:34:28 +01:00
EnterCriticalSection ( & context_section ) ;
2018-02-12 15:41:45 +01:00
if ( context - > new_drawables [ 0 ] )
{
release_gl_drawable ( context - > drawables [ 0 ] ) ;
context - > drawables [ 0 ] = context - > new_drawables [ 0 ] ;
context - > new_drawables [ 0 ] = NULL ;
refresh = TRUE ;
}
if ( context - > new_drawables [ 1 ] )
{
release_gl_drawable ( context - > drawables [ 1 ] ) ;
context - > drawables [ 1 ] = context - > new_drawables [ 1 ] ;
context - > new_drawables [ 1 ] = NULL ;
refresh = TRUE ;
}
if ( refresh )
{
2007-09-26 16:15:52 +02:00
if ( glxRequireVersion ( 3 ) )
2018-02-12 15:41:45 +01:00
pglXMakeContextCurrent ( gdi_display , context - > drawables [ 0 ] - > drawable ,
context - > drawables [ 1 ] - > drawable , context - > ctx ) ;
2007-09-26 16:15:52 +02:00
else
2018-02-12 15:41:45 +01:00
pglXMakeCurrent ( gdi_display , context - > drawables [ 0 ] - > drawable , context - > ctx ) ;
2007-09-26 16:15:52 +02:00
}
2018-02-12 15:34:28 +01:00
LeaveCriticalSection ( & context_section ) ;
2007-09-26 16:15:52 +02:00
}
2016-05-26 23:43:14 +02:00
static BOOL set_swap_interval ( GLXDrawable drawable , int interval )
2014-04-01 04:46:48 +02:00
{
BOOL ret = TRUE ;
switch ( swap_control_method )
{
case GLX_SWAP_CONTROL_EXT :
X11DRV_expect_error ( gdi_display , GLXErrorHandler , NULL ) ;
pglXSwapIntervalEXT ( gdi_display , drawable , interval ) ;
XSync ( gdi_display , False ) ;
ret = ! X11DRV_check_error ( ) ;
break ;
case GLX_SWAP_CONTROL_MESA :
ret = ! pglXSwapIntervalMESA ( interval ) ;
break ;
case GLX_SWAP_CONTROL_SGI :
/* wglSwapIntervalEXT considers an interval value of zero to mean that
* vsync should be disabled , but glXSwapIntervalSGI considers such a
* value to be an error . Just silently ignore the request for now .
*/
if ( ! interval )
WARN ( " Request to disable vertical sync is not handled \n " ) ;
else
ret = ! pglXSwapIntervalSGI ( interval ) ;
break ;
case GLX_SWAP_CONTROL_NONE :
/* Unlikely to happen on modern GLX implementations */
WARN ( " Request to adjust swap interval is not handled \n " ) ;
break ;
}
return ret ;
}
2012-09-07 22:04:33 +02:00
static struct gl_drawable * get_gl_drawable ( HWND hwnd , HDC hdc )
{
struct gl_drawable * gl ;
EnterCriticalSection ( & context_section ) ;
2018-02-12 15:34:28 +01:00
if ( hwnd & & ! XFindContext ( gdi_display , ( XID ) hwnd , gl_hwnd_context , ( char * * ) & gl ) )
gl = grab_gl_drawable ( gl ) ;
else if ( hdc & & ! XFindContext ( gdi_display , ( XID ) hdc , gl_pbuffer_context , ( char * * ) & gl ) )
gl = grab_gl_drawable ( gl ) ;
else
gl = NULL ;
2012-09-07 22:04:33 +02:00
LeaveCriticalSection ( & context_section ) ;
2018-02-12 15:34:28 +01:00
return gl ;
2012-09-07 22:04:33 +02:00
}
2007-09-26 16:15:52 +02:00
2012-06-29 12:29:55 +02:00
static GLXContext create_glxcontext ( Display * display , struct wgl_context * context , GLXContext shareList )
2008-10-25 23:36:32 +02:00
{
GLXContext ctx ;
2009-05-14 17:05:20 +02:00
2009-11-16 23:24:24 +01:00
if ( context - > gl3_context )
{
if ( context - > numAttribs )
2015-11-18 07:36:41 +01:00
ctx = pglXCreateContextAttribsARB ( gdi_display , context - > fmt - > fbconfig , shareList , GL_TRUE , context - > attribList ) ;
2009-11-16 23:24:24 +01:00
else
2015-11-18 07:36:41 +01:00
ctx = pglXCreateContextAttribsARB ( gdi_display , context - > fmt - > fbconfig , shareList , GL_TRUE , NULL ) ;
2009-11-16 23:24:24 +01:00
}
2018-02-09 09:42:53 +01:00
else if ( context - > fmt - > visual )
ctx = pglXCreateContext ( gdi_display , context - > fmt - > visual , shareList , GL_TRUE ) ;
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 ;
}
2012-08-31 12:22:03 +02:00
/***********************************************************************
2012-10-10 10:46:16 +02:00
* create_gl_drawable
2012-08-31 12:22:03 +02:00
*/
2021-04-20 19:43:50 +02:00
static struct gl_drawable * create_gl_drawable ( HWND hwnd , const struct wgl_pixel_format * format , BOOL known_child ,
BOOL mutable_pf )
2012-08-31 12:22:03 +02:00
{
2018-02-12 15:34:28 +01:00
struct gl_drawable * gl , * prev ;
XVisualInfo * visual = format - > visual ;
2018-02-09 13:08:04 +01:00
RECT rect ;
int width , height ;
GetClientRect ( hwnd , & rect ) ;
width = min ( max ( 1 , rect . right ) , 65535 ) ;
height = min ( max ( 1 , rect . bottom ) , 65535 ) ;
2018-02-09 09:42:53 +01:00
2018-02-12 15:34:28 +01:00
if ( ! ( gl = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , sizeof ( * gl ) ) ) ) return NULL ;
/* Default GLX and WGL swap interval is 1, but in case of glXSwapIntervalSGI
* there is no way to query it , so we have to store it here .
*/
gl - > swap_interval = 1 ;
gl - > refresh_swap_interval = TRUE ;
gl - > format = format ;
gl - > ref = 1 ;
2021-04-20 19:43:50 +02:00
gl - > mutable_pf = mutable_pf ;
2012-08-31 12:22:03 +02:00
2019-04-10 21:04:18 +02:00
if ( ! known_child & & ! GetWindow ( hwnd , GW_CHILD ) & & GetAncestor ( hwnd , GA_PARENT ) = = GetDesktopWindow ( ) ) /* childless top-level window */
2012-08-31 12:22:03 +02:00
{
2018-02-12 15:49:23 +01:00
gl - > type = DC_GL_WINDOW ;
gl - > window = create_client_window ( hwnd , visual ) ;
if ( gl - > window )
gl - > drawable = pglXCreateWindow ( gdi_display , gl - > format - > fbconfig , gl - > window , NULL ) ;
TRACE ( " %p created client %lx drawable %lx \n " , hwnd , gl - > window , gl - > drawable ) ;
2012-08-31 12:22:03 +02:00
}
# ifdef SONAME_LIBXCOMPOSITE
else if ( usexcomposite )
{
gl - > type = DC_GL_CHILD_WIN ;
2018-02-12 15:49:23 +01:00
gl - > window = create_client_window ( hwnd , visual ) ;
2016-05-26 23:43:14 +02:00
if ( gl - > window )
2012-08-31 12:22:03 +02:00
{
2016-05-26 23:43:14 +02:00
gl - > drawable = pglXCreateWindow ( gdi_display , gl - > format - > fbconfig , gl - > window , NULL ) ;
2018-02-12 15:49:23 +01:00
pXCompositeRedirectWindow ( gdi_display , gl - > window , CompositeRedirectManual ) ;
2012-08-31 12:22:03 +02:00
}
2018-02-12 15:41:45 +01:00
TRACE ( " %p created child %lx drawable %lx \n " , hwnd , gl - > window , gl - > drawable ) ;
2012-08-31 12:22:03 +02:00
}
# endif
else
{
WARN ( " XComposite is not available, using GLXPixmap hack \n " ) ;
gl - > type = DC_GL_PIXMAP_WIN ;
2018-02-09 13:08:04 +01:00
gl - > pixmap = XCreatePixmap ( gdi_display , root_window , width , height , visual - > depth ) ;
2012-08-31 12:22:03 +02:00
if ( gl - > pixmap )
{
2016-05-26 23:43:13 +02:00
gl - > drawable = pglXCreatePixmap ( gdi_display , gl - > format - > fbconfig , gl - > pixmap , NULL ) ;
2012-08-31 12:22:03 +02:00
if ( ! gl - > drawable ) XFreePixmap ( gdi_display , gl - > pixmap ) ;
2018-02-09 13:08:04 +01:00
gl - > pixmap_size . cx = width ;
gl - > pixmap_size . cy = height ;
2012-08-31 12:22:03 +02:00
}
}
2018-02-12 15:34:28 +01:00
if ( ! gl - > drawable )
{
HeapFree ( GetProcessHeap ( ) , 0 , gl ) ;
return NULL ;
}
EnterCriticalSection ( & context_section ) ;
if ( ! XFindContext ( gdi_display , ( XID ) hwnd , gl_hwnd_context , ( char * * ) & prev ) )
{
gl - > swap_interval = prev - > swap_interval ;
release_gl_drawable ( prev ) ;
}
XSaveContext ( gdi_display , ( XID ) hwnd , gl_hwnd_context , ( char * ) grab_gl_drawable ( gl ) ) ;
LeaveCriticalSection ( & context_section ) ;
return gl ;
2012-10-10 10:46:16 +02:00
}
/***********************************************************************
* set_win_format
*/
2021-04-20 19:43:50 +02:00
static BOOL set_win_format ( HWND hwnd , const struct wgl_pixel_format * format , BOOL mutable_pf )
2012-10-10 10:46:16 +02:00
{
2018-02-12 15:34:28 +01:00
struct gl_drawable * gl ;
2012-10-10 10:46:16 +02:00
2018-02-09 09:42:53 +01:00
if ( ! format - > visual ) return FALSE ;
2021-04-20 19:43:50 +02:00
if ( ! ( gl = create_gl_drawable ( hwnd , format , FALSE , mutable_pf ) ) ) return FALSE ;
2012-08-31 12:22:03 +02:00
2015-11-18 15:05:20 +01:00
TRACE ( " created GL drawable %lx for win %p %s \n " ,
gl - > drawable , hwnd , debugstr_fbconfig ( format - > fbconfig ) ) ;
2012-08-31 12:22:03 +02:00
XFlush ( gdi_display ) ;
2018-02-12 15:34:28 +01:00
release_gl_drawable ( gl ) ;
2012-10-03 23:01:43 +02:00
__wine_set_pixel_format ( hwnd , pixel_format_index ( format ) ) ;
2012-08-31 12:22:03 +02:00
return TRUE ;
}
2014-05-06 10:44:01 +02:00
static BOOL set_pixel_format ( HDC hdc , int format , BOOL allow_change )
{
const struct wgl_pixel_format * fmt ;
int value ;
HWND hwnd = WindowFromDC ( hdc ) ;
TRACE ( " (%p,%d) \n " , hdc , format ) ;
if ( ! hwnd | | hwnd = = GetDesktopWindow ( ) )
{
WARN ( " not a valid window DC %p/%p \n " , hdc , hwnd ) ;
return FALSE ;
}
fmt = get_pixel_format ( gdi_display , format , FALSE /* Offscreen */ ) ;
if ( ! fmt )
{
ERR ( " Invalid format %d \n " , format ) ;
return FALSE ;
}
pglXGetFBConfigAttrib ( gdi_display , fmt - > fbconfig , GLX_DRAWABLE_TYPE , & value ) ;
if ( ! ( value & GLX_WINDOW_BIT ) )
{
WARN ( " Pixel format %d is not compatible for window rendering \n " , format ) ;
return FALSE ;
}
if ( ! allow_change )
{
struct gl_drawable * gl ;
if ( ( gl = get_gl_drawable ( hwnd , hdc ) ) )
{
int prev = pixel_format_index ( gl - > format ) ;
2021-04-20 19:43:50 +02:00
BOOL mutable_pf = gl - > mutable_pf ;
2014-05-06 10:44:01 +02:00
release_gl_drawable ( gl ) ;
2021-04-20 19:43:50 +02:00
if ( ! mutable_pf )
return prev = = format ; /* cannot change it if already set */
2014-05-06 10:44:01 +02:00
}
}
2021-04-20 19:43:50 +02:00
return set_win_format ( hwnd , fmt , allow_change ) ;
2014-05-06 10:44:01 +02:00
}
2012-08-31 12:22:03 +02:00
/***********************************************************************
* sync_gl_drawable
*/
2019-04-10 21:04:18 +02:00
void sync_gl_drawable ( HWND hwnd , BOOL known_child )
2012-08-31 12:22:03 +02:00
{
2018-02-12 15:34:28 +01:00
struct gl_drawable * old , * new ;
2012-09-04 15:03:04 +02:00
2018-02-12 15:34:28 +01:00
if ( ! ( old = get_gl_drawable ( hwnd , 0 ) ) ) return ;
2012-08-31 12:22:03 +02:00
2018-02-12 15:34:28 +01:00
switch ( old - > type )
2012-08-31 12:22:03 +02:00
{
2019-04-10 21:04:18 +02:00
case DC_GL_WINDOW :
if ( ! known_child ) break ; /* Still a childless top-level window */
/* fall through */
2012-08-31 12:22:03 +02:00
case DC_GL_PIXMAP_WIN :
2021-04-20 19:43:50 +02:00
if ( ! ( new = create_gl_drawable ( hwnd , old - > format , known_child , old - > mutable_pf ) ) ) break ;
2018-02-12 15:34:28 +01:00
mark_drawable_dirty ( old , new ) ;
2012-08-31 12:22:03 +02:00
XFlush ( gdi_display ) ;
2018-02-12 15:34:28 +01:00
TRACE ( " Recreated GL drawable %lx to replace %lx \n " , new - > drawable , old - > drawable ) ;
release_gl_drawable ( new ) ;
2012-08-31 12:22:03 +02:00
break ;
default :
break ;
}
2018-02-12 15:34:28 +01:00
release_gl_drawable ( old ) ;
2012-08-31 12:22:03 +02:00
}
2012-10-10 10:46:16 +02:00
/***********************************************************************
* set_gl_drawable_parent
*/
void set_gl_drawable_parent ( HWND hwnd , HWND parent )
{
2018-02-12 15:34:28 +01:00
struct gl_drawable * old , * new ;
2012-10-10 10:46:16 +02:00
2018-02-12 15:34:28 +01:00
if ( ! ( old = get_gl_drawable ( hwnd , 0 ) ) ) return ;
2012-10-10 10:46:16 +02:00
2018-02-12 15:34:28 +01:00
TRACE ( " setting drawable %lx parent %p \n " , old - > drawable , parent ) ;
2012-10-10 10:46:16 +02:00
2018-02-12 15:34:28 +01:00
switch ( old - > type )
2012-10-10 10:46:16 +02:00
{
case DC_GL_WINDOW :
break ;
case DC_GL_CHILD_WIN :
case DC_GL_PIXMAP_WIN :
2018-02-12 15:34:28 +01:00
if ( parent = = GetDesktopWindow ( ) ) break ;
/* fall through */
2012-10-10 10:46:16 +02:00
default :
2018-02-12 15:34:28 +01:00
release_gl_drawable ( old ) ;
return ;
2012-10-10 10:46:16 +02:00
}
2021-04-20 19:43:50 +02:00
if ( ( new = create_gl_drawable ( hwnd , old - > format , FALSE , old - > mutable_pf ) ) )
2012-10-10 10:46:16 +02:00
{
2018-02-12 15:34:28 +01:00
mark_drawable_dirty ( old , new ) ;
release_gl_drawable ( new ) ;
}
else
{
destroy_gl_drawable ( hwnd ) ;
2012-10-10 10:46:16 +02:00
__wine_set_pixel_format ( hwnd , 0 ) ;
}
2018-02-12 15:34:28 +01:00
release_gl_drawable ( old ) ;
2012-10-10 10:46:16 +02:00
}
2012-08-31 12:22:03 +02:00
/***********************************************************************
* destroy_gl_drawable
*/
void destroy_gl_drawable ( HWND hwnd )
{
struct gl_drawable * gl ;
EnterCriticalSection ( & context_section ) ;
2012-09-07 15:23:15 +02:00
if ( ! XFindContext ( gdi_display , ( XID ) hwnd , gl_hwnd_context , ( char * * ) & gl ) )
2012-08-31 12:22:03 +02:00
{
2012-09-07 15:23:15 +02:00
XDeleteContext ( gdi_display , ( XID ) hwnd , gl_hwnd_context ) ;
2018-02-12 15:34:28 +01:00
release_gl_drawable ( gl ) ;
2012-08-31 12:22:03 +02:00
}
LeaveCriticalSection ( & context_section ) ;
2007-09-26 17:17:13 +02:00
}
2005-05-06 16:33:02 +02:00
/**
2012-05-08 12:18:54 +02:00
* glxdrv_DescribePixelFormat
2005-05-06 16:33:02 +02:00
*
* Get the pixel - format descriptor associated to the given id
*/
2021-02-24 15:04:52 +01:00
static int WINAPI describe_pixel_format ( int iPixelFormat , PIXELFORMATDESCRIPTOR * ppfd , BOOL allow_offscreen )
2011-07-08 15:55:11 +02:00
{
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 ;
2012-08-15 15:38:05 +02:00
const struct wgl_pixel_format * fmt ;
2005-04-28 20:29:12 +02:00
2008-06-23 22:56:10 +02:00
if ( ! has_opengl ( ) ) return 0 ;
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 */
2021-02-24 15:04:52 +01:00
fmt = get_pixel_format ( gdi_display , iPixelFormat , allow_offscreen ) ;
2012-08-15 15:32:24 +02:00
if ( ! fmt ) {
WARN ( " unexpected format %d \n " , iPixelFormat ) ;
2006-12-10 19:17:03 +01:00
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
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
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
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
2012-08-15 15:32:24 +02:00
return nb_onscreen_formats ;
2000-05-12 22:18:14 +02:00
}
2021-02-24 15:04:52 +01:00
/**
* glxdrv_DescribePixelFormat
*
* Get the pixel - format descriptor associated to the given id
*/
static int WINAPI glxdrv_wglDescribePixelFormat ( HDC hdc , int iPixelFormat ,
UINT nBytes , PIXELFORMATDESCRIPTOR * ppfd )
{
TRACE ( " (%p,%d,%d,%p) \n " , hdc , iPixelFormat , nBytes , ppfd ) ;
if ( ! ppfd ) return nb_onscreen_formats ;
if ( nBytes < sizeof ( PIXELFORMATDESCRIPTOR ) )
{
ERR ( " Wrong structure size ! \n " ) ;
/* Should set error */
return 0 ;
}
return describe_pixel_format ( iPixelFormat , ppfd , FALSE ) ;
}
2012-06-28 15:51:44 +02:00
/***********************************************************************
2012-07-18 23:58:41 +02:00
* glxdrv_wglGetPixelFormat
2005-05-06 16:33:02 +02:00
*/
2020-04-23 13:33:20 +02:00
static int WINAPI glxdrv_wglGetPixelFormat ( HDC hdc )
2011-07-08 15:55:11 +02:00
{
2012-09-07 15:31:05 +02:00
struct gl_drawable * gl ;
int ret = 0 ;
2008-05-12 19:58:35 +02:00
2012-09-07 22:04:33 +02:00
if ( ( gl = get_gl_drawable ( WindowFromDC ( hdc ) , hdc ) ) )
{
2012-10-03 23:01:19 +02:00
ret = pixel_format_index ( gl - > format ) ;
2012-09-07 22:04:33 +02:00
/* Offscreen formats can't be used with traditional WGL calls.
* As has been verified on Windows GetPixelFormat doesn ' t fail but returns iPixelFormat = 1. */
if ( ! is_onscreen_pixel_format ( ret ) ) ret = 1 ;
release_gl_drawable ( gl ) ;
}
2012-09-07 15:31:05 +02:00
TRACE ( " %p -> %d \n " , hdc , ret ) ;
return ret ;
2000-05-12 22:18:14 +02:00
}
2012-06-28 15:51:44 +02:00
/***********************************************************************
2012-07-30 21:53:37 +02:00
* glxdrv_wglSetPixelFormat
2012-06-28 12:00:45 +02:00
*/
2020-04-23 13:33:20 +02:00
static BOOL WINAPI glxdrv_wglSetPixelFormat ( HDC hdc , int iPixelFormat , const PIXELFORMATDESCRIPTOR * ppfd )
2012-05-08 14:03:56 +02:00
{
2014-05-06 10:44:01 +02:00
return set_pixel_format ( hdc , iPixelFormat , FALSE ) ;
2008-04-23 22:40:43 +02:00
}
2012-06-28 14:13:24 +02:00
/***********************************************************************
* glxdrv_wglCopyContext
2007-11-11 21:32:12 +01:00
*/
2020-04-23 13:33:20 +02:00
static BOOL WINAPI glxdrv_wglCopyContext ( struct wgl_context * src , struct wgl_context * dst , UINT mask )
2011-07-13 14:56:12 +02:00
{
2012-06-29 12:29:55 +02:00
TRACE ( " %p -> %p mask %#x \n " , src , dst , mask ) ;
2007-11-11 21:32:12 +01:00
pglXCopyContext ( gdi_display , src - > ctx , dst - > ctx , mask ) ;
/* As opposed to wglCopyContext, glXCopyContext doesn't return anything, so hopefully we passed */
return TRUE ;
}
2012-06-28 15:47:31 +02:00
/***********************************************************************
* glxdrv_wglCreateContext
2006-11-12 20:23:38 +01:00
*/
2020-04-23 13:33:20 +02:00
static struct wgl_context * WINAPI glxdrv_wglCreateContext ( HDC hdc )
2006-08-29 16:56:57 +02:00
{
2015-11-04 06:15:15 +01:00
struct wgl_context * ret ;
2012-09-07 15:43:01 +02:00
struct gl_drawable * gl ;
2006-08-29 16:56:57 +02:00
2012-09-07 22:04:33 +02:00
if ( ! ( gl = get_gl_drawable ( WindowFromDC ( hdc ) , hdc ) ) )
{
SetLastError ( ERROR_INVALID_PIXEL_FORMAT ) ;
return NULL ;
}
2006-11-02 22:23:42 +01:00
2012-09-07 22:04:33 +02:00
if ( ( ret = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , sizeof ( * ret ) ) ) )
2012-09-07 15:43:01 +02:00
{
ret - > hdc = hdc ;
ret - > fmt = gl - > format ;
ret - > ctx = create_glxcontext ( gdi_display , ret , NULL ) ;
2018-02-12 15:34:28 +01:00
EnterCriticalSection ( & context_section ) ;
2012-09-07 15:43:01 +02:00
list_add_head ( & context_list , & ret - > entry ) ;
2018-02-12 15:34:28 +01:00
LeaveCriticalSection ( & context_section ) ;
2006-08-29 16:56:57 +02:00
}
2012-09-07 22:04:33 +02:00
release_gl_drawable ( gl ) ;
2012-09-07 15:43:01 +02:00
TRACE ( " %p -> %p \n " , hdc , ret ) ;
2012-06-29 12:29:55 +02:00
return ret ;
2006-08-29 16:56:57 +02:00
}
2012-06-28 14:13:24 +02:00
/***********************************************************************
* glxdrv_wglDeleteContext
2006-11-12 20:23:38 +01:00
*/
2020-04-23 13:33:20 +02:00
static BOOL WINAPI glxdrv_wglDeleteContext ( struct wgl_context * ctx )
2006-08-29 16:56:57 +02:00
{
2016-03-15 18:58:26 +01:00
struct wgl_pbuffer * pb ;
2012-06-29 12:29:55 +02:00
TRACE ( " (%p) \n " , ctx ) ;
2006-08-29 16:56:57 +02:00
2012-08-14 14:54:39 +02:00
EnterCriticalSection ( & context_section ) ;
2012-05-07 12:57:29 +02:00
list_remove ( & ctx - > entry ) ;
2016-03-15 18:58:26 +01:00
LIST_FOR_EACH_ENTRY ( pb , & pbuffer_list , struct wgl_pbuffer , entry )
{
if ( pb - > prev_context = = ctx - > ctx ) {
pglXDestroyContext ( gdi_display , pb - > tmp_context ) ;
pb - > prev_context = pb - > tmp_context = NULL ;
}
}
2012-08-14 14:54:39 +02:00
LeaveCriticalSection ( & context_section ) ;
2012-05-07 12:57:29 +02:00
if ( ctx - > ctx ) pglXDestroyContext ( gdi_display , ctx - > ctx ) ;
2018-02-12 15:41:45 +01:00
release_gl_drawable ( ctx - > drawables [ 0 ] ) ;
release_gl_drawable ( ctx - > drawables [ 1 ] ) ;
release_gl_drawable ( ctx - > new_drawables [ 0 ] ) ;
release_gl_drawable ( ctx - > new_drawables [ 1 ] ) ;
2017-10-10 10:06:10 +02:00
return HeapFree ( GetProcessHeap ( ) , 0 , ctx ) ;
2006-08-29 16:56:57 +02:00
}
2012-06-28 16:14:55 +02:00
/***********************************************************************
* glxdrv_wglGetProcAddress
2006-11-12 20:23:38 +01:00
*/
2020-04-23 13:33:20 +02:00
static PROC WINAPI glxdrv_wglGetProcAddress ( LPCSTR lpszProc )
2006-09-11 21:28:32 +02:00
{
2012-07-17 00:00:55 +02:00
if ( ! strncmp ( lpszProc , " wgl " , 3 ) ) return NULL ;
return pglXGetProcAddressARB ( ( const GLubyte * ) lpszProc ) ;
2006-09-11 21:28:32 +02:00
}
2018-02-12 15:41:45 +01:00
static void set_context_drawables ( struct wgl_context * ctx , struct gl_drawable * draw ,
struct gl_drawable * read )
{
struct gl_drawable * prev [ 4 ] ;
int i ;
prev [ 0 ] = ctx - > drawables [ 0 ] ;
prev [ 1 ] = ctx - > drawables [ 1 ] ;
prev [ 2 ] = ctx - > new_drawables [ 0 ] ;
prev [ 3 ] = ctx - > new_drawables [ 1 ] ;
ctx - > drawables [ 0 ] = grab_gl_drawable ( draw ) ;
ctx - > drawables [ 1 ] = read ? grab_gl_drawable ( read ) : NULL ;
ctx - > new_drawables [ 0 ] = ctx - > new_drawables [ 1 ] = NULL ;
for ( i = 0 ; i < 4 ; i + + ) release_gl_drawable ( prev [ i ] ) ;
}
2012-06-28 14:13:24 +02:00
/***********************************************************************
* glxdrv_wglMakeCurrent
2006-11-12 20:23:38 +01:00
*/
2020-04-23 13:33:20 +02:00
static BOOL WINAPI glxdrv_wglMakeCurrent ( HDC hdc , struct wgl_context * ctx )
2011-07-08 15:55:11 +02:00
{
2012-09-07 15:53:00 +02:00
BOOL ret = FALSE ;
struct gl_drawable * gl ;
2006-08-29 16:58:49 +02:00
2012-06-29 12:29:55 +02:00
TRACE ( " (%p,%p) \n " , hdc , ctx ) ;
2006-11-02 22:23:42 +01:00
2012-06-29 12:29:55 +02:00
if ( ! ctx )
2010-04-26 15:49:56 +02:00
{
2012-08-14 13:38:03 +02:00
pglXMakeCurrent ( gdi_display , None , NULL ) ;
2006-08-29 16:58:49 +02:00
NtCurrentTeb ( ) - > glContext = NULL ;
2012-06-27 13:58:23 +02:00
return TRUE ;
2010-04-26 15:49:56 +02:00
}
2012-06-27 13:58:23 +02:00
2012-09-07 22:04:33 +02:00
if ( ( gl = get_gl_drawable ( WindowFromDC ( hdc ) , hdc ) ) )
2010-04-26 15:49:56 +02:00
{
2012-09-07 15:53:00 +02:00
if ( ctx - > fmt ! = gl - > format )
{
WARN ( " mismatched pixel format hdc %p %p ctx %p %p \n " , hdc , gl - > format , ctx , ctx - > fmt ) ;
SetLastError ( ERROR_INVALID_PIXEL_FORMAT ) ;
goto done ;
}
2015-11-18 15:05:20 +01:00
TRACE ( " hdc %p drawable %lx fmt %p ctx %p %s \n " , hdc , gl - > drawable , gl - > format , ctx - > ctx ,
debugstr_fbconfig ( gl - > format - > fbconfig ) ) ;
2009-11-15 12:09:08 +01:00
2018-02-12 15:34:28 +01:00
EnterCriticalSection ( & context_section ) ;
2012-09-07 15:53:00 +02:00
ret = pglXMakeCurrent ( gdi_display , gl - > drawable , ctx - > ctx ) ;
2011-03-03 21:06:33 +01:00
if ( ret )
2006-08-29 16:58:49 +02:00
{
2011-03-03 21:06:33 +01:00
NtCurrentTeb ( ) - > glContext = ctx ;
2009-11-15 12:09:08 +01:00
ctx - > has_been_current = TRUE ;
2012-06-27 13:58:23 +02:00
ctx - > hdc = hdc ;
2018-02-12 15:41:45 +01:00
set_context_drawables ( ctx , gl , gl ) ;
2007-09-26 16:15:52 +02:00
ctx - > refresh_drawables = FALSE ;
2018-02-12 15:34:28 +01:00
LeaveCriticalSection ( & context_section ) ;
2012-09-07 15:53:00 +02:00
goto done ;
2006-08-29 16:58:49 +02:00
}
2018-02-12 15:34:28 +01:00
LeaveCriticalSection ( & context_section ) ;
2006-08-29 16:58:49 +02:00
}
2012-09-07 15:53:00 +02:00
SetLastError ( ERROR_INVALID_HANDLE ) ;
done :
2012-09-07 22:04:33 +02:00
release_gl_drawable ( gl ) ;
2012-09-07 15:53:00 +02:00
TRACE ( " %p,%p returning %d \n " , hdc , ctx , ret ) ;
2006-08-29 16:58:49 +02:00
return ret ;
}
2012-06-28 14:49:49 +02:00
/***********************************************************************
2012-07-17 00:00:55 +02:00
* X11DRV_wglMakeContextCurrentARB
2006-11-12 20:23:38 +01:00
*/
2012-07-17 00:00:55 +02:00
static BOOL X11DRV_wglMakeContextCurrentARB ( HDC draw_hdc , HDC read_hdc , struct wgl_context * ctx )
2006-08-29 16:58:49 +02:00
{
2012-09-07 16:09:22 +02:00
BOOL ret = FALSE ;
2012-09-07 22:04:33 +02:00
struct gl_drawable * draw_gl , * read_gl = NULL ;
2007-09-27 18:02:26 +02:00
2012-06-29 12:29:55 +02:00
TRACE ( " (%p,%p,%p) \n " , draw_hdc , read_hdc , ctx ) ;
2006-11-02 22:23:42 +01:00
2012-06-29 12:29:55 +02:00
if ( ! ctx )
2010-04-26 15:49:56 +02:00
{
2012-08-14 13:38:03 +02:00
pglXMakeCurrent ( gdi_display , None , NULL ) ;
2006-10-14 12:56:07 +02:00
NtCurrentTeb ( ) - > glContext = NULL ;
2012-06-29 12:29:55 +02:00
return TRUE ;
2010-04-26 15:49:56 +02:00
}
2012-06-27 14:07:06 +02:00
2012-09-07 16:09:22 +02:00
if ( ! pglXMakeContextCurrent ) return FALSE ;
2012-06-27 14:07:06 +02:00
2012-09-07 22:04:33 +02:00
if ( ( draw_gl = get_gl_drawable ( WindowFromDC ( draw_hdc ) , draw_hdc ) ) )
2010-04-26 15:49:56 +02:00
{
2012-09-07 22:04:33 +02:00
read_gl = get_gl_drawable ( WindowFromDC ( read_hdc ) , read_hdc ) ;
2018-02-12 15:34:28 +01:00
EnterCriticalSection ( & context_section ) ;
2012-09-07 16:09:22 +02:00
ret = pglXMakeContextCurrent ( gdi_display , draw_gl - > drawable ,
read_gl ? read_gl - > drawable : 0 , ctx - > ctx ) ;
2012-05-09 17:06:50 +02:00
if ( ret )
{
ctx - > has_been_current = TRUE ;
2012-06-27 14:07:06 +02:00
ctx - > hdc = draw_hdc ;
2018-02-12 15:41:45 +01:00
set_context_drawables ( ctx , draw_gl , read_gl ) ;
2012-05-09 17:06:50 +02:00
ctx - > refresh_drawables = FALSE ;
NtCurrentTeb ( ) - > glContext = ctx ;
2018-02-12 15:34:28 +01:00
LeaveCriticalSection ( & context_section ) ;
2012-09-07 16:09:22 +02:00
goto done ;
2006-08-29 16:58:49 +02:00
}
2018-02-12 15:34:28 +01:00
LeaveCriticalSection ( & context_section ) ;
2006-08-29 16:58:49 +02:00
}
2012-09-07 16:09:22 +02:00
SetLastError ( ERROR_INVALID_HANDLE ) ;
done :
2012-09-07 22:04:33 +02:00
release_gl_drawable ( read_gl ) ;
release_gl_drawable ( draw_gl ) ;
2012-09-07 16:09:22 +02:00
TRACE ( " %p,%p,%p returning %d \n " , draw_hdc , read_hdc , ctx , ret ) ;
2006-08-29 16:58:49 +02:00
return ret ;
}
2012-06-28 14:13:24 +02:00
/***********************************************************************
* glxdrv_wglShareLists
2006-11-12 20:23:38 +01:00
*/
2020-04-23 13:33:20 +02:00
static BOOL WINAPI glxdrv_wglShareLists ( struct wgl_context * org , struct wgl_context * dest )
2011-07-13 14:56:12 +02:00
{
2006-08-29 16:58:49 +02:00
TRACE ( " (%p, %p) \n " , org , dest ) ;
2009-11-15 12:09:08 +01:00
/* Sharing of display lists works differently in GLX and WGL. In case of GLX it is done
* at context creation time but in case of WGL it is done using wglShareLists .
* In the past we tried to emulate wglShareLists by delaying GLX context creation until
* either a wglMakeCurrent or wglShareLists . This worked fine for most apps but it causes
* issues for OpenGL 3 because there wglCreateContextAttribsARB can fail in a lot of cases ,
* so there delaying context creation doesn ' t work .
*
* The new approach is to create a GLX context in wglCreateContext / wglCreateContextAttribsARB
* and when a program requests sharing we recreate the destination context if it hasn ' t been made
* current or when it hasn ' t shared display lists before .
*/
if ( ( org - > has_been_current & & dest - > has_been_current ) | | dest - > has_been_current )
{
ERR ( " Could not share display lists, one of the contexts has been current already ! \n " ) ;
2006-08-29 16:58:49 +02:00
return FALSE ;
2009-11-15 12:09:08 +01:00
}
else if ( dest - > sharing )
{
ERR ( " Could not share display lists because hglrc2 has already shared lists before \n " ) ;
return FALSE ;
}
else
{
/* Re-create the GLX context and share display lists */
pglXDestroyContext ( gdi_display , dest - > ctx ) ;
dest - > ctx = create_glxcontext ( gdi_display , dest , org - > ctx ) ;
2015-11-18 15:05:20 +01:00
TRACE ( " re-created context (%p) for Wine context %p (%s) sharing lists with ctx %p (%s) \n " ,
dest - > ctx , dest , debugstr_fbconfig ( dest - > fmt - > fbconfig ) ,
org - > ctx , debugstr_fbconfig ( org - > fmt - > fbconfig ) ) ;
2009-11-15 12:09:08 +01:00
org - > sharing = TRUE ;
dest - > sharing = TRUE ;
return TRUE ;
2006-08-29 16:58:49 +02:00
}
return FALSE ;
}
2012-07-16 23:56:55 +02:00
static void wglFinish ( void )
2007-09-23 05:45:27 +02:00
{
2012-10-02 21:50:54 +02:00
struct x11drv_escape_flush_gl_drawable escape ;
struct gl_drawable * gl ;
2012-06-29 12:29:55 +02:00
struct wgl_context * ctx = NtCurrentTeb ( ) - > glContext ;
2007-09-26 16:15:52 +02:00
2012-10-02 21:50:54 +02:00
escape . code = X11DRV_FLUSH_GL_DRAWABLE ;
escape . gl_drawable = 0 ;
2018-03-16 11:08:28 +01:00
escape . flush = FALSE ;
2012-10-02 21:50:54 +02:00
if ( ( gl = get_gl_drawable ( WindowFromDC ( ctx - > hdc ) , 0 ) ) )
{
switch ( gl - > type )
{
case DC_GL_PIXMAP_WIN : escape . gl_drawable = gl - > pixmap ; break ;
2016-05-26 23:43:14 +02:00
case DC_GL_CHILD_WIN : escape . gl_drawable = gl - > window ; break ;
2012-10-02 21:50:54 +02:00
default : break ;
}
sync_context ( ctx ) ;
release_gl_drawable ( gl ) ;
}
2007-09-23 05:45:27 +02:00
pglFinish ( ) ;
2012-10-02 21:50:54 +02:00
if ( escape . gl_drawable ) ExtEscape ( ctx - > hdc , X11DRV_ESCAPE , sizeof ( escape ) , ( LPSTR ) & escape , 0 , NULL ) ;
2007-09-23 05:45:27 +02:00
}
2012-07-16 23:56:55 +02:00
static void wglFlush ( void )
2007-09-23 05:45:27 +02:00
{
2012-10-02 21:50:54 +02:00
struct x11drv_escape_flush_gl_drawable escape ;
struct gl_drawable * gl ;
2012-06-29 12:29:55 +02:00
struct wgl_context * ctx = NtCurrentTeb ( ) - > glContext ;
2007-09-26 16:15:52 +02:00
2012-10-02 21:50:54 +02:00
escape . code = X11DRV_FLUSH_GL_DRAWABLE ;
escape . gl_drawable = 0 ;
2018-03-16 11:08:28 +01:00
escape . flush = FALSE ;
2012-10-02 21:50:54 +02:00
if ( ( gl = get_gl_drawable ( WindowFromDC ( ctx - > hdc ) , 0 ) ) )
{
switch ( gl - > type )
{
case DC_GL_PIXMAP_WIN : escape . gl_drawable = gl - > pixmap ; break ;
2016-05-26 23:43:14 +02:00
case DC_GL_CHILD_WIN : escape . gl_drawable = gl - > window ; break ;
2012-10-02 21:50:54 +02:00
default : break ;
}
sync_context ( ctx ) ;
release_gl_drawable ( gl ) ;
}
2007-09-23 05:45:27 +02:00
pglFlush ( ) ;
2012-10-02 21:50:54 +02:00
if ( escape . gl_drawable ) ExtEscape ( ctx - > hdc , X11DRV_ESCAPE , sizeof ( escape ) , ( LPSTR ) & escape , 0 , NULL ) ;
2007-09-23 05:45:27 +02:00
}
2013-08-12 23:07:05 +02:00
static const GLubyte * wglGetString ( GLenum name )
{
2018-02-12 16:06:01 +01:00
if ( name = = GL_EXTENSIONS & & glExtensions ) return ( const GLubyte * ) glExtensions ;
2013-08-12 23:07:05 +02:00
return pglGetString ( name ) ;
}
2012-06-28 15:07:44 +02:00
/***********************************************************************
2012-07-17 00:00:55 +02:00
* X11DRV_wglCreateContextAttribsARB
2009-11-16 23:24:24 +01:00
*/
2012-07-17 00:00:55 +02:00
static struct wgl_context * X11DRV_wglCreateContextAttribsARB ( HDC hdc , struct wgl_context * hShareContext ,
2012-06-29 12:29:55 +02:00
const int * attribList )
2009-11-16 23:24:24 +01:00
{
2015-11-04 06:15:15 +01:00
struct wgl_context * ret ;
2012-09-07 16:19:06 +02:00
struct gl_drawable * gl ;
2013-04-19 19:06:15 +02:00
int err = 0 ;
2009-11-16 23:24:24 +01:00
2012-06-28 15:07:44 +02:00
TRACE ( " (%p %p %p) \n " , hdc , hShareContext , attribList ) ;
2009-11-16 23:24:24 +01:00
2012-09-07 22:04:33 +02:00
if ( ! ( gl = get_gl_drawable ( WindowFromDC ( hdc ) , hdc ) ) )
{
SetLastError ( ERROR_INVALID_PIXEL_FORMAT ) ;
return NULL ;
}
2009-11-16 23:24:24 +01:00
2012-09-07 22:04:33 +02:00
if ( ( ret = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , sizeof ( * ret ) ) ) )
2009-11-16 23:24:24 +01:00
{
2012-09-07 16:19:06 +02:00
ret - > hdc = hdc ;
ret - > fmt = gl - > format ;
ret - > gl3_context = TRUE ;
if ( attribList )
2009-11-16 23:24:24 +01:00
{
2012-09-07 16:19:06 +02:00
int * pContextAttribList = & ret - > attribList [ 0 ] ;
/* attribList consists of pairs {token, value] terminated with 0 */
while ( attribList [ 0 ] ! = 0 )
2009-11-16 23:24:24 +01:00
{
2012-09-07 16:19:06 +02:00
TRACE ( " %#x %#x \n " , attribList [ 0 ] , attribList [ 1 ] ) ;
switch ( attribList [ 0 ] )
{
2009-11-16 23:24:24 +01:00
case WGL_CONTEXT_MAJOR_VERSION_ARB :
pContextAttribList [ 0 ] = GLX_CONTEXT_MAJOR_VERSION_ARB ;
2012-09-07 16:19:06 +02:00
pContextAttribList [ 1 ] = attribList [ 1 ] ;
2013-04-11 16:34:31 +02:00
pContextAttribList + = 2 ;
2013-05-31 14:52:21 +02:00
ret - > numAttribs + + ;
2009-11-16 23:24:24 +01:00
break ;
case WGL_CONTEXT_MINOR_VERSION_ARB :
pContextAttribList [ 0 ] = GLX_CONTEXT_MINOR_VERSION_ARB ;
2012-09-07 16:19:06 +02:00
pContextAttribList [ 1 ] = attribList [ 1 ] ;
2013-04-11 16:34:31 +02:00
pContextAttribList + = 2 ;
2013-05-31 14:52:21 +02:00
ret - > numAttribs + + ;
2009-11-16 23:24:24 +01:00
break ;
case WGL_CONTEXT_LAYER_PLANE_ARB :
break ;
case WGL_CONTEXT_FLAGS_ARB :
pContextAttribList [ 0 ] = GLX_CONTEXT_FLAGS_ARB ;
2012-09-07 16:19:06 +02:00
pContextAttribList [ 1 ] = attribList [ 1 ] ;
2013-04-11 16:34:31 +02:00
pContextAttribList + = 2 ;
2013-05-31 14:52:21 +02:00
ret - > numAttribs + + ;
2009-11-16 23:24:24 +01:00
break ;
2018-01-24 17:33:22 +01:00
case WGL_CONTEXT_OPENGL_NO_ERROR_ARB :
pContextAttribList [ 0 ] = GLX_CONTEXT_OPENGL_NO_ERROR_ARB ;
pContextAttribList [ 1 ] = attribList [ 1 ] ;
pContextAttribList + = 2 ;
ret - > numAttribs + + ;
break ;
2009-11-17 11:50:25 +01:00
case WGL_CONTEXT_PROFILE_MASK_ARB :
pContextAttribList [ 0 ] = GLX_CONTEXT_PROFILE_MASK_ARB ;
2012-09-07 16:19:06 +02:00
pContextAttribList [ 1 ] = attribList [ 1 ] ;
2013-04-11 16:34:31 +02:00
pContextAttribList + = 2 ;
2013-05-31 14:52:21 +02:00
ret - > numAttribs + + ;
2009-11-17 11:50:25 +01:00
break ;
2016-03-15 16:55:13 +01:00
case WGL_RENDERER_ID_WINE :
pContextAttribList [ 0 ] = GLX_RENDERER_ID_MESA ;
pContextAttribList [ 1 ] = attribList [ 1 ] ;
pContextAttribList + = 2 ;
ret - > numAttribs + + ;
break ;
2009-11-16 23:24:24 +01:00
default :
2012-09-07 16:19:06 +02:00
ERR ( " Unhandled attribList pair: %#x %#x \n " , attribList [ 0 ] , attribList [ 1 ] ) ;
}
attribList + = 2 ;
2009-11-16 23:24:24 +01:00
}
}
2012-09-07 16:19:06 +02:00
X11DRV_expect_error ( gdi_display , GLXErrorHandler , NULL ) ;
2013-04-23 13:21:30 +02:00
ret - > ctx = create_glxcontext ( gdi_display , ret , hShareContext ? hShareContext - > ctx : NULL ) ;
2012-09-07 16:19:06 +02:00
XSync ( gdi_display , False ) ;
2013-04-19 19:06:15 +02:00
if ( ( err = X11DRV_check_error ( ) ) | | ! ret - > ctx )
2012-09-07 16:19:06 +02:00
{
2012-09-07 22:04:33 +02:00
/* In the future we should convert the GLX error to a win32 one here if needed */
2018-01-19 19:25:16 +01:00
WARN ( " Context creation failed (error %#x). \n " , err ) ;
2012-09-07 22:04:33 +02:00
HeapFree ( GetProcessHeap ( ) , 0 , ret ) ;
ret = NULL ;
2012-09-07 16:19:06 +02:00
}
2018-02-12 15:34:28 +01:00
else
{
EnterCriticalSection ( & context_section ) ;
list_add_head ( & context_list , & ret - > entry ) ;
LeaveCriticalSection ( & context_section ) ;
}
2009-11-16 23:24:24 +01:00
}
2012-09-07 22:04:33 +02:00
release_gl_drawable ( gl ) ;
2012-09-07 16:19:06 +02:00
TRACE ( " %p -> %p \n " , hdc , ret ) ;
2012-06-29 12:29:55 +02:00
return ret ;
2009-11-16 23:24:24 +01:00
}
2006-11-12 20:23:38 +01:00
/**
* X11DRV_wglGetExtensionsStringARB
*
* WGL_ARB_extensions_string : wglGetExtensionsStringARB
*/
2013-11-01 18:18:26 +01:00
static const char * X11DRV_wglGetExtensionsStringARB ( HDC hdc )
2012-07-17 00:00:55 +02:00
{
2018-02-12 16:06:01 +01:00
TRACE ( " () returning \" %s \" \n " , wglExtensions ) ;
return wglExtensions ;
2006-09-11 21:28:32 +02:00
}
2006-11-12 20:23:38 +01:00
/**
* X11DRV_wglCreatePbufferARB
*
* WGL_ARB_pbuffer : wglCreatePbufferARB
*/
2012-07-20 12:25:01 +02:00
static struct wgl_pbuffer * X11DRV_wglCreatePbufferARB ( HDC hdc , int iPixelFormat , int iWidth , int iHeight ,
const int * piAttribList )
2006-09-11 21:28:32 +02:00
{
2015-11-04 06:15:15 +01:00
struct wgl_pbuffer * object ;
const struct wgl_pixel_format * fmt ;
2006-09-11 21:28:32 +02:00
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 ) ;
/* Convert the WGL pixelformat to a GLX format, if it fails then the format is invalid */
2012-08-15 15:38:05 +02:00
fmt = get_pixel_format ( gdi_display , iPixelFormat , TRUE /* Offscreen */ ) ;
2007-07-26 19:23:39 +02:00
if ( ! fmt ) {
2012-07-20 12:35:24 +02:00
ERR ( " (%p): invalid pixel format %d \n " , hdc , iPixelFormat ) ;
2006-09-11 21:28:32 +02:00
SetLastError ( ERROR_INVALID_PIXEL_FORMAT ) ;
2012-07-20 12:25:01 +02:00
return NULL ;
2006-09-11 21:28:32 +02:00
}
2012-07-20 12:25:01 +02:00
object = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , sizeof ( * object ) ) ;
2006-09-11 21:28:32 +02:00
if ( NULL = = object ) {
SetLastError ( ERROR_NO_SYSTEM_RESOURCES ) ;
2012-07-20 12:25:01 +02:00
return NULL ;
2006-09-11 21:28:32 +02:00
}
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 ) ;
2012-06-25 07:42:10 +02:00
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 ;
}
2006-09-11 21:28:32 +02:00
switch ( attr_v ) {
2012-06-25 07:42:10 +02:00
case WGL_TEXTURE_RGB_ARB :
object - > use_render_texture = GL_RGB ;
object - > texture_bpp = 3 ;
object - > texture_format = GL_RGB ;
object - > texture_type = GL_UNSIGNED_BYTE ;
break ;
case WGL_TEXTURE_RGBA_ARB :
object - > use_render_texture = GL_RGBA ;
object - > texture_bpp = 4 ;
object - > texture_format = GL_RGBA ;
object - > texture_type = GL_UNSIGNED_BYTE ;
break ;
/* WGL_FLOAT_COMPONENTS_NV */
case WGL_TEXTURE_FLOAT_R_NV :
object - > use_render_texture = GL_FLOAT_R_NV ;
object - > texture_bpp = 4 ;
object - > texture_format = GL_RED ;
object - > texture_type = GL_FLOAT ;
break ;
case WGL_TEXTURE_FLOAT_RG_NV :
object - > use_render_texture = GL_FLOAT_RG_NV ;
object - > texture_bpp = 8 ;
object - > texture_format = GL_LUMINANCE_ALPHA ;
object - > texture_type = GL_FLOAT ;
break ;
case WGL_TEXTURE_FLOAT_RGB_NV :
object - > use_render_texture = GL_FLOAT_RGB_NV ;
object - > texture_bpp = 12 ;
object - > texture_format = GL_RGB ;
object - > texture_type = GL_FLOAT ;
break ;
case WGL_TEXTURE_FLOAT_RGBA_NV :
object - > use_render_texture = GL_FLOAT_RGBA_NV ;
object - > texture_bpp = 16 ;
object - > texture_format = GL_RGBA ;
object - > texture_type = GL_FLOAT ;
break ;
2006-09-11 21:28:32 +02:00
default :
2012-06-25 07:42:10 +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 ) ;
2012-06-25 07:42:10 +02:00
if ( WGL_NO_TEXTURE_ARB = = attr_v ) {
object - > texture_target = 0 ;
2006-09-11 21:28:32 +02:00
} else {
2012-06-25 07:42:10 +02:00
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 ;
2007-07-27 15:01:52 +02:00
}
2012-06-25 07:42:10 +02:00
object - > texture_target = GL_TEXTURE_CUBE_MAP ;
object - > texture_bind_target = GL_TEXTURE_BINDING_CUBE_MAP ;
break ;
}
case WGL_TEXTURE_1D_ARB : {
if ( 1 ! = iHeight ) {
2006-09-11 21:28:32 +02:00
SetLastError ( ERROR_INVALID_DATA ) ;
goto create_failed ;
2012-06-25 07:42:10 +02:00
}
object - > texture_target = GL_TEXTURE_1D ;
object - > texture_bind_target = GL_TEXTURE_BINDING_1D ;
break ;
}
case WGL_TEXTURE_2D_ARB : {
object - > texture_target = GL_TEXTURE_2D ;
object - > texture_bind_target = GL_TEXTURE_BINDING_2D ;
break ;
}
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
}
2012-06-25 07:42:10 +02:00
default :
ERR ( " Unknown texture target: %x \n " , attr_v ) ;
SetLastError ( ERROR_INVALID_DATA ) ;
goto create_failed ;
2006-09-11 21:28:32 +02:00
}
}
break ;
}
case WGL_MIPMAP_TEXTURE_ARB : {
+ + piAttribList ;
attr_v = * piAttribList ;
TRACE ( " WGL_render_texture Attribute: WGL_MIPMAP_TEXTURE_ARB as %x \n " , attr_v ) ;
2012-06-25 07:42:10 +02:00
if ( ! use_render_texture_emulation ) {
SetLastError ( ERROR_INVALID_DATA ) ;
goto create_failed ;
2006-09-11 21:28:32 +02:00
}
break ;
}
}
+ + piAttribList ;
}
PUSH1 ( attribs , None ) ;
2007-07-26 19:23:39 +02:00
object - > drawable = pglXCreatePbuffer ( gdi_display , fmt - > fbconfig , attribs ) ;
2012-05-03 12:22:49 +02:00
TRACE ( " new Pbuffer drawable as %lx \n " , object - > drawable ) ;
2006-09-11 21:28:32 +02:00
if ( ! object - > drawable ) {
SetLastError ( ERROR_NO_SYSTEM_RESOURCES ) ;
goto create_failed ; /* unexpected error */
}
2016-03-15 18:58:26 +01:00
EnterCriticalSection ( & context_section ) ;
list_add_head ( & pbuffer_list , & object - > entry ) ;
LeaveCriticalSection ( & context_section ) ;
2006-09-11 21:28:32 +02:00
TRACE ( " ->(%p) \n " , object ) ;
2012-07-20 12:25:01 +02: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
*/
2012-07-20 12:25:01 +02:00
static BOOL X11DRV_wglDestroyPbufferARB ( struct wgl_pbuffer * object )
2006-09-11 21:28:32 +02:00
{
2012-07-20 12:25:01 +02:00
TRACE ( " (%p) \n " , object ) ;
2016-03-15 18:58:26 +01:00
EnterCriticalSection ( & context_section ) ;
list_remove ( & object - > entry ) ;
LeaveCriticalSection ( & context_section ) ;
2012-07-20 12:35:24 +02:00
pglXDestroyPbuffer ( gdi_display , object - > drawable ) ;
2016-03-15 18:58:26 +01:00
if ( object - > tmp_context )
pglXDestroyContext ( gdi_display , object - > tmp_context ) ;
2006-09-11 21:28:32 +02:00
HeapFree ( GetProcessHeap ( ) , 0 , object ) ;
return GL_TRUE ;
}
2006-11-12 20:23:38 +01:00
/**
2012-05-08 12:35:13 +02:00
* X11DRV_wglGetPbufferDCARB
2006-11-12 20:23:38 +01:00
*
* WGL_ARB_pbuffer : wglGetPbufferDCARB
2006-11-04 22:23:15 +01:00
*/
2012-07-20 12:25:01 +02:00
static HDC X11DRV_wglGetPbufferDCARB ( struct wgl_pbuffer * object )
2006-09-11 21:28:32 +02:00
{
2012-05-08 12:35:13 +02:00
struct x11drv_escape_set_drawable escape ;
2012-09-07 15:23:15 +02:00
struct gl_drawable * gl , * prev ;
2012-05-08 12:35:13 +02:00
HDC hdc ;
2011-07-08 15:55:11 +02:00
2012-05-08 12:35:13 +02:00
hdc = CreateDCA ( " DISPLAY " , NULL , NULL , NULL ) ;
if ( ! hdc ) return 0 ;
2012-09-07 15:23:15 +02:00
if ( ! ( gl = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , sizeof ( * gl ) ) ) )
{
DeleteDC ( hdc ) ;
return 0 ;
}
gl - > type = DC_GL_PBUFFER ;
gl - > drawable = object - > drawable ;
2012-09-07 15:36:57 +02:00
gl - > format = object - > fmt ;
2018-02-12 15:34:28 +01:00
gl - > ref = 1 ;
2012-09-07 15:23:15 +02:00
EnterCriticalSection ( & context_section ) ;
if ( ! XFindContext ( gdi_display , ( XID ) hdc , gl_pbuffer_context , ( char * * ) & prev ) )
2018-02-12 15:34:28 +01:00
release_gl_drawable ( prev ) ;
2012-09-07 15:23:15 +02:00
XSaveContext ( gdi_display , ( XID ) hdc , gl_pbuffer_context , ( char * ) gl ) ;
LeaveCriticalSection ( & context_section ) ;
2012-05-08 12:35:13 +02:00
escape . code = X11DRV_SET_DRAWABLE ;
escape . drawable = object - > drawable ;
escape . mode = IncludeInferiors ;
2012-07-12 21:19:58 +02:00
SetRect ( & escape . dc_rect , 0 , 0 , object - > width , object - > height ) ;
2012-05-08 12:35:13 +02:00
ExtEscape ( hdc , X11DRV_ESCAPE , sizeof ( escape ) , ( LPSTR ) & escape , 0 , NULL ) ;
2006-11-04 22:23:15 +01:00
2012-07-20 12:25:01 +02:00
TRACE ( " (%p)->(%p) \n " , object , hdc ) ;
2012-05-08 12:35:13 +02:00
return hdc ;
2006-09-11 21:28:32 +02:00
}
2006-11-12 20:23:38 +01:00
/**
* X11DRV_wglQueryPbufferARB
*
* WGL_ARB_pbuffer : wglQueryPbufferARB
*/
2012-07-20 12:25:01 +02:00
static BOOL X11DRV_wglQueryPbufferARB ( struct wgl_pbuffer * object , int iAttribute , int * piValue )
2006-09-11 21:28:32 +02:00
{
2012-07-20 12:25:01 +02:00
TRACE ( " (%p, 0x%x, %p) \n " , object , iAttribute , piValue ) ;
2006-09-11 21:28:32 +02:00
switch ( iAttribute ) {
case WGL_PBUFFER_WIDTH_ARB :
2012-07-20 12:35:24 +02:00
pglXQueryDrawable ( gdi_display , object - > drawable , GLX_WIDTH , ( unsigned int * ) piValue ) ;
2006-09-11 21:28:32 +02:00
break ;
case WGL_PBUFFER_HEIGHT_ARB :
2012-07-20 12:35:24 +02:00
pglXQueryDrawable ( gdi_display , object - > drawable , GLX_HEIGHT , ( unsigned int * ) piValue ) ;
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 :
2012-06-25 07:42:10 +02:00
if ( ! object - > use_render_texture ) {
* piValue = WGL_NO_TEXTURE_ARB ;
2006-09-11 21:28:32 +02:00
} else {
2012-06-25 07:42:10 +02:00
if ( ! use_render_texture_emulation ) {
SetLastError ( ERROR_INVALID_HANDLE ) ;
return GL_FALSE ;
}
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 :
2012-06-25 07:42:10 +02:00
if ( ! object - > texture_target ) {
2006-09-11 21:28:32 +02:00
* piValue = WGL_NO_TEXTURE_ARB ;
} else {
if ( ! use_render_texture_emulation ) {
2012-06-25 07:42:10 +02:00
SetLastError ( ERROR_INVALID_DATA ) ;
2006-09-11 21:28:32 +02:00
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
}
}
2012-06-25 07:42:10 +02:00
break ;
2006-09-11 21:28:32 +02:00
2012-06-25 07:42:10 +02:00
case WGL_MIPMAP_TEXTURE_ARB :
2006-09-11 21:28:32 +02:00
* piValue = GL_FALSE ; /** don't support that */
FIXME ( " unsupported WGL_ARB_render_texture attribute query for 0x%x \n " , iAttribute ) ;
2012-06-25 07:42:10 +02:00
break ;
2006-09-11 21:28:32 +02:00
2012-06-25 07:42:10 +02:00
default :
FIXME ( " unexpected attribute %x \n " , iAttribute ) ;
break ;
2006-09-11 21:28:32 +02:00
}
return GL_TRUE ;
}
2006-11-12 20:23:38 +01:00
/**
* X11DRV_wglReleasePbufferDCARB
*
* WGL_ARB_pbuffer : wglReleasePbufferDCARB
*/
2012-07-20 12:25:01 +02:00
static int X11DRV_wglReleasePbufferDCARB ( struct wgl_pbuffer * object , HDC hdc )
2006-09-11 21:28:32 +02:00
{
2012-09-07 15:23:15 +02:00
struct gl_drawable * gl ;
2012-07-20 12:25:01 +02:00
TRACE ( " (%p, %p) \n " , object , hdc ) ;
2012-09-07 15:23:15 +02:00
EnterCriticalSection ( & context_section ) ;
2012-10-17 21:40:52 +02:00
2012-09-07 15:23:15 +02:00
if ( ! XFindContext ( gdi_display , ( XID ) hdc , gl_pbuffer_context , ( char * * ) & gl ) )
{
XDeleteContext ( gdi_display , ( XID ) hdc , gl_pbuffer_context ) ;
2018-02-12 15:34:28 +01:00
release_gl_drawable ( gl ) ;
2012-09-07 15:23:15 +02:00
}
2012-10-17 21:40:52 +02:00
else hdc = 0 ;
2012-09-07 15:23:15 +02:00
LeaveCriticalSection ( & context_section ) ;
2012-10-17 21:40:52 +02:00
return hdc & & DeleteDC ( hdc ) ;
2006-09-11 21:28:32 +02:00
}
2006-11-12 20:23:38 +01:00
/**
* X11DRV_wglSetPbufferAttribARB
*
* WGL_ARB_pbuffer : wglSetPbufferAttribARB
*/
2012-07-20 12:25:01 +02:00
static BOOL X11DRV_wglSetPbufferAttribARB ( struct wgl_pbuffer * object , const int * piAttribList )
2006-09-11 21:28:32 +02:00
{
2008-05-28 17:02:07 +02:00
GLboolean ret = GL_FALSE ;
2012-07-20 12:25:01 +02:00
WARN ( " (%p, %p): alpha-testing, report any problem \n " , object , piAttribList ) ;
2006-09-11 21:28:32 +02:00
if ( ! object - > use_render_texture ) {
SetLastError ( ERROR_INVALID_HANDLE ) ;
return GL_FALSE ;
}
2013-10-09 00:06:15 +02:00
if ( use_render_texture_emulation ) {
2006-09-11 21:28:32 +02:00
return GL_TRUE ;
}
2008-05-28 17:02:07 +02:00
return ret ;
2006-09-11 21:28:32 +02:00
}
2021-02-24 15:04:53 +01:00
struct choose_pixel_format_arb_format
{
int format ;
int original_index ;
PIXELFORMATDESCRIPTOR pfd ;
int depth , stencil ;
} ;
static int compare_formats ( const void * a , const void * b )
{
/* Order formats so that onscreen formats go first. Then, if no depth bits requested,
* prioritize formats with smaller depth within the original sort order with respect to
* other attributes . */
const struct choose_pixel_format_arb_format * fmt_a = a , * fmt_b = b ;
BOOL offscreen_a , offscreen_b ;
offscreen_a = fmt_a - > format > nb_onscreen_formats ;
offscreen_b = fmt_b - > format > nb_onscreen_formats ;
if ( offscreen_a ! = offscreen_b )
return offscreen_a - offscreen_b ;
if ( memcmp ( & fmt_a - > pfd , & fmt_b - > pfd , sizeof ( fmt_a - > pfd ) ) )
return fmt_a - > original_index - fmt_b - > original_index ;
if ( fmt_a - > depth ! = fmt_b - > depth )
return fmt_a - > depth - fmt_b - > depth ;
if ( fmt_a - > stencil ! = fmt_b - > stencil )
return fmt_a - > stencil - fmt_b - > stencil ;
return fmt_a - > original_index - fmt_b - > original_index ;
}
2006-11-12 20:23:38 +01:00
/**
* X11DRV_wglChoosePixelFormatARB
*
* WGL_ARB_pixel_format : wglChoosePixelFormatARB
*/
2012-07-17 00:00:55 +02:00
static BOOL X11DRV_wglChoosePixelFormatARB ( HDC hdc , const int * piAttribIList , const FLOAT * pfAttribFList ,
UINT nMaxFormats , int * piFormats , UINT * nNumFormats )
2006-09-11 21:28:32 +02:00
{
2021-02-24 15:04:53 +01:00
struct choose_pixel_format_arb_format * formats ;
int it , i , format_count ;
BYTE depth_bits = 0 ;
GLXFBConfig * cfgs ;
DWORD dwFlags = 0 ;
2006-09-11 21:28:32 +02:00
int attribs [ 256 ] ;
int nAttribs = 0 ;
int nCfgs = 0 ;
int fmt_id ;
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).
2012-08-15 15:38:05 +02:00
* Flags like PFD_SUPPORT_GDI , PFD_DRAW_TO_BITMAP and others are a property of the pixel format . We don ' t query these attributes
* using glXChooseFBConfig but we filter the result of glXChooseFBConfig later on .
*/
2009-05-16 21:50:58 +02:00
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 ;
2021-02-24 15:04:53 +01:00
case WGL_DEPTH_BITS_ARB :
depth_bits = piAttribIList [ i + 1 ] ;
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 */
cfgs = pglXChooseFBConfig ( gdi_display , DefaultScreen ( gdi_display ) , attribs , & nCfgs ) ;
if ( NULL = = cfgs ) {
WARN ( " Compatible Pixel Format not found \n " ) ;
return GL_FALSE ;
}
2021-02-24 15:04:53 +01:00
if ( ! ( formats = heap_alloc ( nCfgs * sizeof ( * formats ) ) ) )
{
ERR ( " No memory. \n " ) ;
XFree ( cfgs ) ;
return GL_FALSE ;
}
format_count = 0 ;
for ( it = 0 ; it < nCfgs ; + + it )
2007-08-10 15:35:02 +02:00
{
2021-02-24 15:04:53 +01:00
struct choose_pixel_format_arb_format * format ;
if ( pglXGetFBConfigAttrib ( gdi_display , cfgs [ it ] , GLX_FBCONFIG_ID , & fmt_id ) )
2012-06-07 06:55:34 +02:00
{
2021-02-24 15:04:53 +01:00
ERR ( " Failed to retrieve FBCONFIG_ID from GLXFBConfig, expect problems. \n " ) ;
continue ;
}
2006-09-11 21:28:32 +02:00
2021-02-24 15:04:53 +01:00
for ( i = 0 ; i < nb_pixel_formats ; + + i )
if ( pixel_formats [ i ] . fmt_id = = fmt_id )
break ;
2007-08-10 15:35:02 +02:00
2021-02-24 15:04:53 +01:00
if ( i = = nb_pixel_formats )
continue ;
format = & formats [ format_count ] ;
format - > format = i + 1 ;
format - > original_index = it ;
memset ( & format - > pfd , 0 , sizeof ( format - > pfd ) ) ;
if ( ! describe_pixel_format ( format - > format , & format - > pfd , TRUE ) )
ERR ( " describe_pixel_format failed, format %d. \n " , format - > format ) ;
format - > depth = format - > pfd . cDepthBits ;
format - > stencil = format - > pfd . cStencilBits ;
if ( ! depth_bits & & ! ( format - > pfd . dwFlags & PFD_GENERIC_FORMAT ) )
{
format - > pfd . cDepthBits = 0 ;
format - > pfd . cStencilBits = 0 ;
2007-08-01 23:20:54 +02:00
}
2021-02-24 15:04:53 +01:00
+ + format_count ;
2006-09-11 21:28:32 +02:00
}
2021-02-24 15:04:53 +01:00
qsort ( formats , format_count , sizeof ( * formats ) , compare_formats ) ;
* nNumFormats = min ( nMaxFormats , format_count ) ;
for ( i = 0 ; i < * nNumFormats ; + + i )
piFormats [ i ] = formats [ i ] . format ;
heap_free ( formats ) ;
2006-09-11 21:28:32 +02:00
XFree ( cfgs ) ;
return GL_TRUE ;
}
2006-11-12 20:23:38 +01:00
/**
* X11DRV_wglGetPixelFormatAttribivARB
*
* WGL_ARB_pixel_format : wglGetPixelFormatAttribivARB
*/
2012-07-17 00:00:55 +02:00
static BOOL 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 ;
2015-11-04 06:15:15 +01:00
const struct wgl_pixel_format * fmt ;
2006-09-11 21:28:32 +02:00
int hTest ;
int tmp ;
int curGLXAttr = 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 . */
2012-08-15 15:38:05 +02:00
fmt = get_pixel_format ( gdi_display , iPixelFormat , TRUE /* Offscreen */ ) ;
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
}
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 :
2012-08-15 15:32:24 +02:00
piValues [ i ] = nb_pixel_formats ;
2006-09-11 21:28:32 +02:00
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 ;
2012-12-21 20:18:58 +01:00
piValues [ i ] = GL_FALSE ;
2006-09-11 21:28:32 +02:00
if ( GLX_NONE ! = tmp ) piValues [ i ] = GL_TRUE ;
2012-12-21 20:18:58 +01:00
continue ;
2006-09-11 21:28:32 +02:00
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 :
case WGL_BIND_TO_TEXTURE_RGBA_ARB :
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 ;
2012-07-31 11:33:15 +02:00
piValues [ i ] = ( fmt - > dwFlags & PFD_SUPPORT_GDI ) ! = 0 ;
2009-05-16 21:50:58 +02:00
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 ;
2012-07-31 11:33:15 +02:00
piValues [ i ] = ( fmt - > dwFlags & PFD_DRAW_TO_BITMAP ) ! = 0 ;
2009-05-17 21:50:56 +02:00
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 :
2014-11-10 18:56:11 +01:00
if ( has_swap_method )
{
2016-02-12 10:01:42 +01:00
hTest = pglXGetFBConfigAttrib ( gdi_display , fmt - > fbconfig , GLX_SWAP_METHOD_OML , & tmp ) ;
2014-11-10 18:56:11 +01:00
if ( hTest ) goto get_error ;
switch ( tmp )
{
case GLX_SWAP_EXCHANGE_OML :
piValues [ i ] = WGL_SWAP_EXCHANGE_ARB ;
break ;
case GLX_SWAP_COPY_OML :
piValues [ i ] = WGL_SWAP_COPY_ARB ;
break ;
case GLX_SWAP_UNDEFINED_OML :
piValues [ i ] = WGL_SWAP_UNDEFINED_ARB ;
break ;
default :
ERR ( " Unexpected swap method %x. \n " , tmp ) ;
}
}
else
{
WARN ( " GLX_OML_swap_method not supported, returning WGL_SWAP_EXCHANGE_ARB. \n " ) ;
piValues [ i ] = WGL_SWAP_EXCHANGE_ARB ;
}
2014-11-10 18:56:10 +01:00
continue ;
2009-05-16 00:00:24 +02:00
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 ;
}
}
return GL_TRUE ;
get_error :
ERR ( " (%p): unexpected failure on GetFBConfigAttrib(%x) returns FALSE \n " , hdc , curGLXAttr ) ;
return GL_FALSE ;
pix_error :
2012-08-15 15:32:24 +02:00
ERR ( " (%p): unexpected iPixelFormat(%d) vs nFormats(%d), returns FALSE \n " , hdc , iPixelFormat , nb_pixel_formats ) ;
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
*/
2012-07-17 00:00:55 +02:00
static BOOL X11DRV_wglGetPixelFormatAttribfvARB ( HDC hdc , int iPixelFormat , int iLayerPlane ,
UINT nAttributes , const int * piAttributes , FLOAT * pfValues )
2006-12-06 02:46:30 +01:00
{
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
*/
2012-07-20 12:25:01 +02:00
static BOOL X11DRV_wglBindTexImageARB ( struct wgl_pbuffer * object , int iBuffer )
2006-09-11 21:28:32 +02:00
{
2008-05-28 17:02:07 +02:00
GLboolean ret = GL_FALSE ;
2012-07-20 12:25:01 +02:00
TRACE ( " (%p, %d) \n " , object , iBuffer ) ;
2006-09-11 21:28:32 +02:00
if ( ! object - > use_render_texture ) {
SetLastError ( ERROR_INVALID_HANDLE ) ;
return GL_FALSE ;
}
2007-07-25 22:32:07 +02:00
2013-10-09 00:06:15 +02:00
if ( use_render_texture_emulation ) {
static BOOL initialized = FALSE ;
2007-07-29 14:13:45 +02:00
int prev_binded_texture = 0 ;
2008-05-28 17:02:07 +02:00
GLXContext prev_context ;
2016-05-26 23:43:14 +02:00
GLXDrawable prev_drawable ;
2007-07-25 22:32:07 +02:00
2008-05-28 17:02:07 +02:00
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 .
*/
2013-10-09 00:06:15 +02:00
if ( ! initialized ) {
initialized = TRUE ; /* Only show the FIXME once for performance reasons */
2007-07-25 22:32:07 +02:00
FIXME ( " partial stub! \n " ) ;
2006-09-11 21:28:32 +02:00
}
2007-07-25 22:32:07 +02:00
2012-05-03 12:22:49 +02:00
TRACE ( " drawable=%lx, context=%p \n " , object - > drawable , prev_context ) ;
2016-03-15 18:58:26 +01:00
if ( ! object - > tmp_context | | object - > prev_context ! = prev_context ) {
if ( object - > tmp_context )
pglXDestroyContext ( gdi_display , object - > tmp_context ) ;
object - > tmp_context = pglXCreateNewContext ( gdi_display , object - > fmt - > fbconfig , object - > fmt - > render_type , prev_context , True ) ;
object - > prev_context = prev_context ;
}
2007-07-29 14:13:45 +02:00
2012-07-20 13:21:20 +02:00
opengl_funcs . gl . p_glGetIntegerv ( 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 */
2016-03-15 18:58:26 +01:00
pglXMakeCurrent ( gdi_display , object - > drawable , object - > 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.
2016-03-15 18:58:26 +01:00
* After that copy the pbuffer texture data . */
2012-07-17 00:00:55 +02:00
opengl_funcs . gl . p_glBindTexture ( object - > texture_target , prev_binded_texture ) ;
opengl_funcs . gl . p_glCopyTexImage2D ( object - > texture_target , 0 , object - > use_render_texture , 0 , 0 , object - > width , object - > height , 0 ) ;
2007-07-25 22:32:07 +02:00
2016-03-15 18:58:26 +01:00
/* Switch back to the original drawable and context */
2012-07-20 12:35:24 +02:00
pglXMakeCurrent ( gdi_display , prev_drawable , prev_context ) ;
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
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
*/
2012-07-20 12:25:01 +02:00
static BOOL X11DRV_wglReleaseTexImageARB ( struct wgl_pbuffer * object , int iBuffer )
2006-09-11 21:28:32 +02:00
{
2008-05-28 17:02:07 +02:00
GLboolean ret = GL_FALSE ;
2012-07-20 12:25:01 +02:00
TRACE ( " (%p, %d) \n " , object , iBuffer ) ;
2006-09-11 21:28:32 +02:00
if ( ! object - > use_render_texture ) {
SetLastError ( ERROR_INVALID_HANDLE ) ;
return GL_FALSE ;
}
2013-10-09 00:06:15 +02:00
if ( use_render_texture_emulation ) {
2006-09-11 21:28:32 +02:00
return GL_TRUE ;
}
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
*/
2013-11-01 18:18:26 +01:00
static const char * X11DRV_wglGetExtensionsStringEXT ( void )
2012-07-17 00:00:55 +02:00
{
2018-02-12 16:06:01 +01:00
TRACE ( " () returning \" %s \" \n " , wglExtensions ) ;
return wglExtensions ;
2006-09-11 21:28:32 +02:00
}
2006-11-12 20:23:38 +01:00
/**
* X11DRV_wglGetSwapIntervalEXT
*
* WGL_EXT_swap_control : wglGetSwapIntervalEXT
*/
2012-07-17 00:00:55 +02:00
static int X11DRV_wglGetSwapIntervalEXT ( void )
{
2013-05-12 02:55:18 +02:00
struct wgl_context * ctx = NtCurrentTeb ( ) - > glContext ;
struct gl_drawable * gl ;
int swap_interval ;
2010-12-27 13:44:11 +01:00
TRACE ( " () \n " ) ;
2013-05-12 02:55:18 +02:00
if ( ! ( gl = get_gl_drawable ( WindowFromDC ( ctx - > hdc ) , ctx - > hdc ) ) )
{
/* This can't happen because a current WGL context is required to get
* here . Likely the application is buggy .
*/
WARN ( " No GL drawable found, returning swap interval 0 \n " ) ;
return 0 ;
}
swap_interval = gl - > swap_interval ;
release_gl_drawable ( gl ) ;
2006-09-11 21:28:32 +02:00
return swap_interval ;
}
2006-11-12 20:23:38 +01:00
/**
* X11DRV_wglSwapIntervalEXT
*
* WGL_EXT_swap_control : wglSwapIntervalEXT
*/
2012-07-17 00:00:55 +02:00
static BOOL X11DRV_wglSwapIntervalEXT ( int interval )
{
2013-05-12 02:55:18 +02:00
struct wgl_context * ctx = NtCurrentTeb ( ) - > glContext ;
struct gl_drawable * gl ;
2015-11-04 06:15:15 +01:00
BOOL ret ;
2008-05-28 17:02:07 +02:00
2006-09-11 21:28:32 +02:00
TRACE ( " (%d) \n " , interval ) ;
2010-12-27 13:44:11 +01:00
2013-09-02 06:58:54 +02:00
/* Without WGL/GLX_EXT_swap_control_tear a negative interval
* is invalid .
*/
if ( interval < 0 & & ! has_swap_control_tear )
2010-12-27 13:44:11 +01:00
{
SetLastError ( ERROR_INVALID_DATA ) ;
return FALSE ;
}
2013-05-12 02:55:18 +02:00
if ( ! ( gl = get_gl_drawable ( WindowFromDC ( ctx - > hdc ) , ctx - > hdc ) ) )
{
SetLastError ( ERROR_DC_NOT_FOUND ) ;
return FALSE ;
}
2018-02-12 15:34:28 +01:00
EnterCriticalSection ( & context_section ) ;
2014-04-01 04:46:48 +02:00
ret = set_swap_interval ( gl - > drawable , interval ) ;
gl - > refresh_swap_interval = FALSE ;
2013-09-02 06:58:53 +02:00
if ( ret )
gl - > swap_interval = interval ;
else
SetLastError ( ERROR_DC_NOT_FOUND ) ;
2018-02-12 15:34:28 +01:00
LeaveCriticalSection ( & context_section ) ;
2013-05-12 02:55:18 +02:00
release_gl_drawable ( gl ) ;
2008-05-28 17:02:07 +02:00
return ret ;
2006-09-11 21:28:32 +02:00
}
2008-04-23 00:15:15 +02:00
/**
2012-06-28 12:00:45 +02:00
* X11DRV_wglSetPixelFormatWINE
2008-04-23 00:15:15 +02:00
*
* WGL_WINE_pixel_format_passthrough : wglSetPixelFormatWINE
* This is a WINE - specific wglSetPixelFormat which can set the pixel format multiple times .
*/
2012-07-17 00:00:55 +02:00
static BOOL X11DRV_wglSetPixelFormatWINE ( HDC hdc , int format )
2008-04-23 00:15:15 +02:00
{
2014-05-06 10:44:01 +02:00
return set_pixel_format ( hdc , format , TRUE ) ;
2008-04-23 00:15:15 +02:00
}
2016-03-15 16:55:13 +01:00
static BOOL X11DRV_wglQueryCurrentRendererIntegerWINE ( GLenum attribute , GLuint * value )
{
return pglXQueryCurrentRendererIntegerMESA ( attribute , value ) ;
}
static const char * X11DRV_wglQueryCurrentRendererStringWINE ( GLenum attribute )
{
return pglXQueryCurrentRendererStringMESA ( attribute ) ;
}
static BOOL X11DRV_wglQueryRendererIntegerWINE ( HDC dc , GLint renderer , GLenum attribute , GLuint * value )
{
return pglXQueryRendererIntegerMESA ( gdi_display , DefaultScreen ( gdi_display ) , renderer , attribute , value ) ;
}
static const char * X11DRV_wglQueryRendererStringWINE ( HDC dc , GLint renderer , GLenum attribute )
{
return pglXQueryRendererStringMESA ( gdi_display , DefaultScreen ( gdi_display ) , renderer , attribute ) ;
}
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 */
2018-02-12 16:06:01 +01:00
return ( requiredVersion < = glxVersion [ 1 ] ) ;
2006-09-11 21:28:32 +02:00
}
2012-07-17 00:00:55 +02:00
static void register_extension ( const char * ext )
2007-07-27 15:01:52 +02:00
{
2018-02-12 16:06:01 +01:00
if ( wglExtensions [ 0 ] )
strcat ( wglExtensions , " " ) ;
strcat ( wglExtensions , ext ) ;
2007-07-27 15:01:52 +02:00
TRACE ( " '%s' \n " , ext ) ;
}
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
{
2018-02-12 16:06:01 +01:00
wglExtensions [ 0 ] = 0 ;
2006-09-12 11:50:36 +02:00
2006-09-11 21:28:32 +02:00
/* ARB Extensions */
2006-09-12 11:50:36 +02:00
2018-02-12 16:06:01 +01:00
if ( has_extension ( glxExtensions , " GLX_ARB_create_context " ) )
2009-11-16 23:24:24 +01:00
{
2012-07-17 00:00:55 +02:00
register_extension ( " WGL_ARB_create_context " ) ;
opengl_funcs . ext . p_wglCreateContextAttribsARB = X11DRV_wglCreateContextAttribsARB ;
2009-11-17 11:50:25 +01:00
2018-02-12 16:06:01 +01:00
if ( has_extension ( glxExtensions , " GLX_ARB_create_context_no_error " ) )
2018-01-24 17:33:22 +01:00
register_extension ( " WGL_ARB_create_context_no_error " ) ;
2018-02-12 16:06:01 +01:00
if ( has_extension ( glxExtensions , " GLX_ARB_create_context_profile " ) )
2012-07-17 00:00:55 +02:00
register_extension ( " WGL_ARB_create_context_profile " ) ;
2009-11-16 23:24:24 +01:00
}
2018-02-12 16:06:01 +01:00
if ( has_extension ( glxExtensions , " GLX_ARB_fbconfig_float " ) )
2007-07-28 18:56:12 +02:00
{
2012-07-17 00:00:55 +02:00
register_extension ( " WGL_ARB_pixel_format_float " ) ;
register_extension ( " WGL_ATI_pixel_format_float " ) ;
2007-07-28 18:56:12 +02:00
}
2012-07-17 00:00:55 +02:00
register_extension ( " WGL_ARB_extensions_string " ) ;
opengl_funcs . ext . p_wglGetExtensionsStringARB = X11DRV_wglGetExtensionsStringARB ;
2006-09-12 11:50:36 +02:00
if ( glxRequireVersion ( 3 ) )
2012-07-17 00:00:55 +02:00
{
register_extension ( " WGL_ARB_make_current_read " ) ;
2012-07-25 14:28:47 +02:00
opengl_funcs . ext . p_wglGetCurrentReadDCARB = ( void * ) 1 ; /* never called */
2012-07-17 00:00:55 +02:00
opengl_funcs . ext . p_wglMakeContextCurrentARB = X11DRV_wglMakeContextCurrentARB ;
}
2006-09-12 11:50:36 +02:00
2018-02-12 16:06:01 +01:00
if ( has_extension ( glxExtensions , " GLX_ARB_multisample " ) ) register_extension ( " WGL_ARB_multisample " ) ;
2006-09-12 11:50:36 +02:00
2013-03-31 17:07:57 +02:00
if ( glxRequireVersion ( 3 ) )
2012-07-17 00:00:55 +02:00
{
register_extension ( " WGL_ARB_pbuffer " ) ;
opengl_funcs . ext . p_wglCreatePbufferARB = X11DRV_wglCreatePbufferARB ;
opengl_funcs . ext . p_wglDestroyPbufferARB = X11DRV_wglDestroyPbufferARB ;
opengl_funcs . ext . p_wglGetPbufferDCARB = X11DRV_wglGetPbufferDCARB ;
opengl_funcs . ext . p_wglQueryPbufferARB = X11DRV_wglQueryPbufferARB ;
opengl_funcs . ext . p_wglReleasePbufferDCARB = X11DRV_wglReleasePbufferDCARB ;
opengl_funcs . ext . p_wglSetPbufferAttribARB = X11DRV_wglSetPbufferAttribARB ;
}
2006-09-12 11:50:36 +02:00
2012-07-17 00:00:55 +02:00
register_extension ( " WGL_ARB_pixel_format " ) ;
opengl_funcs . ext . p_wglChoosePixelFormatARB = X11DRV_wglChoosePixelFormatARB ;
opengl_funcs . ext . p_wglGetPixelFormatAttribfvARB = X11DRV_wglGetPixelFormatAttribfvARB ;
opengl_funcs . ext . p_wglGetPixelFormatAttribivARB = X11DRV_wglGetPixelFormatAttribivARB ;
2006-09-12 11:50:36 +02:00
2007-07-25 22:32:07 +02:00
/* Support WGL_ARB_render_texture when there's support or pbuffer based emulation */
2018-02-12 16:06:01 +01:00
if ( has_extension ( glxExtensions , " GLX_ARB_render_texture " ) | |
2013-03-31 17:07:57 +02:00
( glxRequireVersion ( 3 ) & & use_render_texture_emulation ) )
2007-07-27 15:01:52 +02:00
{
2012-07-17 00:00:55 +02:00
register_extension ( " WGL_ARB_render_texture " ) ;
opengl_funcs . ext . p_wglBindTexImageARB = X11DRV_wglBindTexImageARB ;
opengl_funcs . ext . p_wglReleaseTexImageARB = X11DRV_wglReleaseTexImageARB ;
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 */
2018-02-12 16:06:01 +01:00
if ( has_extension ( glxExtensions , " GLX_NV_float_buffer " ) )
2012-07-17 00:00:55 +02:00
register_extension ( " WGL_NV_float_buffer " ) ;
2007-07-27 15:01:52 +02:00
/* Again there's no GLX equivalent for this extension, so depend on the required GL extension */
2018-02-12 16:06:01 +01:00
if ( has_extension ( glExtensions , " GL_NV_texture_rectangle " ) )
2012-10-20 09:04:58 +02:00
register_extension ( " WGL_NV_render_texture_rectangle " ) ;
2007-07-27 15:01:52 +02:00
}
2006-09-11 21:28:32 +02:00
/* EXT Extensions */
2006-09-12 11:50:36 +02:00
2012-07-17 00:00:55 +02:00
register_extension ( " WGL_EXT_extensions_string " ) ;
opengl_funcs . ext . p_wglGetExtensionsStringEXT = X11DRV_wglGetExtensionsStringEXT ;
2006-09-12 11:50:36 +02:00
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 . */
2012-07-17 00:00:55 +02:00
register_extension ( " WGL_EXT_swap_control " ) ;
opengl_funcs . ext . p_wglSwapIntervalEXT = X11DRV_wglSwapIntervalEXT ;
opengl_funcs . ext . p_wglGetSwapIntervalEXT = X11DRV_wglGetSwapIntervalEXT ;
2006-12-03 22:40:24 +01:00
2018-02-12 16:06:01 +01:00
if ( has_extension ( glxExtensions , " GLX_EXT_framebuffer_sRGB " ) )
2012-07-17 00:00:55 +02:00
register_extension ( " WGL_EXT_framebuffer_sRGB " ) ;
2008-04-30 00:42:09 +02:00
2018-02-12 16:06:01 +01:00
if ( has_extension ( glxExtensions , " GLX_EXT_fbconfig_packed_float " ) )
2012-07-17 00:00:55 +02:00
register_extension ( " WGL_EXT_pixel_format_packed_float " ) ;
2009-04-20 22:57:19 +02:00
2018-02-12 16:06:01 +01:00
if ( has_extension ( glxExtensions , " GLX_EXT_swap_control " ) )
2013-09-02 06:58:53 +02:00
{
swap_control_method = GLX_SWAP_CONTROL_EXT ;
2018-02-12 16:06:01 +01:00
if ( has_extension ( glxExtensions , " GLX_EXT_swap_control_tear " ) )
2013-09-02 06:58:54 +02:00
{
register_extension ( " WGL_EXT_swap_control_tear " ) ;
has_swap_control_tear = TRUE ;
}
2013-09-02 06:58:53 +02:00
}
2018-02-12 16:06:01 +01:00
else if ( has_extension ( glxExtensions , " GLX_MESA_swap_control " ) )
2013-09-15 04:57:39 +02:00
{
swap_control_method = GLX_SWAP_CONTROL_MESA ;
}
2018-02-12 16:06:01 +01:00
else if ( has_extension ( glxExtensions , " GLX_SGI_swap_control " ) )
2013-09-02 06:58:53 +02:00
{
swap_control_method = GLX_SWAP_CONTROL_SGI ;
}
2011-03-07 21:45:27 +01:00
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. */
2018-02-12 16:06:01 +01:00
if ( has_extension ( glExtensions , " GL_NV_vertex_array_range " ) )
2012-07-17 00:00:55 +02:00
{
register_extension ( " WGL_NV_vertex_array_range " ) ;
opengl_funcs . ext . p_wglAllocateMemoryNV = pglXAllocateMemoryNV ;
opengl_funcs . ext . p_wglFreeMemoryNV = pglXFreeMemoryNV ;
}
2008-04-23 00:15:15 +02:00
2018-02-12 16:06:01 +01:00
if ( has_extension ( glxExtensions , " GLX_OML_swap_method " ) )
2014-11-10 18:56:11 +01:00
has_swap_method = TRUE ;
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 .
*/
2012-07-17 00:00:55 +02:00
register_extension ( " WGL_WINE_pixel_format_passthrough " ) ;
opengl_funcs . ext . p_wglSetPixelFormatWINE = X11DRV_wglSetPixelFormatWINE ;
2016-03-15 16:55:13 +01:00
2018-02-12 16:06:01 +01:00
if ( has_extension ( glxExtensions , " GLX_MESA_query_renderer " ) )
2016-03-15 16:55:13 +01:00
{
register_extension ( " WGL_WINE_query_renderer " ) ;
opengl_funcs . ext . p_wglQueryCurrentRendererIntegerWINE = X11DRV_wglQueryCurrentRendererIntegerWINE ;
opengl_funcs . ext . p_wglQueryCurrentRendererStringWINE = X11DRV_wglQueryCurrentRendererStringWINE ;
opengl_funcs . ext . p_wglQueryRendererIntegerWINE = X11DRV_wglQueryRendererIntegerWINE ;
opengl_funcs . ext . p_wglQueryRendererStringWINE = X11DRV_wglQueryRendererStringWINE ;
}
2006-09-11 21:28:32 +02:00
}
2005-05-06 16:33:02 +02:00
/**
2012-05-08 12:18:54 +02:00
* glxdrv_SwapBuffers
2005-05-06 16:33:02 +02:00
*
* Swap the buffers of this DC
*/
2020-04-23 13:33:20 +02:00
static BOOL WINAPI glxdrv_wglSwapBuffers ( HDC hdc )
2006-06-23 13:13:55 +02:00
{
2012-10-02 21:50:54 +02:00
struct x11drv_escape_flush_gl_drawable escape ;
2012-09-07 21:00:46 +02:00
struct gl_drawable * gl ;
2012-09-07 21:11:55 +02:00
struct wgl_context * ctx = NtCurrentTeb ( ) - > glContext ;
2017-03-23 23:58:10 +01:00
INT64 ust , msc , sbc , target_sbc = 0 ;
2011-03-17 22:51:04 +01:00
2012-09-07 21:11:55 +02:00
TRACE ( " (%p) \n " , hdc ) ;
2007-10-10 17:33:35 +02:00
2012-10-02 21:50:54 +02:00
escape . code = X11DRV_FLUSH_GL_DRAWABLE ;
escape . gl_drawable = 0 ;
2018-03-16 11:08:28 +01:00
escape . flush = ! pglXWaitForSbcOML ;
2012-10-02 21:50:54 +02:00
2012-09-07 22:04:33 +02:00
if ( ! ( gl = get_gl_drawable ( WindowFromDC ( hdc ) , hdc ) ) )
{
SetLastError ( ERROR_INVALID_HANDLE ) ;
return FALSE ;
}
2012-09-07 21:00:46 +02:00
2018-02-12 15:34:28 +01:00
EnterCriticalSection ( & context_section ) ;
2014-04-01 04:46:48 +02:00
if ( gl - > refresh_swap_interval )
{
set_swap_interval ( gl - > drawable , gl - > swap_interval ) ;
gl - > refresh_swap_interval = FALSE ;
}
2018-02-12 15:34:28 +01:00
LeaveCriticalSection ( & context_section ) ;
2014-04-01 04:46:48 +02:00
2012-09-07 22:04:33 +02:00
switch ( gl - > type )
2012-09-07 21:00:46 +02:00
{
2012-09-07 22:04:33 +02:00
case DC_GL_PIXMAP_WIN :
if ( ctx ) sync_context ( ctx ) ;
2012-10-02 21:50:54 +02:00
escape . gl_drawable = gl - > pixmap ;
2012-09-07 22:04:33 +02:00
if ( pglXCopySubBufferMESA ) {
/* (glX)SwapBuffers has an implicit glFlush effect, however
* GLX_MESA_copy_sub_buffer doesn ' t . Make sure GL is flushed before
* copying */
pglFlush ( ) ;
pglXCopySubBufferMESA ( gdi_display , gl - > drawable , 0 , 0 ,
2018-02-09 13:08:04 +01:00
gl - > pixmap_size . cx , gl - > pixmap_size . cy ) ;
2012-09-07 21:00:46 +02:00
break ;
}
2017-03-23 23:58:10 +01:00
if ( pglXSwapBuffersMscOML )
{
pglFlush ( ) ;
target_sbc = pglXSwapBuffersMscOML ( gdi_display , gl - > drawable , 0 , 0 , 0 ) ;
break ;
}
2012-10-02 21:50:54 +02:00
pglXSwapBuffers ( gdi_display , gl - > drawable ) ;
break ;
2019-04-10 21:04:18 +02:00
case DC_GL_WINDOW :
2012-10-02 21:50:54 +02:00
case DC_GL_CHILD_WIN :
2013-10-01 07:29:05 +02:00
if ( ctx ) sync_context ( ctx ) ;
2019-04-10 21:04:18 +02:00
if ( gl - > type = = DC_GL_CHILD_WIN ) escape . gl_drawable = gl - > window ;
2012-09-07 22:04:33 +02:00
/* fall through */
default :
2017-07-12 18:42:29 +02:00
if ( escape . gl_drawable & & pglXSwapBuffersMscOML )
2017-03-23 23:58:10 +01:00
{
pglFlush ( ) ;
target_sbc = pglXSwapBuffersMscOML ( gdi_display , gl - > drawable , 0 , 0 , 0 ) ;
break ;
}
2012-09-07 22:04:33 +02:00
pglXSwapBuffers ( gdi_display , gl - > drawable ) ;
break ;
2012-09-07 21:00:46 +02:00
}
2012-09-07 21:11:55 +02:00
2017-03-23 23:58:10 +01:00
if ( escape . gl_drawable & & pglXWaitForSbcOML )
pglXWaitForSbcOML ( gdi_display , gl - > drawable , target_sbc , & ust , & msc , & sbc ) ;
2012-09-07 22:04:33 +02:00
release_gl_drawable ( gl ) ;
2012-09-07 21:00:46 +02:00
2012-10-02 21:50:54 +02:00
if ( escape . gl_drawable ) ExtEscape ( ctx - > hdc , X11DRV_ESCAPE , sizeof ( escape ) , ( LPSTR ) & escape , 0 , NULL ) ;
2012-09-07 22:04:33 +02:00
return TRUE ;
2000-05-12 22:18:14 +02:00
}
2012-07-18 23:58:41 +02:00
static struct opengl_funcs opengl_funcs =
{
{
glxdrv_wglCopyContext , /* p_wglCopyContext */
glxdrv_wglCreateContext , /* p_wglCreateContext */
glxdrv_wglDeleteContext , /* p_wglDeleteContext */
2012-07-30 21:53:37 +02:00
glxdrv_wglDescribePixelFormat , /* p_wglDescribePixelFormat */
2012-07-18 23:58:41 +02:00
glxdrv_wglGetPixelFormat , /* p_wglGetPixelFormat */
glxdrv_wglGetProcAddress , /* p_wglGetProcAddress */
glxdrv_wglMakeCurrent , /* p_wglMakeCurrent */
2012-07-30 21:53:37 +02:00
glxdrv_wglSetPixelFormat , /* p_wglSetPixelFormat */
2012-07-18 23:58:41 +02:00
glxdrv_wglShareLists , /* p_wglShareLists */
2012-09-07 21:11:55 +02:00
glxdrv_wglSwapBuffers , /* p_wglSwapBuffers */
2012-07-18 23:58:41 +02:00
}
2012-06-28 14:13:24 +02:00
} ;
2012-10-02 22:05:57 +02:00
struct opengl_funcs * get_glx_driver ( UINT version )
2011-07-13 14:56:12 +02:00
{
2012-10-02 22:05:57 +02:00
if ( version ! = WINE_WGL_DRIVER_VERSION )
{
ERR ( " version mismatch, opengl32 wants %u but driver has %u \n " , version , WINE_WGL_DRIVER_VERSION ) ;
return NULL ;
}
if ( has_opengl ( ) ) return & opengl_funcs ;
return NULL ;
2006-08-29 16:56:57 +02:00
}
2012-05-08 12:18:54 +02:00
# else /* no OpenGL includes */
2006-09-11 21:28:32 +02:00
2012-10-02 22:05:57 +02:00
struct opengl_funcs * get_glx_driver ( UINT version )
2006-11-04 22:23:15 +01:00
{
return NULL ;
}
2019-04-10 21:04:18 +02:00
void sync_gl_drawable ( HWND hwnd , BOOL known_child )
2005-09-26 13:04:12 +02:00
{
}
2012-10-10 10:46:16 +02:00
void set_gl_drawable_parent ( HWND hwnd , HWND parent )
{
}
2012-08-31 12:22:03 +02:00
void destroy_gl_drawable ( HWND hwnd )
2007-09-26 07:43:38 +02:00
{
}
2010-09-06 20:51:41 +02:00
# endif /* defined(SONAME_LIBGL) */