From 12dbce5c938a060721a70411d579b4e6eec2c4a6 Mon Sep 17 00:00:00 2001 From: Roderick Colenbrander <thunderbird2k@gmx.net> Date: Mon, 11 Sep 2006 21:28:32 +0200 Subject: [PATCH] winex11.drv: Move WGL extension code to winex11.drv. --- dlls/opengl32/wgl.c | 53 +- dlls/winex11.drv/opengl.c | 1555 ++++++++++++++++++++++++++++- dlls/winex11.drv/winex11.drv.spec | 1 + include/wine/wgl.h | 180 ++++ 4 files changed, 1705 insertions(+), 84 deletions(-) create mode 100644 include/wine/wgl.h diff --git a/dlls/opengl32/wgl.c b/dlls/opengl32/wgl.c index 1a2a51ec8f8..518e99606b5 100644 --- a/dlls/opengl32/wgl.c +++ b/dlls/opengl32/wgl.c @@ -65,6 +65,7 @@ typedef struct wine_wgl_s { HGLRC WINAPI (*p_wglGetCurrentContext)(void); HDC WINAPI (*p_wglGetCurrentDC)(void); HDC WINAPI (*p_wglGetCurrentReadDCARB)(void); + PROC WINAPI (*p_wglGetProcAddress)(LPCSTR lpszProc); BOOL WINAPI (*p_wglMakeCurrent)(HDC hdc, HGLRC hglrc); BOOL WINAPI (*p_wglMakeContextCurrentARB)(HDC hDrawDC, HDC hReadDC, HGLRC hglrc); BOOL WINAPI (*p_wglShareLists)(HGLRC hglrc1, HGLRC hglrc2); @@ -309,11 +310,6 @@ static int compar(const void *elt_a, const void *elt_b) { ((const OpenGL_extension *) elt_b)->name); } -static int wgl_compar(const void *elt_a, const void *elt_b) { - return strcmp(((const WGL_extension *) elt_a)->func_name, - ((const WGL_extension *) elt_b)->func_name); -} - PROC WINAPI wglGetProcAddress(LPCSTR lpszProc) { void *local_func; OpenGL_extension ext; @@ -337,47 +333,10 @@ PROC WINAPI wglGetProcAddress(LPCSTR lpszProc) { ext_ret = (const OpenGL_extension *) bsearch(&ext, extension_registry, extension_registry_size, sizeof(OpenGL_extension), compar); + /* If nothing was found, we are looking for a WGL extension */ if (ext_ret == NULL) { - WGL_extension wgl_ext, *wgl_ext_ret; - - /* Try to find the function in the WGL extensions ... */ - wgl_ext.func_name = (char *) lpszProc; - wgl_ext_ret = (WGL_extension *) bsearch(&wgl_ext, wgl_extension_registry, - wgl_extension_registry_size, sizeof(WGL_extension), wgl_compar); - - if (wgl_ext_ret == NULL) { - /* Some sanity checks :-) */ - ENTER_GL(); - local_func = p_glXGetProcAddressARB( (const GLubyte *) lpszProc); - LEAVE_GL(); - if (local_func != NULL) { - WARN("Extension %s defined in the OpenGL library but NOT in opengl_ext.c...\n", lpszProc); - return NULL; - } - - WARN("Did not find extension %s in either Wine or your OpenGL library.\n", lpszProc); - return NULL; - } else { - void *ret = NULL; - - if (wgl_ext_ret->func_init != NULL) { - const char *err_msg; - if ((err_msg = wgl_ext_ret->func_init(p_glXGetProcAddressARB, - wgl_ext_ret->context)) == NULL) { - ret = wgl_ext_ret->func_address; - } else { - WARN("Error when getting WGL extension '%s' : %s.\n", debugstr_a(lpszProc), err_msg); - return NULL; - } - } else { - ret = wgl_ext_ret->func_address; - } - - if (ret) - TRACE(" returning WGL function (%p)\n", ret); - return ret; - } - } else { + return wine_wgl.p_wglGetProcAddress(lpszProc); + } else { /* We are looking for an OpenGL extension */ const char *glx_name = ext_ret->glx_name ? ext_ret->glx_name : ext_ret->name; ENTER_GL(); local_func = p_glXGetProcAddressARB( (const GLubyte*)glx_name); @@ -1062,6 +1021,7 @@ static BOOL process_attach(void) wine_wgl.p_wglGetCurrentContext = (void *)GetProcAddress(mod, "wglGetCurrentContext"); wine_wgl.p_wglGetCurrentDC = (void *)GetProcAddress(mod, "wglGetCurrentDC"); wine_wgl.p_wglGetCurrentReadDCARB = (void *)GetProcAddress(mod, "wglGetCurrentReadDCARB"); + wine_wgl.p_wglGetProcAddress = (void *)GetProcAddress(mod, "wglGetProcAddress"); wine_wgl.p_wglMakeCurrent = (void *)GetProcAddress(mod, "wglMakeCurrent"); wine_wgl.p_wglMakeContextCurrentARB = (void *)GetProcAddress(mod, "wglMakeContextCurrentARB"); wine_wgl.p_wglShareLists = (void *)GetProcAddress(mod, "wglShareLists"); @@ -1125,7 +1085,6 @@ static BOOL process_attach(void) { /* After context initialize also the list of supported WGL extensions. */ wgl_initialize_glx(default_display, DefaultScreen(default_display), p_glXGetProcAddressARB); - wgl_ext_initialize_extensions(default_display, DefaultScreen(default_display), p_glXGetProcAddressARB, internal_gl_disabled_extensions); } return TRUE; } @@ -1137,8 +1096,6 @@ static void process_detach(void) { glXDestroyContext(default_display, default_cx); - /* Do not leak memory... */ - wgl_ext_finalize_extensions(); HeapFree(GetProcessHeap(), 0, internal_gl_extensions); } diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 989ffcc0c59..8d672e4b448 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -2,7 +2,10 @@ * X11DRV OpenGL functions * * Copyright 2000 Lionel Ulmer + * Copyright 2005 Alex Woods + * Copyright 2005 Raphael Junqueira * Copyright 2006 Roderick Colenbrander + * Copyright 2006 Tomas Carnecky * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -49,6 +52,8 @@ WINE_DECLARE_DEBUG_CHANNEL(opengl); # include <GL/glext.h> #endif +#include "wine/wgl.h" + #undef APIENTRY #undef CALLBACK #undef WINAPI @@ -58,19 +63,76 @@ WINE_DECLARE_DEBUG_CHANNEL(opengl); #define WINAPI __stdcall #define APIENTRY WINAPI + WINE_DECLARE_DEBUG_CHANNEL(fps); typedef struct wine_glcontext { - HDC hdc; - Display *display; - XVisualInfo *vis; - GLXFBConfig fb_conf; - GLXContext ctx; - BOOL do_escape; - struct wine_glcontext *next; - struct wine_glcontext *prev; + HDC hdc; + Display *display; + XVisualInfo *vis; + GLXFBConfig fb_conf; + GLXContext ctx; + BOOL do_escape; + struct wine_glcontext *next; + struct wine_glcontext *prev; } Wine_GLContext; + +typedef struct wine_glpbuffer { + Drawable drawable; + Display* display; + int pixelFormat; + int width; + int height; + int* attribList; + HDC hdc; + + int use_render_texture; + GLuint texture_target; + GLuint texture_bind_target; + GLuint texture; + int texture_level; + HDC prev_hdc; + HGLRC prev_ctx; + HDC render_hdc; + HGLRC render_ctx; +} Wine_GLPBuffer; + +typedef struct wine_glextension { + const char *extName; + struct { + const char *funcName; + void *funcAddress; + } extEntryPoints[8]; + int extNumEntryPoints; +} WineGLExtension; + +struct WineGLInfo { + const char *glVersion; + const char *glExtensions; + + int glxVersion[2]; + + const char *glxServerVersion; + const char *glxServerExtensions; + + const char *glxClientVersion; + const char *glxClientExtensions; + + const char *glxExtensions; + + BOOL glxDirect; + char wglExtensions[4096]; +}; + static Wine_GLContext *context_list; +static struct WineGLInfo WineGLInfo = { 0 }; +static int use_render_texture_emulation = 0; +static int use_render_texture_ati = 0; +static int swap_interval = 1; + +static WineGLExtension *WineGLExtensionList = NULL; +long WineGLExtensionListSize = 0; +void X11DRV_WineGL_LoadExtensions(); static void dump_PIXELFORMATDESCRIPTOR(const PIXELFORMATDESCRIPTOR *ppfd) { TRACE(" - size / version : %d / %d\n", ppfd->nSize, ppfd->nVersion); @@ -128,36 +190,122 @@ static void dump_PIXELFORMATDESCRIPTOR(const PIXELFORMATDESCRIPTOR *ppfd) { #define SONAME_LIBGL "libGL.so" #endif +#define PUSH1(attribs,att) do { attribs[nAttribs++] = (att); } while (0) +#define PUSH2(attribs,att,value) do { attribs[nAttribs++] = (att); attribs[nAttribs++] = (value); } while(0) + #define MAKE_FUNCPTR(f) static typeof(f) * p##f; -MAKE_FUNCPTR(glGetError) +/* GLX 1.0 */ MAKE_FUNCPTR(glXChooseVisual) +MAKE_FUNCPTR(glXCreateContext) +MAKE_FUNCPTR(glXCreateGLXPixmap) +MAKE_FUNCPTR(glXGetCurrentContext) +MAKE_FUNCPTR(glXDestroyContext) +MAKE_FUNCPTR(glXDestroyGLXPixmap) MAKE_FUNCPTR(glXGetConfig) +MAKE_FUNCPTR(glXIsDirect) +MAKE_FUNCPTR(glXMakeCurrent) MAKE_FUNCPTR(glXSwapBuffers) MAKE_FUNCPTR(glXQueryExtension) +MAKE_FUNCPTR(glXQueryVersion) + +/* GLX 1.1 */ +MAKE_FUNCPTR(glXGetClientString) +MAKE_FUNCPTR(glXQueryExtensionsString) MAKE_FUNCPTR(glXQueryServerString) +/* GLX 1.3 */ MAKE_FUNCPTR(glXGetFBConfigs) MAKE_FUNCPTR(glXChooseFBConfig) +MAKE_FUNCPTR(glXCreatePbuffer) +MAKE_FUNCPTR(glXDestroyPbuffer) MAKE_FUNCPTR(glXGetFBConfigAttrib) MAKE_FUNCPTR(glXGetVisualFromFBConfig) -MAKE_FUNCPTR(glXCreateGLXPixmap) -MAKE_FUNCPTR(glXDestroyGLXPixmap) -MAKE_FUNCPTR(glXCreateContext) -MAKE_FUNCPTR(glXDestroyContext) -MAKE_FUNCPTR(glXGetCurrentContext) -MAKE_FUNCPTR(glXGetCurrentReadDrawable) -MAKE_FUNCPTR(glXMakeCurrent) MAKE_FUNCPTR(glXMakeContextCurrent) MAKE_FUNCPTR(glXQueryDrawable) +MAKE_FUNCPTR(glXGetCurrentReadDrawable) +/* GLX Extensions */ +static void* (*pglXGetProcAddressARB)(const GLubyte *); +static BOOL (*pglXBindTexImageARB)(Display *dpy, GLXPbuffer pbuffer, int buffer); +static BOOL (*pglXReleaseTexImageARB)(Display *dpy, GLXPbuffer pbuffer, int buffer); +static BOOL (*pglXDrawableAttribARB)(Display *dpy, GLXDrawable draw, const int *attribList); +static int (*pglXSwapIntervalSGI)(int); + +/* Standard OpenGL */ +MAKE_FUNCPTR(glBindTexture) +MAKE_FUNCPTR(glCopyTexSubImage1D) +MAKE_FUNCPTR(glCopyTexSubImage2D) MAKE_FUNCPTR(glDrawBuffer) +MAKE_FUNCPTR(glGetError) +MAKE_FUNCPTR(glGetIntegerv) +MAKE_FUNCPTR(glGetString) #undef MAKE_FUNCPTR +BOOL X11DRV_WineGL_InitOpenglInfo() +{ + static BOOL infoInitialized = FALSE; + + int screen = DefaultScreen(gdi_display); + Window win = RootWindow(gdi_display, screen); + Visual *visual; + XVisualInfo template; + XVisualInfo *vis; + int num; + GLXContext ctx = NULL; + + if (infoInitialized) + return TRUE; + infoInitialized = TRUE; + + wine_tsx11_lock(); + + visual = DefaultVisual(gdi_display, screen); + template.visualid = XVisualIDFromVisual(visual); + vis = XGetVisualInfo(gdi_display, VisualIDMask, &template, &num); + if (vis) { + /* Create a GLX Context. Without one we can't query GL information */ + ctx = pglXCreateContext(gdi_display, vis, None, GL_TRUE); + } + + if (ctx) { + pglXMakeCurrent(gdi_display, win, ctx); + } else { + ERR(" couldn't initialize OpenGL, expect problems\n"); + return FALSE; + } + + WineGLInfo.glVersion = (const char *) pglGetString(GL_VERSION); + WineGLInfo.glExtensions = (const char *) pglGetString(GL_EXTENSIONS); + + /* Get the common GLX version supported by GLX client and server ( major/minor) */ + pglXQueryVersion(gdi_display, &WineGLInfo.glxVersion[0], &WineGLInfo.glxVersion[1]); + + WineGLInfo.glxServerVersion = pglXQueryServerString(gdi_display, screen, GLX_VERSION); + WineGLInfo.glxServerExtensions = pglXQueryServerString(gdi_display, screen, GLX_EXTENSIONS); + + WineGLInfo.glxClientVersion = pglXGetClientString(gdi_display, GLX_VERSION); + WineGLInfo.glxClientExtensions = pglXGetClientString(gdi_display, GLX_EXTENSIONS); + + WineGLInfo.glxExtensions = pglXQueryExtensionsString(gdi_display, screen); + WineGLInfo.glxDirect = pglXIsDirect(gdi_display, ctx); + + TRACE("GL version : %s.\n", WineGLInfo.glVersion); + TRACE("GLX version : %d.%d.\n", WineGLInfo.glxVersion[0], WineGLInfo.glxVersion[1]); + TRACE("Server GLX version : %s.\n", WineGLInfo.glxServerVersion); + TRACE("Client GLX version : %s.\n", WineGLInfo.glxClientVersion); + TRACE("Direct rendering enabled: %s\n", WineGLInfo.glxDirect ? "True" : "False"); + + wine_tsx11_unlock(); + if(vis) XFree(vis); + if(ctx) pglXDestroyContext(gdi_display, ctx); + return TRUE; +} + static BOOL has_opengl(void) { static int init_done; static void *opengl_handle; - const char *server_glx_version; + const char *glx_extensions; int error_base, event_base; @@ -167,31 +315,56 @@ static BOOL has_opengl(void) opengl_handle = wine_dlopen(SONAME_LIBGL, RTLD_NOW|RTLD_GLOBAL, NULL, 0); if (opengl_handle == NULL) return FALSE; -#define LOAD_FUNCPTR(f) if((p##f = wine_dlsym(RTLD_DEFAULT, #f, NULL, 0)) == NULL) goto sym_not_found; -LOAD_FUNCPTR(glGetError) + pglXGetProcAddressARB = wine_dlsym(opengl_handle, "glXGetProcAddressARB", NULL, 0); + if (pglXGetProcAddressARB == NULL) { + ERR("could not find glXGetProcAddressARB in libGL.\n"); + return FALSE; + } + +#define LOAD_FUNCPTR(f) if((p##f = (void*)pglXGetProcAddressARB((unsigned char*)#f)) == NULL) goto sym_not_found; +/* GLX 1.0 */ LOAD_FUNCPTR(glXChooseVisual) +LOAD_FUNCPTR(glXCreateContext) +LOAD_FUNCPTR(glXCreateGLXPixmap) +LOAD_FUNCPTR(glXGetCurrentContext) +LOAD_FUNCPTR(glXDestroyContext) +LOAD_FUNCPTR(glXDestroyGLXPixmap) LOAD_FUNCPTR(glXGetConfig) +LOAD_FUNCPTR(glXIsDirect) +LOAD_FUNCPTR(glXMakeCurrent) LOAD_FUNCPTR(glXSwapBuffers) LOAD_FUNCPTR(glXQueryExtension) +LOAD_FUNCPTR(glXQueryVersion) + +/* GLX 1.1 */ +LOAD_FUNCPTR(glXGetClientString) +LOAD_FUNCPTR(glXQueryExtensionsString) LOAD_FUNCPTR(glXQueryServerString) -LOAD_FUNCPTR(glXGetFBConfigs) -LOAD_FUNCPTR(glXChooseFBConfig) -LOAD_FUNCPTR(glXGetFBConfigAttrib) -LOAD_FUNCPTR(glXGetVisualFromFBConfig) -LOAD_FUNCPTR(glXCreateGLXPixmap) -LOAD_FUNCPTR(glXDestroyGLXPixmap) -LOAD_FUNCPTR(glXCreateContext) -LOAD_FUNCPTR(glXDestroyContext) -LOAD_FUNCPTR(glXGetCurrentContext) -LOAD_FUNCPTR(glXGetCurrentReadDrawable) -LOAD_FUNCPTR(glXMakeCurrent) +/* GLX 1.3 */ +LOAD_FUNCPTR(glXCreatePbuffer) +LOAD_FUNCPTR(glXDestroyPbuffer) LOAD_FUNCPTR(glXMakeContextCurrent) +LOAD_FUNCPTR(glXGetCurrentReadDrawable) +LOAD_FUNCPTR(glXGetFBConfigs) -/* Standard OpenGL call, need in wglMakeCurrent */ +/* Standard OpenGL calls */ +LOAD_FUNCPTR(glBindTexture) +LOAD_FUNCPTR(glCopyTexSubImage1D) +LOAD_FUNCPTR(glCopyTexSubImage2D) LOAD_FUNCPTR(glDrawBuffer) +LOAD_FUNCPTR(glGetError) +LOAD_FUNCPTR(glGetIntegerv) +LOAD_FUNCPTR(glGetString) #undef LOAD_FUNCPTR + if(!X11DRV_WineGL_InitOpenglInfo()) { + ERR("Intialization of OpenGL info failed, disabling OpenGL!\n"); + wine_dlclose(opengl_handle, NULL, 0); + opengl_handle = NULL; + return FALSE; + } + wine_tsx11_lock(); if (pglXQueryExtension(gdi_display, &error_base, &event_base) == True) { TRACE("GLX is up and running error_base = %d\n", error_base); @@ -200,16 +373,70 @@ LOAD_FUNCPTR(glDrawBuffer) opengl_handle = NULL; } - server_glx_version = pglXQueryServerString(gdi_display, DefaultScreen(gdi_display), GLX_VERSION); - TRACE("Server GLX version: %s\n", server_glx_version); + /* 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. + * + * In general the server GLX information should be used in case of indirect rendering. When direct + * rendering is used, the OpenGL client library is responsible for which GLX calls are available. + * Nvidia's OpenGL drivers are the best in terms of GLX features. At the moment of writing their + * 8762 drivers support 1.3 for the server and 1.4 for the client and they support lots of extensions. + * Unfortunately it is much more complicated for Mesa/DRI-based drivers and ATI's drivers. + * Both sets of drivers report a server version of 1.2 and the client version can be 1.3 or 1.4. + * Further in case of atleast ATI's drivers one crucial extension needed for our pixel format code + * is only available in the list of server extensions and not in the client list. + * + * The versioning checks below try to take into account the comments from above. + */ + + /* Depending on the use of direct or indirect rendering we need either the list of extensions + * exported by the client or by the server. + */ + if(WineGLInfo.glxDirect) + glx_extensions = WineGLInfo.glxClientExtensions; + else + glx_extensions = WineGLInfo.glxServerExtensions; + + /* Based on the default opengl context we decide whether direct or indirect rendering is used. + * In case of indirect rendering we check if the GLX version of the server is 1.2 and else + * the client version is checked. + */ + if ((!WineGLInfo.glxDirect && !strcmp("1.2", WineGLInfo.glxServerVersion)) || + (WineGLInfo.glxDirect && !strcmp("1.2", WineGLInfo.glxClientVersion))) + { + pglXChooseFBConfig = (void*)pglXGetProcAddressARB((const GLubyte *) "glXChooseFBConfig"); + pglXGetFBConfigAttrib = (void*)pglXGetProcAddressARB((const GLubyte *) "glXGetFBConfigAttrib"); + pglXGetVisualFromFBConfig = (void*)pglXGetProcAddressARB((const GLubyte *) "glXGetVisualFromFBConfig"); + } else { + if (NULL != strstr(glx_extensions, "GLX_SGIX_fbconfig")) { + pglXChooseFBConfig = (void*)pglXGetProcAddressARB((const GLubyte *) "glXChooseFBConfigSGIX"); + pglXGetFBConfigAttrib = (void*)pglXGetProcAddressARB((const GLubyte *) "glXGetFBConfigAttribSGIX"); + pglXGetVisualFromFBConfig = (void*)pglXGetProcAddressARB((const GLubyte *) "glXGetVisualFromFBConfigSGIX"); + } else { + ERR(" glx_version as %s and GLX_SGIX_fbconfig extension is unsupported. Expect problems.\n", WineGLInfo.glxClientVersion); + } + } + /* 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 - */ - if (!strcmp("1.2", server_glx_version)) + * enable this function when the Xserver understand GLX 1.3 or newer + */ + if (!strcmp("1.2", WineGLInfo.glxServerVersion)) pglXQueryDrawable = NULL; else pglXQueryDrawable = wine_dlsym(RTLD_DEFAULT, "glXQueryDrawable", NULL, 0); + if (NULL != strstr(glx_extensions, "GLX_ATI_render_texture")) { + pglXBindTexImageARB = (void*)pglXGetProcAddressARB((const GLubyte *) "glXBindTexImageARB"); + pglXReleaseTexImageARB = (void*)pglXGetProcAddressARB((const GLubyte *) "glXReleaseTexImageARB"); + pglXDrawableAttribARB = (void*)pglXGetProcAddressARB((const GLubyte *) "glXDrawableAttribARB"); + } + + X11DRV_WineGL_LoadExtensions(); + wine_tsx11_unlock(); return (opengl_handle != NULL); @@ -260,6 +487,19 @@ inline static Drawable get_drawable( HDC hdc ) return drawable; } +inline static void set_drawable( HDC hdc, Drawable drawable ) +{ + struct x11drv_escape_set_drawable escape; + + escape.code = X11DRV_SET_DRAWABLE; + escape.drawable = drawable; + escape.mode = IncludeInferiors; + escape.org.x = escape.org.y = 0; + escape.drawable_org.x = escape.drawable_org.y = 0; + + ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape, 0, NULL ); +} + /** for use of wglGetCurrentReadDCARB */ inline static HDC get_hdc_from_Drawable(GLXDrawable d) { @@ -324,6 +564,203 @@ static int describeDrawable(Wine_GLContext* ctx, Drawable drawable) { return tmp; } +static int ConvertAttribWGLtoGLX(const int* iWGLAttr, int* oGLXAttr, Wine_GLPBuffer* pbuf) { + int nAttribs = 0; + unsigned cur = 0; + int pop; + int isColor = 0; + int wantColorBits = 0; + int sz_alpha = 0; + + while (0 != iWGLAttr[cur]) { + TRACE("pAttr[%d] = %x\n", cur, iWGLAttr[cur]); + + switch (iWGLAttr[cur]) { + case WGL_COLOR_BITS_ARB: + pop = iWGLAttr[++cur]; + wantColorBits = pop; /** see end */ + break; + case WGL_BLUE_BITS_ARB: + pop = iWGLAttr[++cur]; + PUSH2(oGLXAttr, GLX_BLUE_SIZE, pop); + TRACE("pAttr[%d] = GLX_BLUE_SIZE: %d\n", cur, pop); + break; + case WGL_RED_BITS_ARB: + pop = iWGLAttr[++cur]; + PUSH2(oGLXAttr, GLX_RED_SIZE, pop); + TRACE("pAttr[%d] = GLX_RED_SIZE: %d\n", cur, pop); + break; + case WGL_GREEN_BITS_ARB: + pop = iWGLAttr[++cur]; + PUSH2(oGLXAttr, GLX_GREEN_SIZE, pop); + TRACE("pAttr[%d] = GLX_GREEN_SIZE: %d\n", cur, pop); + break; + case WGL_ALPHA_BITS_ARB: + pop = iWGLAttr[++cur]; + sz_alpha = pop; + PUSH2(oGLXAttr, GLX_ALPHA_SIZE, pop); + TRACE("pAttr[%d] = GLX_ALPHA_SIZE: %d\n", cur, pop); + break; + case WGL_DEPTH_BITS_ARB: + pop = iWGLAttr[++cur]; + PUSH2(oGLXAttr, GLX_DEPTH_SIZE, pop); + TRACE("pAttr[%d] = GLX_DEPTH_SIZE: %d\n", cur, pop); + break; + case WGL_STENCIL_BITS_ARB: + pop = iWGLAttr[++cur]; + PUSH2(oGLXAttr, GLX_STENCIL_SIZE, pop); + TRACE("pAttr[%d] = GLX_STENCIL_SIZE: %d\n", cur, pop); + break; + case WGL_DOUBLE_BUFFER_ARB: + pop = iWGLAttr[++cur]; + PUSH2(oGLXAttr, GLX_DOUBLEBUFFER, pop); + TRACE("pAttr[%d] = GLX_DOUBLEBUFFER: %d\n", cur, pop); + break; + + case WGL_PIXEL_TYPE_ARB: + pop = iWGLAttr[++cur]; + switch (pop) { + case WGL_TYPE_COLORINDEX_ARB: pop = GLX_COLOR_INDEX_BIT; isColor = 1; break ; + case WGL_TYPE_RGBA_ARB: pop = GLX_RGBA_BIT; break ; + case WGL_TYPE_RGBA_FLOAT_ATI: pop = GLX_RGBA_FLOAT_ATI_BIT; break ; + default: + ERR("unexpected PixelType(%x)\n", pop); + pop = 0; + } + PUSH2(oGLXAttr, GLX_RENDER_TYPE, pop); + TRACE("pAttr[%d] = GLX_RENDER_TYPE: %d\n", cur, pop); + break; + + case WGL_SUPPORT_GDI_ARB: + pop = iWGLAttr[++cur]; + PUSH2(oGLXAttr, GLX_X_RENDERABLE, pop); + TRACE("pAttr[%d] = GLX_RENDERABLE: %d\n", cur, pop); + break; + + case WGL_DRAW_TO_BITMAP_ARB: + pop = iWGLAttr[++cur]; + PUSH2(oGLXAttr, GLX_X_RENDERABLE, pop); + TRACE("pAttr[%d] = GLX_RENDERABLE: %d\n", cur, pop); + if (pop) { + PUSH2(oGLXAttr, GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT); + TRACE("pAttr[%d] = GLX_DRAWABLE_TYPE: GLX_PIXMAP_BIT\n", cur); + } + break; + + case WGL_DRAW_TO_WINDOW_ARB: + pop = iWGLAttr[++cur]; + if (pop) { + PUSH2(oGLXAttr, GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT); + TRACE("pAttr[%d] = GLX_DRAWABLE_TYPE: GLX_WINDOW_BIT\n", cur); + } + break; + + case WGL_DRAW_TO_PBUFFER_ARB: + pop = iWGLAttr[++cur]; + PUSH2(oGLXAttr, GLX_X_RENDERABLE, pop); + TRACE("pAttr[%d] = GLX_RENDERABLE: %d\n", cur, pop); + if (pop) { + PUSH2(oGLXAttr, GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT); + TRACE("pAttr[%d] = GLX_DRAWABLE_TYPE: GLX_PBUFFER_BIT\n", cur); + } + break; + + case WGL_ACCELERATION_ARB: + case WGL_SUPPORT_OPENGL_ARB: + pop = iWGLAttr[++cur]; + /** nothing to do, if we are here, supposing support Accelerated OpenGL */ + TRACE("pAttr[%d] = WGL_SUPPORT_OPENGL_ARB: %d\n", cur, pop); + break; + + case WGL_PBUFFER_LARGEST_ARB: + pop = iWGLAttr[++cur]; + PUSH2(oGLXAttr, GLX_LARGEST_PBUFFER, pop); + TRACE("pAttr[%d] = GLX_LARGEST_PBUFFER: %x\n", cur, pop); + break; + + case WGL_SAMPLE_BUFFERS_ARB: + pop = iWGLAttr[++cur]; + PUSH2(oGLXAttr, GLX_SAMPLE_BUFFERS_ARB, pop); + TRACE("pAttr[%d] = GLX_SAMPLE_BUFFERS_ARB: %x\n", cur, pop); + break; + + case WGL_SAMPLES_ARB: + pop = iWGLAttr[++cur]; + PUSH2(oGLXAttr, GLX_SAMPLES_ARB, pop); + TRACE("pAttr[%d] = GLX_SAMPLES_ARB: %x\n", cur, pop); + break; + + case WGL_TEXTURE_FORMAT_ARB: + case WGL_TEXTURE_TARGET_ARB: + case WGL_MIPMAP_TEXTURE_ARB: + TRACE("WGL_render_texture Attributes: %x as %x\n", iWGLAttr[cur], iWGLAttr[cur + 1]); + pop = iWGLAttr[++cur]; + if (NULL == pbuf) { + ERR("trying to use GLX_Pbuffer Attributes without Pbuffer (was %x)\n", iWGLAttr[cur]); + } + if (use_render_texture_ati) { + /** nothing to do here */ + } + else if (!use_render_texture_emulation) { + if (WGL_NO_TEXTURE_ARB != pop) { + ERR("trying to use WGL_render_texture Attributes without support (was %x)\n", iWGLAttr[cur]); + return -1; /** error: don't support it */ + } else { + PUSH2(oGLXAttr, GLX_X_RENDERABLE, pop); + PUSH2(oGLXAttr, GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT); + } + } + break ; + + case WGL_BIND_TO_TEXTURE_RGB_ARB: + case WGL_BIND_TO_TEXTURE_RGBA_ARB: + pop = iWGLAttr[++cur]; + /** cannot be converted, see direct handling on + * - wglGetPixelFormatAttribivARB + * TODO: wglChoosePixelFormat + */ + break ; + + default: + FIXME("unsupported %x WGL Attribute\n", iWGLAttr[cur]); + break; + } + ++cur; + } + + /** + * Trick as WGL_COLOR_BITS_ARB != GLX_BUFFER_SIZE + * WGL_COLOR_BITS_ARB + WGL_ALPHA_BITS_ARB == GLX_BUFFER_SIZE + * + * WGL_COLOR_BITS_ARB + * The number of color bitplanes in each color buffer. For RGBA + * pixel types, it is the size of the color buffer, excluding the + * alpha bitplanes. For color-index pixels, it is the size of the + * color index buffer. + * + * GLX_BUFFER_SIZE + * This attribute defines the number of bits per color buffer. + * For GLX FBConfigs that correspond to a PseudoColor or StaticColor visual, + * this is equal to the depth value reported in the X11 visual. + * For GLX FBConfigs that correspond to TrueColor or DirectColor visual, + * this is the sum of GLX_RED_SIZE, GLX_GREEN_SIZE, GLX_BLUE_SIZE, and GLX_ALPHA_SIZE. + * + */ + if (0 < wantColorBits) { + if (!isColor) { + wantColorBits += sz_alpha; + } + if (32 < wantColorBits) { + ERR("buggy %d GLX_BUFFER_SIZE default to 32\n", wantColorBits); + wantColorBits = 32; + } + PUSH2(oGLXAttr, GLX_BUFFER_SIZE, wantColorBits); + TRACE("pAttr[%d] = WGL_COLOR_BITS_ARB: %d\n", cur, wantColorBits); + } + + return nAttribs; +} + /* 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). @@ -873,6 +1310,33 @@ HDC WINAPI X11DRV_wglGetCurrentReadDCARB(void) return ret; } +/* OpenGL32: wglGetProcAddress */ +PROC X11DRV_wglGetProcAddress(LPCSTR lpszProc) +{ + int i, j; + WineGLExtension *ext; + + int padding = 32 - strlen(lpszProc); + if (padding < 0) + padding = 0; + + TRACE("('%s'):%*s", lpszProc, padding, " "); + for (i = 0; i < WineGLExtensionListSize; ++i) { + ext = &WineGLExtensionList[i]; + for (j = 0; j < ext->extNumEntryPoints; ++j) { + if (strcmp(ext->extEntryPoints[j].funcName, lpszProc) == 0) { + TRACE("(%p) - WineGL\n", ext->extEntryPoints[j].funcAddress); + return ext->extEntryPoints[j].funcAddress; + } + } + } + + ERR("(%s) - not found\n", lpszProc); + + return NULL; +} + + /* OpenGL32 wglMakeCurrent */ BOOL WINAPI X11DRV_wglMakeCurrent(HDC hdc, HGLRC hglrc) { BOOL ret; @@ -1015,6 +1479,1019 @@ void X11DRV_wglGetIntegerv(GLenum pname, GLint* params) { } } +/* WGL_ARB_extensions_string: wglGetExtensionsStringARB */ +static const char * WINAPI X11DRV_wglGetExtensionsStringARB(HDC hdc) { + TRACE("() returning \"%s\"\n", WineGLInfo.wglExtensions); + return WineGLInfo.wglExtensions; +} + +/* WGL_ARB_pbuffer: wglCreatePbufferARB */ +static HPBUFFERARB WINAPI X11DRV_wglCreatePbufferARB(HDC hdc, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList) +{ + Wine_GLPBuffer* object = NULL; + GLXFBConfig* cfgs = NULL; + int nCfgs = 0; + int attribs[256]; + unsigned nAttribs = 0; + int fmt_index = 0; + + TRACE("(%p, %d, %d, %d, %p)\n", hdc, iPixelFormat, iWidth, iHeight, piAttribList); + + if (0 >= iPixelFormat) { + ERR("(%p): unexpected iPixelFormat(%d) <= 0, returns NULL\n", hdc, iPixelFormat); + SetLastError(ERROR_INVALID_PIXEL_FORMAT); + return NULL; /* unexpected error */ + } + + cfgs = pglXGetFBConfigs(gdi_display, DefaultScreen(gdi_display), &nCfgs); + + if (NULL == cfgs || 0 == nCfgs) { + ERR("(%p): Cannot get FB Configs for iPixelFormat(%d), returns NULL\n", hdc, iPixelFormat); + SetLastError(ERROR_INVALID_PIXEL_FORMAT); + return NULL; /* unexpected error */ + } + + /* Convert the WGL pixelformat to a GLX format, if it fails then the format is invalid */ + if(!ConvertPixelFormatWGLtoGLX(gdi_display, iPixelFormat, &fmt_index, &nCfgs)) { + ERR("(%p): unexpected iPixelFormat(%d) > nFormats(%d), returns NULL\n", hdc, iPixelFormat, nCfgs); + SetLastError(ERROR_INVALID_PIXEL_FORMAT); + goto create_failed; /* unexpected error */ + } + + object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(Wine_GLPBuffer)); + if (NULL == object) { + SetLastError(ERROR_NO_SYSTEM_RESOURCES); + goto create_failed; /* unexpected error */ + } + object->hdc = hdc; + object->display = gdi_display; + object->width = iWidth; + object->height = iHeight; + + nAttribs = ConvertAttribWGLtoGLX(piAttribList, attribs, object); + if (-1 == nAttribs) { + WARN("Cannot convert WGL to GLX attributes\n"); + goto create_failed; + } + PUSH2(attribs, GLX_PBUFFER_WIDTH, iWidth); + PUSH2(attribs, GLX_PBUFFER_HEIGHT, iHeight); + while (0 != *piAttribList) { + int attr_v; + switch (*piAttribList) { + case WGL_TEXTURE_FORMAT_ARB: { + ++piAttribList; + attr_v = *piAttribList; + TRACE("WGL_render_texture Attribute: WGL_TEXTURE_FORMAT_ARB as %x\n", attr_v); + if (use_render_texture_ati) { + int type = 0; + switch (attr_v) { + case WGL_NO_TEXTURE_ARB: type = GLX_NO_TEXTURE_ATI; break ; + case WGL_TEXTURE_RGB_ARB: type = GLX_TEXTURE_RGB_ATI; break ; + case WGL_TEXTURE_RGBA_ARB: type = GLX_TEXTURE_RGBA_ATI; break ; + default: + SetLastError(ERROR_INVALID_DATA); + goto create_failed; + } + object->use_render_texture = 1; + PUSH2(attribs, GLX_TEXTURE_FORMAT_ATI, type); + } else { + if (WGL_NO_TEXTURE_ARB == attr_v) { + object->use_render_texture = 0; + } else { + if (!use_render_texture_emulation) { + SetLastError(ERROR_INVALID_DATA); + goto create_failed; + } + switch (attr_v) { + case WGL_TEXTURE_RGB_ARB: + object->use_render_texture = GL_RGB; + break; + case WGL_TEXTURE_RGBA_ARB: + object->use_render_texture = GL_RGBA; + break; + default: + SetLastError(ERROR_INVALID_DATA); + goto create_failed; + } + } + } + break; + } + + case WGL_TEXTURE_TARGET_ARB: { + ++piAttribList; + attr_v = *piAttribList; + TRACE("WGL_render_texture Attribute: WGL_TEXTURE_TARGET_ARB as %x\n", attr_v); + if (use_render_texture_ati) { + int type = 0; + switch (attr_v) { + case WGL_NO_TEXTURE_ARB: type = GLX_NO_TEXTURE_ATI; break ; + case WGL_TEXTURE_CUBE_MAP_ARB: type = GLX_TEXTURE_CUBE_MAP_ATI; break ; + case WGL_TEXTURE_1D_ARB: type = GLX_TEXTURE_1D_ATI; break ; + case WGL_TEXTURE_2D_ARB: type = GLX_TEXTURE_2D_ATI; break ; + default: + SetLastError(ERROR_INVALID_DATA); + goto create_failed; + } + PUSH2(attribs, GLX_TEXTURE_TARGET_ATI, type); + } else { + if (WGL_NO_TEXTURE_ARB == attr_v) { + object->texture_target = 0; + } else { + if (!use_render_texture_emulation) { + SetLastError(ERROR_INVALID_DATA); + goto create_failed; + } + switch (attr_v) { + case WGL_TEXTURE_CUBE_MAP_ARB: { + if (iWidth != iHeight) { + SetLastError(ERROR_INVALID_DATA); + goto create_failed; + } + object->texture_target = GL_TEXTURE_CUBE_MAP; + object->texture_bind_target = GL_TEXTURE_CUBE_MAP; + break; + } + case WGL_TEXTURE_1D_ARB: { + if (1 != iHeight) { + SetLastError(ERROR_INVALID_DATA); + goto create_failed; + } + object->texture_target = GL_TEXTURE_1D; + object->texture_bind_target = GL_TEXTURE_1D; + break; + } + case WGL_TEXTURE_2D_ARB: { + object->texture_target = GL_TEXTURE_2D; + object->texture_bind_target = GL_TEXTURE_2D; + break; + } + default: + SetLastError(ERROR_INVALID_DATA); + goto create_failed; + } + } + } + break; + } + + case WGL_MIPMAP_TEXTURE_ARB: { + ++piAttribList; + attr_v = *piAttribList; + TRACE("WGL_render_texture Attribute: WGL_MIPMAP_TEXTURE_ARB as %x\n", attr_v); + if (use_render_texture_ati) { + PUSH2(attribs, GLX_MIPMAP_TEXTURE_ATI, attr_v); + } else { + if (!use_render_texture_emulation) { + SetLastError(ERROR_INVALID_DATA); + goto create_failed; + } + } + break; + } + } + ++piAttribList; + } + + PUSH1(attribs, None); + object->drawable = pglXCreatePbuffer(gdi_display, cfgs[fmt_index], attribs); + TRACE("new Pbuffer drawable as %p\n", (void*) object->drawable); + if (!object->drawable) { + SetLastError(ERROR_NO_SYSTEM_RESOURCES); + goto create_failed; /* unexpected error */ + } + TRACE("->(%p)\n", object); + + /** free list */ + XFree(cfgs); + return (HPBUFFERARB) object; + +create_failed: + if (NULL != cfgs) XFree(cfgs); + HeapFree(GetProcessHeap(), 0, object); + TRACE("->(FAILED)\n"); + return (HPBUFFERARB) NULL; +} + +/* WGL_ARB_pbuffer: wglDestroyPbufferARB */ +static GLboolean WINAPI X11DRV_wglDestroyPbufferARB(HPBUFFERARB hPbuffer) +{ + Wine_GLPBuffer* object = (Wine_GLPBuffer*) hPbuffer; + TRACE("(%p)\n", hPbuffer); + if (NULL == object) { + SetLastError(ERROR_INVALID_HANDLE); + return GL_FALSE; + } + pglXDestroyPbuffer(object->display, object->drawable); + HeapFree(GetProcessHeap(), 0, object); + return GL_TRUE; +} + +/* WGL_ARB_pbuffer: wglGetPbufferDCARB */ +static HDC WINAPI X11DRV_wglGetPbufferDCARB(HPBUFFERARB hPbuffer) +{ + Wine_GLPBuffer* object = (Wine_GLPBuffer*) hPbuffer; + HDC hDC; + if (NULL == object) { + SetLastError(ERROR_INVALID_HANDLE); + return NULL; + } + hDC = CreateCompatibleDC(object->hdc); + + /* The function wglGetPbufferDCARB returns a DC to which the pbuffer can be connected. + * We only support one onscreen rendering format (the one from the main visual), so use that. */ + SetPixelFormat(hDC, 1, NULL); + set_drawable(hDC, object->drawable); /* works ?? */ + TRACE("(%p)->(%p)\n", hPbuffer, hDC); + return hDC; +} + +/* WGL_ARB_pbuffer: wglQueryPbufferARB */ +static GLboolean WINAPI X11DRV_wglQueryPbufferARB(HPBUFFERARB hPbuffer, int iAttribute, int *piValue) +{ + Wine_GLPBuffer* object = (Wine_GLPBuffer*) hPbuffer; + TRACE("(%p, 0x%x, %p)\n", hPbuffer, iAttribute, piValue); + if (NULL == object) { + SetLastError(ERROR_INVALID_HANDLE); + return GL_FALSE; + } + switch (iAttribute) { + case WGL_PBUFFER_WIDTH_ARB: + pglXQueryDrawable(object->display, object->drawable, GLX_WIDTH, (unsigned int*) piValue); + break; + case WGL_PBUFFER_HEIGHT_ARB: + pglXQueryDrawable(object->display, object->drawable, GLX_HEIGHT, (unsigned int*) piValue); + break; + + case WGL_PBUFFER_LOST_ARB: + FIXME("unsupported WGL_PBUFFER_LOST_ARB (need glXSelectEvent/GLX_DAMAGED work)\n"); + break; + + case WGL_TEXTURE_FORMAT_ARB: + if (use_render_texture_ati) { + unsigned int tmp; + int type = WGL_NO_TEXTURE_ARB; + pglXQueryDrawable(object->display, object->drawable, GLX_TEXTURE_FORMAT_ATI, &tmp); + switch (tmp) { + case GLX_NO_TEXTURE_ATI: type = WGL_NO_TEXTURE_ARB; break ; + case GLX_TEXTURE_RGB_ATI: type = WGL_TEXTURE_RGB_ARB; break ; + case GLX_TEXTURE_RGBA_ATI: type = WGL_TEXTURE_RGBA_ARB; break ; + } + *piValue = type; + } else { + if (!object->use_render_texture) { + *piValue = WGL_NO_TEXTURE_ARB; + } else { + if (!use_render_texture_emulation) { + SetLastError(ERROR_INVALID_HANDLE); + return GL_FALSE; + } + if (GL_RGBA == object->use_render_texture) { + *piValue = WGL_TEXTURE_RGBA_ARB; + } else { + *piValue = WGL_TEXTURE_RGB_ARB; + } + } + } + break; + + case WGL_TEXTURE_TARGET_ARB: + if (use_render_texture_ati) { + unsigned int tmp; + int type = WGL_NO_TEXTURE_ARB; + pglXQueryDrawable(object->display, object->drawable, GLX_TEXTURE_TARGET_ATI, &tmp); + switch (tmp) { + case GLX_NO_TEXTURE_ATI: type = WGL_NO_TEXTURE_ARB; break ; + case GLX_TEXTURE_CUBE_MAP_ATI: type = WGL_TEXTURE_CUBE_MAP_ARB; break ; + case GLX_TEXTURE_1D_ATI: type = WGL_TEXTURE_1D_ARB; break ; + case GLX_TEXTURE_2D_ATI: type = WGL_TEXTURE_2D_ARB; break ; + } + *piValue = type; + } else { + if (!object->texture_target) { + *piValue = WGL_NO_TEXTURE_ARB; + } else { + if (!use_render_texture_emulation) { + SetLastError(ERROR_INVALID_DATA); + return GL_FALSE; + } + switch (object->texture_target) { + case GL_TEXTURE_1D: *piValue = WGL_TEXTURE_CUBE_MAP_ARB; break; + case GL_TEXTURE_2D: *piValue = WGL_TEXTURE_1D_ARB; break; + case GL_TEXTURE_CUBE_MAP: *piValue = WGL_TEXTURE_2D_ARB; break; + } + } + } + break; + + case WGL_MIPMAP_TEXTURE_ARB: + if (use_render_texture_ati) { + pglXQueryDrawable(object->display, object->drawable, GLX_MIPMAP_TEXTURE_ATI, (unsigned int*) piValue); + } else { + *piValue = GL_FALSE; /** don't support that */ + FIXME("unsupported WGL_ARB_render_texture attribute query for 0x%x\n", iAttribute); + } + break; + + default: + FIXME("unexpected attribute %x\n", iAttribute); + break; + } + + return GL_TRUE; +} + +/* WGL_ARB_pbuffer: wglReleasePbufferDCARB */ +static int WINAPI X11DRV_wglReleasePbufferDCARB(HPBUFFERARB hPbuffer, HDC hdc) +{ + TRACE("(%p, %p)\n", hPbuffer, hdc); + DeleteDC(hdc); + return 0; +} + +/* WGL_ARB_pbuffer: wglSetPbufferAttribARB */ +static GLboolean WINAPI X11DRV_wglSetPbufferAttribARB(HPBUFFERARB hPbuffer, const int *piAttribList) +{ + Wine_GLPBuffer* object = (Wine_GLPBuffer*) hPbuffer; + WARN("(%p, %p): alpha-testing, report any problem\n", hPbuffer, piAttribList); + if (NULL == object) { + SetLastError(ERROR_INVALID_HANDLE); + return GL_FALSE; + } + if (!object->use_render_texture) { + SetLastError(ERROR_INVALID_HANDLE); + return GL_FALSE; + } + if (!use_render_texture_ati && 1 == use_render_texture_emulation) { + return GL_TRUE; + } + if (NULL != pglXDrawableAttribARB) { + if (use_render_texture_ati) { + FIXME("Need conversion for GLX_ATI_render_texture\n"); + } + return pglXDrawableAttribARB(object->display, object->drawable, piAttribList); + } + return GL_FALSE; +} + +/* WGL_ARB_pixel_format: wglChoosePixelFormatARB */ +GLboolean WINAPI X11DRV_wglChoosePixelFormatARB(HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats) +{ + int gl_test = 0; + int attribs[256]; + int nAttribs = 0; + GLboolean res = FALSE; + + /* We need the visualid to check if the format is suitable */ + VisualID visualid = XVisualIDFromVisual(visual); + + GLXFBConfig* cfgs = NULL; + int nCfgs = 0; + UINT it; + int fmt_id; + + GLXFBConfig* cfgs_fmt = NULL; + int nCfgs_fmt = 0; + UINT it_fmt; + int tmp_fmt_id; + int tmp_vis_id; + + int pfmt_it = 0; + int offscreen_index = 1; /* Start at one because we allways have a main visual at iPixelFormat=1 */ + + 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); + + /* 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; + } + + /* Get a list of all FB configurations */ + cfgs_fmt = pglXGetFBConfigs(gdi_display, DefaultScreen(gdi_display), &nCfgs_fmt); + if (NULL == cfgs_fmt) { + ERR("Failed to get All FB Configs\n"); + XFree(cfgs); + return GL_FALSE; + } + + /* Loop through all matching formats and check if they are suitable. + * Note that this function should at max return nMaxFormats different formats */ + for (it = 0; pfmt_it < nMaxFormats && it < nCfgs; ++it) { + gl_test = pglXGetFBConfigAttrib(gdi_display, cfgs[it], GLX_FBCONFIG_ID, &fmt_id); + if (gl_test) { + ERR("Failed to retrieve FBCONFIG_ID from GLXFBConfig, expect problems.\n"); + continue; + } + + gl_test = pglXGetFBConfigAttrib(gdi_display, cfgs[it], GLX_VISUAL_ID, &tmp_vis_id); + if (gl_test) { + ERR("Failed to retrieve VISUAL_ID from GLXFBConfig, expect problems.\n"); + continue; + } + + /* When the visualid of the GLXFBConfig matches the one of the main visual we have found our + * only supported onscreen rendering format. This format has a WGL index of 1. */ + if(tmp_vis_id == visualid) { + piFormats[pfmt_it] = 1; + ++pfmt_it; + res = GL_TRUE; + TRACE("Found compatible GLXFBConfig 0x%x with WGL index 1\n", fmt_id); + continue; + } + /* Only continue with this loop for offscreen rendering formats (visualid = 0) */ + else if(tmp_vis_id != 0) { + TRACE("Discarded GLXFBConfig %0x with VisualID %x because the visualid is not the same as our main visual (%lx)\n", fmt_id, tmp_vis_id, visualid); + continue; + } + + /* Find the index of the found format in the whole format table */ + for (it_fmt = 0; it_fmt < nCfgs_fmt; ++it_fmt) { + gl_test = pglXGetFBConfigAttrib(gdi_display, cfgs_fmt[it_fmt], GLX_FBCONFIG_ID, &tmp_fmt_id); + if (gl_test) { + ERR("Failed to retrieve FBCONFIG_ID from GLXFBConfig, expect problems.\n"); + continue; + } + gl_test = pglXGetFBConfigAttrib(gdi_display, cfgs[it], GLX_VISUAL_ID, &tmp_vis_id); + if (gl_test) { + ERR("Failed to retrieve VISUAL_ID from GLXFBConfig, expect problems.\n"); + continue; + } + /* The format of Wine's main visual is stored at index 1 of our WGL format table. + * At higher indices we store offscreen rendering formats (visualid=0). Below we calculate + * the index of the offscreen format. We do this by counting the number of offscreen formats + * which we see upto reaching our target format. */ + if(tmp_vis_id == 0) + offscreen_index++; + + /* We have found the format in the table (note the format is offscreen) */ + if (fmt_id == tmp_fmt_id) { + int tmp; + + piFormats[pfmt_it] = offscreen_index + 1; /* Add 1 to get a one-based index */ + ++pfmt_it; + pglXGetFBConfigAttrib(gdi_display, cfgs_fmt[it_fmt], GLX_ALPHA_SIZE, &tmp); + TRACE("ALPHA_SIZE of FBCONFIG_ID(%d/%d) found as '%d'\n", it_fmt + 1, nCfgs_fmt, tmp); + break; + } + } + if (it_fmt == nCfgs_fmt) { + ERR("Failed to get valid fmt for %d. Try next.\n", it); + continue; + } + TRACE("at %d/%d found FBCONFIG_ID(%d/%d)\n", it + 1, nCfgs, piFormats[it], nCfgs_fmt); + } + + *nNumFormats = pfmt_it; + /** free list */ + XFree(cfgs); + XFree(cfgs_fmt); + return GL_TRUE; +} + +/* WGL_ARB_pixel_format: wglGetPixelFormatAttribfvARB */ +GLboolean WINAPI X11DRV_wglGetPixelFormatAttribfvARB(HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues) +{ + FIXME("(%p, %d, %d, %d, %p, %p): stub\n", hdc, iPixelFormat, iLayerPlane, nAttributes, piAttributes, pfValues); + return GL_FALSE; +} + +/* WGL_ARB_pixel_format: wglGetPixelFormatAttribivARB */ +GLboolean WINAPI X11DRV_wglGetPixelFormatAttribivARB(HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues) +{ + UINT i; + GLXFBConfig* cfgs = NULL; + GLXFBConfig curCfg = NULL; + int nCfgs = 0; + int hTest; + int tmp; + int curGLXAttr = 0; + int nWGLFormats = 0; + int fmt_index = 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; + } + + cfgs = pglXGetFBConfigs(gdi_display, DefaultScreen(gdi_display), &nCfgs); + if (NULL == cfgs) { + ERR("no FB Configs found for display(%p)\n", gdi_display); + return GL_FALSE; + } + + /* Convert the WGL pixelformat to a GLX one, if this fails then most likely the iPixelFormat isn't supoprted. + * We don't have to fail yet as a program can specify an invaled iPixelFormat (lets say 0) if it wants to query + * the number of supported WGL formats. Whether the iPixelFormat is valid is handled in the for-loop below. */ + if(!ConvertPixelFormatWGLtoGLX(gdi_display, iPixelFormat, &fmt_index, &nWGLFormats)) { + ERR("Unable to convert iPixelFormat %d to a GLX one, expect problems!\n", iPixelFormat); + } + + for (i = 0; i < nAttributes; ++i) { + const int curWGLAttr = piAttributes[i]; + TRACE("pAttr[%d] = %x\n", i, curWGLAttr); + + switch (curWGLAttr) { + case WGL_NUMBER_PIXEL_FORMATS_ARB: + piValues[i] = nWGLFormats; + continue; + + case WGL_SUPPORT_OPENGL_ARB: + piValues[i] = GL_TRUE; + continue; + + case WGL_ACCELERATION_ARB: + curGLXAttr = GLX_CONFIG_CAVEAT; + + if (nCfgs < iPixelFormat || 0 >= iPixelFormat) goto pix_error; + curCfg = cfgs[iPixelFormat - 1]; + + hTest = pglXGetFBConfigAttrib(gdi_display, curCfg, curGLXAttr, &tmp); + if (hTest) goto get_error; + switch (tmp) { + case GLX_NONE: piValues[i] = WGL_FULL_ACCELERATION_ARB; break; + case GLX_SLOW_CONFIG: piValues[i] = WGL_NO_ACCELERATION_ARB; break; + case GLX_NON_CONFORMANT_CONFIG: piValues[i] = WGL_FULL_ACCELERATION_ARB; break; + default: + ERR("unexpected Config Caveat(%x)\n", tmp); + piValues[i] = WGL_NO_ACCELERATION_ARB; + } + continue; + + case WGL_TRANSPARENT_ARB: + curGLXAttr = GLX_TRANSPARENT_TYPE; + /* Check if the format is supported by checking if iPixelFormat isn't larger than the max number of + * supported WGLFormats and also check if the GLX fmt_index is valid. */ + if((iPixelFormat > nWGLFormats) || (fmt_index > nCfgs)) goto pix_error; + curCfg = cfgs[fmt_index]; + hTest = pglXGetFBConfigAttrib(gdi_display, curCfg, curGLXAttr, &tmp); + if (hTest) goto get_error; + piValues[i] = GL_FALSE; + if (GLX_NONE != tmp) piValues[i] = GL_TRUE; + continue; + + case WGL_PIXEL_TYPE_ARB: + curGLXAttr = GLX_RENDER_TYPE; + /* Check if the format is supported by checking if iPixelFormat isn't larger than the max number of + * supported WGLFormats and also check if the GLX fmt_index is valid. */ + if((iPixelFormat > nWGLFormats) || (fmt_index > nCfgs)) goto pix_error; + curCfg = cfgs[fmt_index]; + hTest = pglXGetFBConfigAttrib(gdi_display, curCfg, curGLXAttr, &tmp); + 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; } + else { + ERR("unexpected RenderType(%x)\n", tmp); + piValues[i] = WGL_TYPE_RGBA_ARB; + } + continue; + + case WGL_COLOR_BITS_ARB: + /** see ConvertAttribWGLtoGLX for explain */ + /* Check if the format is supported by checking if iPixelFormat isn't larger than the max number of + * supported WGLFormats and also check if the GLX fmt_index is valid. */ + if((iPixelFormat > nWGLFormats) || (fmt_index > nCfgs)) goto pix_error; + curCfg = cfgs[fmt_index]; + hTest = pglXGetFBConfigAttrib(gdi_display, curCfg, GLX_BUFFER_SIZE, piValues + i); + if (hTest) goto get_error; + TRACE("WGL_COLOR_BITS_ARB: GLX_BUFFER_SIZE = %d\n", piValues[i]); + hTest = pglXGetFBConfigAttrib(gdi_display, curCfg, GLX_ALPHA_SIZE, &tmp); + if (hTest) goto get_error; + TRACE("WGL_COLOR_BITS_ARB: GLX_ALPHA_SIZE = %d\n", tmp); + piValues[i] = piValues[i] - tmp; + continue; + + case WGL_BIND_TO_TEXTURE_RGB_ARB: + if (use_render_texture_ati) { + curGLXAttr = GLX_BIND_TO_TEXTURE_RGB_ATI; + break; + } + case WGL_BIND_TO_TEXTURE_RGBA_ARB: + if (use_render_texture_ati) { + curGLXAttr = GLX_BIND_TO_TEXTURE_RGBA_ATI; + break; + } + if (!use_render_texture_emulation) { + piValues[i] = GL_FALSE; + continue; + } + curGLXAttr = GLX_RENDER_TYPE; + /* Check if the format is supported by checking if iPixelFormat isn't larger than the max number of + * supported WGLFormats and also check if the GLX fmt_index is valid. */ + if((iPixelFormat > nWGLFormats) || (fmt_index > nCfgs)) goto pix_error; + curCfg = cfgs[fmt_index]; + hTest = pglXGetFBConfigAttrib(gdi_display, curCfg, curGLXAttr, &tmp); + if (hTest) goto get_error; + if (GLX_COLOR_INDEX_BIT == tmp) { + piValues[i] = GL_FALSE; + continue; + } + hTest = pglXGetFBConfigAttrib(gdi_display, curCfg, GLX_DRAWABLE_TYPE, &tmp); + if (hTest) goto get_error; + piValues[i] = (tmp & GLX_PBUFFER_BIT) ? GL_TRUE : GL_FALSE; + 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; + + case WGL_SUPPORT_GDI_ARB: + case WGL_DRAW_TO_WINDOW_ARB: + case WGL_DRAW_TO_BITMAP_ARB: + case WGL_DRAW_TO_PBUFFER_ARB: + curGLXAttr = GLX_X_RENDERABLE; + break; + + 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; + + default: + FIXME("unsupported %x WGL Attribute\n", curWGLAttr); + } + + if (0 != curGLXAttr) { + /* Check if the format is supported by checking if iPixelFormat isn't larger than the max number of + * supported WGLFormats and also check if the GLX fmt_index is valid. */ + if((iPixelFormat > 0) && ((iPixelFormat > nWGLFormats) || (fmt_index > nCfgs))) goto pix_error; + curCfg = cfgs[fmt_index]; + hTest = pglXGetFBConfigAttrib(gdi_display, curCfg, curGLXAttr, piValues + i); + if (hTest) goto get_error; + } else { + piValues[i] = GL_FALSE; + } + } + return GL_TRUE; + +get_error: + ERR("(%p): unexpected failure on GetFBConfigAttrib(%x) returns FALSE\n", hdc, curGLXAttr); + XFree(cfgs); + return GL_FALSE; + +pix_error: + ERR("(%p): unexpected iPixelFormat(%d) vs nFormats(%d), returns FALSE\n", hdc, iPixelFormat, nCfgs); + XFree(cfgs); + return GL_FALSE; +} + +/* WGL_ARB_render_texture: wglBindTexImageARB */ +static GLboolean WINAPI X11DRV_wglBindTexImageARB(HPBUFFERARB hPbuffer, int iBuffer) +{ + Wine_GLPBuffer* object = (Wine_GLPBuffer*) hPbuffer; + TRACE("(%p, %d)\n", hPbuffer, iBuffer); + if (NULL == object) { + SetLastError(ERROR_INVALID_HANDLE); + return GL_FALSE; + } + if (!object->use_render_texture) { + SetLastError(ERROR_INVALID_HANDLE); + return GL_FALSE; + } + if (!use_render_texture_ati && 1 == use_render_texture_emulation) { + int do_init = 0; + GLint prev_binded_tex; + pglGetIntegerv(object->texture_target, &prev_binded_tex); + if (NULL == object->render_ctx) { + object->render_hdc = X11DRV_wglGetPbufferDCARB(hPbuffer); + object->render_ctx = X11DRV_wglCreateContext(object->render_hdc); + do_init = 1; + } + object->prev_hdc = X11DRV_wglGetCurrentDC(); + object->prev_ctx = X11DRV_wglGetCurrentContext(); + X11DRV_wglMakeCurrent(object->render_hdc, object->render_ctx); + /* + if (do_init) { + glBindTexture(object->texture_target, object->texture); + if (GL_RGBA == object->use_render_texture) { + glTexImage2D(object->texture_target, 0, GL_RGBA8, object->width, object->height, 0, GL_RGBA, GL_FLOAT, NULL); + } else { + glTexImage2D(object->texture_target, 0, GL_RGB8, object->width, object->height, 0, GL_RGB, GL_FLOAT, NULL); + } + } + */ + object->texture = prev_binded_tex; + return GL_TRUE; + } + if (NULL != pglXBindTexImageARB) { + return pglXBindTexImageARB(object->display, object->drawable, iBuffer); + } + return GL_FALSE; +} + +/* WGL_ARB_render_texture: wglReleaseTexImageARB */ +static GLboolean WINAPI X11DRV_wglReleaseTexImageARB(HPBUFFERARB hPbuffer, int iBuffer) +{ + Wine_GLPBuffer* object = (Wine_GLPBuffer*) hPbuffer; + TRACE("(%p, %d)\n", hPbuffer, iBuffer); + if (NULL == object) { + SetLastError(ERROR_INVALID_HANDLE); + return GL_FALSE; + } + if (!object->use_render_texture) { + SetLastError(ERROR_INVALID_HANDLE); + return GL_FALSE; + } + if (!use_render_texture_ati && 1 == use_render_texture_emulation) { + /* + GLint prev_binded_tex; + glGetIntegerv(object->texture_target, &prev_binded_tex); + if (GL_TEXTURE_1D == object->texture_target) { + glCopyTexSubImage1D(object->texture_target, object->texture_level, 0, 0, 0, object->width); + } else { + glCopyTexSubImage2D(object->texture_target, object->texture_level, 0, 0, 0, 0, object->width, object->height); + } + glBindTexture(object->texture_target, prev_binded_tex); + SwapBuffers(object->render_hdc); + */ + pglBindTexture(object->texture_target, object->texture); + if (GL_TEXTURE_1D == object->texture_target) { + pglCopyTexSubImage1D(object->texture_target, object->texture_level, 0, 0, 0, object->width); + } else { + pglCopyTexSubImage2D(object->texture_target, object->texture_level, 0, 0, 0, 0, object->width, object->height); + } + + X11DRV_wglMakeCurrent(object->prev_hdc, object->prev_ctx); + return GL_TRUE; + } + if (NULL != pglXReleaseTexImageARB) { + return pglXReleaseTexImageARB(object->display, object->drawable, iBuffer); + } + return GL_FALSE; +} + +/* WGL_EXT_extensions_string: wglGetExtensionsStringEXT */ +const char * WINAPI X11DRV_wglGetExtensionsStringEXT(void) { + TRACE("() returning \"%s\"\n", WineGLInfo.wglExtensions); + return WineGLInfo.wglExtensions; +} + +/* WGL_EXT_swap_control: wglGetSwapIntervalEXT */ +int WINAPI X11DRV_wglGetSwapIntervalEXT(VOID) { + FIXME("(),stub!\n"); + return swap_interval; +} + +/* WGL_EXT_swap_control: wglSwapIntervalEXT */ +BOOL WINAPI X11DRV_wglSwapIntervalEXT(int interval) { + TRACE("(%d)\n", interval); + swap_interval = interval; + if (NULL != pglXSwapIntervalSGI) { + return 0 == pglXSwapIntervalSGI(interval); + } + WARN("(): GLX_SGI_swap_control extension seems not supported\n"); + return TRUE; +} + +/* Check if the supported GLX version matches requiredVersion */ +static BOOL glxRequireVersion(int requiredVersion) +{ + /* Both requiredVersion and glXVersion[1] contains the minor GLX version */ + if(requiredVersion <= WineGLInfo.glxVersion[1]) + return TRUE; + + return FALSE; +} + +static BOOL glxRequireExtension(const char *requiredExtension) +{ + if (strstr(WineGLInfo.glxClientExtensions, requiredExtension) == NULL) { + return FALSE; + } + + return TRUE; +} + +BOOL X11DRV_WineGL_RegisterExtension(const WineGLExtension * ext) +{ + int i; + + if (WineGLExtensionListSize == 0) + { + WineGLExtensionList = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WineGLExtension)); + } + else + { + WineGLExtensionList = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, WineGLExtensionList, (WineGLExtensionListSize + 1) * sizeof(WineGLExtension)); + } + + WineGLExtensionList[WineGLExtensionListSize] = *ext; + ++WineGLExtensionListSize; + + strcat(WineGLInfo.wglExtensions, " "); + strcat(WineGLInfo.wglExtensions, ext->extName); + + TRACE("'%s'\n", ext->extName); + + for (i = 0; i < ext->extNumEntryPoints; ++i) + TRACE(" - '%s'\n", ext->extEntryPoints[i].funcName); + + return TRUE; +} + +static const WineGLExtension WGL_ARB_extensions_string = +{ + "WGL_ARB_extensions_string", + { + { "wglGetExtensionsStringARB", X11DRV_wglGetExtensionsStringARB }, + } +}; + +/* WGL_ARB_extensions_string */ +static void WineGLExtension__WGL_ARB_extensions_string() +{ + X11DRV_WineGL_RegisterExtension(&WGL_ARB_extensions_string); +} + +static const WineGLExtension WGL_ARB_make_current_read = +{ + "WGL_ARB_make_current_read", + { + { "wglGetCurrentReadDCARB", X11DRV_wglGetCurrentReadDCARB }, + { "wglMakeContextCurrentARB", X11DRV_wglMakeContextCurrentARB }, + } +}; + +/* WGL_ARB_make_current_read */ +static void WineGLExtension__WGL_ARB_make_current_read() +{ + if (glxRequireVersion(3) == FALSE) + return; + + X11DRV_WineGL_RegisterExtension(&WGL_ARB_make_current_read); +} + +static const WineGLExtension WGL_ARB_multisample = +{ + "WGL_ARB_multisample", +}; + +/* WGL_ARB_multisample */ +static void WineGLExtension__WGL_ARB_multisample() +{ + if (glxRequireExtension("GLX_ARB_multisample") == FALSE) + return; + + X11DRV_WineGL_RegisterExtension(&WGL_ARB_multisample); +} + +static const WineGLExtension WGL_ARB_pbuffer = +{ + "WGL_ARB_pbuffer", + { + { "wglCreatePbufferARB", X11DRV_wglCreatePbufferARB }, + { "wglDestroyPbufferARB", X11DRV_wglDestroyPbufferARB }, + { "wglGetPbufferDCARB", X11DRV_wglGetPbufferDCARB }, + { "wglQueryPbufferARB", X11DRV_wglQueryPbufferARB }, + { "wglReleasePbufferDCARB", X11DRV_wglReleasePbufferDCARB }, + { "wglSetPbufferAttribARB", X11DRV_wglSetPbufferAttribARB }, + } +}; + +/* WGL_ARB_pbuffer */ +static void WineGLExtension__WGL_ARB_pbuffer() +{ + if ((glxRequireVersion(3) == FALSE) || (glxRequireExtension("GLX_SGIX_pbuffer") == FALSE)) + return; + + X11DRV_WineGL_RegisterExtension(&WGL_ARB_pbuffer); +} + +static const WineGLExtension WGL_ARB_pixel_format = +{ + "WGL_ARB_pixel_format", + { + { "wglChoosePixelFormatARB", X11DRV_wglChoosePixelFormatARB }, + { "wglGetPixelFormatAttribfvARB", X11DRV_wglGetPixelFormatAttribfvARB }, + { "wglGetPixelFormatAttribivARB", X11DRV_wglGetPixelFormatAttribivARB }, + } +}; + +/* WGL_ARB_pixel_format */ +static void WineGLExtension__WGL_ARB_pixel_format() +{ + X11DRV_WineGL_RegisterExtension(&WGL_ARB_pixel_format); +} + +static const WineGLExtension WGL_ARB_render_texture = +{ + "WGL_ARB_render_texture", + { + { "wglBindTexImageARB", X11DRV_wglBindTexImageARB }, + { "wglReleaseTexImageARB", X11DRV_wglReleaseTexImageARB }, + } +}; + +/* WGL_ARB_render_texture */ +static void WineGLExtension__WGL_ARB_render_texture() +{ + if (glxRequireExtension("GLX_ATI_render_texture") == FALSE && + glxRequireExtension("GLX_ARB_render_texture") == FALSE) + return; + + X11DRV_WineGL_RegisterExtension(&WGL_ARB_render_texture); +} + +static const WineGLExtension WGL_EXT_extensions_string = +{ + "WGL_EXT_extensions_string", + { + { "wglGetExtensionsStringEXT", X11DRV_wglGetExtensionsStringEXT }, + } +}; + +/* WGL_EXT_extensions_string */ +static void WineGLExtension__WGL_EXT_extensions_string() +{ + X11DRV_WineGL_RegisterExtension(&WGL_EXT_extensions_string); +} + +static const WineGLExtension WGL_EXT_swap_control = +{ + "WGL_EXT_swap_control", + { + { "wglSwapIntervalEXT", X11DRV_wglSwapIntervalEXT }, + { "wglGetSwapIntervalEXT", X11DRV_wglGetSwapIntervalEXT }, + } +}; + +/* WGL_EXT_swap_control */ +static void WineGLExtension__WGL_EXT_swap_control() +{ + if (glxRequireExtension("GLX_SGI_swap_control") == FALSE) + return; + + X11DRV_WineGL_RegisterExtension(&WGL_EXT_swap_control); +} + + +/** + * X11DRV_WineGL_LoadExtensions + */ +void X11DRV_WineGL_LoadExtensions(void) +{ + WineGLInfo.wglExtensions[0] = 0; + /* ARB Extensions */ + WineGLExtension__WGL_ARB_extensions_string(); + WineGLExtension__WGL_ARB_make_current_read(); + WineGLExtension__WGL_ARB_multisample(); + WineGLExtension__WGL_ARB_pbuffer(); + WineGLExtension__WGL_ARB_pixel_format(); + WineGLExtension__WGL_ARB_render_texture(); + + /* EXT Extensions */ + WineGLExtension__WGL_EXT_extensions_string(); + WineGLExtension__WGL_EXT_swap_control(); +} + + static XID create_glxpixmap(X11DRV_PDEVICE *physDev) { GLXPixmap ret; @@ -1233,6 +2710,12 @@ HDC WINAPI X11DRV_wglGetCurrentReadDCARB(void) return 0; } +/* OpenGL32: wglGetProcAddress */ +PROC X11DRV_wglGetProcAddress(LPCSTR lpszProc) { + ERR_(opengl)("No OpenGL support compiled in.\n"); + return NULL; +} + /* OpenGL32 wglMakeCurrent */ BOOL WINAPI X11DRV_wglMakeCurrent(HDC hdc, HGLRC hglrc) { ERR_(opengl)("No OpenGL support compiled in.\n"); diff --git a/dlls/winex11.drv/winex11.drv.spec b/dlls/winex11.drv/winex11.drv.spec index bfef43cc397..54b781b92e5 100644 --- a/dlls/winex11.drv/winex11.drv.spec +++ b/dlls/winex11.drv/winex11.drv.spec @@ -135,6 +135,7 @@ @ cdecl wglGetCurrentDC() X11DRV_wglGetCurrentDC @ cdecl wglGetCurrentReadDCARB() X11DRV_wglGetCurrentReadDCARB @ cdecl wglGetIntegerv(long ptr) X11DRV_wglGetIntegerv +@ cdecl wglGetProcAddress(ptr) X11DRV_wglGetProcAddress @ cdecl wglMakeContextCurrentARB(long long long) X11DRV_wglMakeContextCurrentARB @ cdecl wglMakeCurrent(long long) X11DRV_wglMakeCurrent @ cdecl wglShareLists(long long) X11DRV_wglShareLists diff --git a/include/wine/wgl.h b/include/wine/wgl.h new file mode 100644 index 00000000000..66fb1b0562f --- /dev/null +++ b/include/wine/wgl.h @@ -0,0 +1,180 @@ +/* + * Wine WGL extension + ATI GLX extension defines + * + * Copyright (c) 2004 Lionel Ulmer + * Copyright (c) 2005 Alex Woods + * Copyright (c) 2005 Raphael Junqueira + * + * 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 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define HPBUFFERARB void * + +#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 +#define WGL_DRAW_TO_WINDOW_ARB 0x2001 +#define WGL_DRAW_TO_BITMAP_ARB 0x2002 +#define WGL_ACCELERATION_ARB 0x2003 +#define WGL_NEED_PALETTE_ARB 0x2004 +#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005 +#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006 +#define WGL_SWAP_METHOD_ARB 0x2007 +#define WGL_NUMBER_OVERLAYS_ARB 0x2008 +#define WGL_NUMBER_UNDERLAYS_ARB 0x2009 +#define WGL_TRANSPARENT_ARB 0x200A +#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037 +#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038 +#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039 +#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A +#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B +#define WGL_SHARE_DEPTH_ARB 0x200C +#define WGL_SHARE_STENCIL_ARB 0x200D +#define WGL_SHARE_ACCUM_ARB 0x200E +#define WGL_SUPPORT_GDI_ARB 0x200F +#define WGL_SUPPORT_OPENGL_ARB 0x2010 +#define WGL_DOUBLE_BUFFER_ARB 0x2011 +#define WGL_STEREO_ARB 0x2012 +#define WGL_PIXEL_TYPE_ARB 0x2013 +#define WGL_COLOR_BITS_ARB 0x2014 +#define WGL_RED_BITS_ARB 0x2015 +#define WGL_RED_SHIFT_ARB 0x2016 +#define WGL_GREEN_BITS_ARB 0x2017 +#define WGL_GREEN_SHIFT_ARB 0x2018 +#define WGL_BLUE_BITS_ARB 0x2019 +#define WGL_BLUE_SHIFT_ARB 0x201A +#define WGL_ALPHA_BITS_ARB 0x201B +#define WGL_ALPHA_SHIFT_ARB 0x201C +#define WGL_ACCUM_BITS_ARB 0x201D +#define WGL_ACCUM_RED_BITS_ARB 0x201E +#define WGL_ACCUM_GREEN_BITS_ARB 0x201F +#define WGL_ACCUM_BLUE_BITS_ARB 0x2020 +#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021 +#define WGL_DEPTH_BITS_ARB 0x2022 +#define WGL_STENCIL_BITS_ARB 0x2023 +#define WGL_AUX_BUFFERS_ARB 0x2024 + +#define WGL_NO_ACCELERATION_ARB 0x2025 +#define WGL_GENERIC_ACCELERATION_ARB 0x2026 +#define WGL_FULL_ACCELERATION_ARB 0x2027 + +#define WGL_PBUFFER_WIDTH_ARB 0x2034 +#define WGL_PBUFFER_HEIGHT_ARB 0x2035 +#define WGL_PBUFFER_LOST_ARB 0x2036 +#define WGL_DRAW_TO_PBUFFER_ARB 0x202D +#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E +#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F +#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030 +#define WGL_PBUFFER_LARGEST_ARB 0x2033 + +#define WGL_TYPE_RGBA_ARB 0x202B +#define WGL_TYPE_COLORINDEX_ARB 0x202C + +#define WGL_SAMPLE_BUFFERS_ARB 0x2041 +#define WGL_SAMPLES_ARB 0x2042 + +/** + * WGL_render_texture + */ +/** GetPixelFormat/ChoosePixelFormat */ +#define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070 +#define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071 +/** CreatePbuffer / QueryPbuffer */ +#define WGL_TEXTURE_FORMAT_ARB 0x2072 +#define WGL_TEXTURE_TARGET_ARB 0x2073 +#define WGL_MIPMAP_TEXTURE_ARB 0x2074 +/** CreatePbuffer / QueryPbuffer */ +#define WGL_TEXTURE_RGB_ARB 0x2075 +#define WGL_TEXTURE_RGBA_ARB 0x2076 +#define WGL_NO_TEXTURE_ARB 0x2077 +/** CreatePbuffer / QueryPbuffer */ +#define WGL_TEXTURE_CUBE_MAP_ARB 0x2078 +#define WGL_TEXTURE_1D_ARB 0x2079 +#define WGL_TEXTURE_2D_ARB 0x207A +#define WGL_NO_TEXTURE_ARB 0x2077 +/** SetPbufferAttribARB/QueryPbufferARB parameters */ +#define WGL_MIPMAP_LEVEL_ARB 0x207B +#define WGL_CUBE_MAP_FACE_ARB 0x207C +/** SetPbufferAttribARB/QueryPbufferARB attribs */ +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080 +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081 +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082 +/** BindTexImageARB/ReleaseTexImageARB */ +#define WGL_FRONT_LEFT_ARB 0x2083 +#define WGL_FRONT_RIGHT_ARB 0x2084 +#define WGL_BACK_LEFT_ARB 0x2085 +#define WGL_BACK_RIGHT_ARB 0x2086 +#define WGL_AUX0_ARB 0x2087 +#define WGL_AUX1_ARB 0x2088 +#define WGL_AUX2_ARB 0x2089 +#define WGL_AUX3_ARB 0x208A +#define WGL_AUX4_ARB 0x208B +#define WGL_AUX5_ARB 0x208C +#define WGL_AUX6_ARB 0x208D +#define WGL_AUX7_ARB 0x208E +#define WGL_AUX8_ARB 0x208F +#define WGL_AUX9_ARB 0x2090 + +/** + * WGL_ATI_pixel_format_float / WGL_ARB_color_buffer_float + */ +#define WGL_TYPE_RGBA_FLOAT_ATI 0x21A0 +#define GL_RGBA_FLOAT_MODE_ATI 0x8820 +#define GL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI 0x8835 +#define GL_CLAMP_VERTEX_COLOR_ARB 0x891A +#define GL_CLAMP_FRAGMENT_COLOR_ARB 0x891B +#define GL_CLAMP_READ_COLOR_ARB 0x891C +/** 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 +/** GLX_ATI_render_texture */ +#define GLX_BIND_TO_TEXTURE_RGB_ATI 0x9800 +#define GLX_BIND_TO_TEXTURE_RGBA_ATI 0x9801 +#define GLX_TEXTURE_FORMAT_ATI 0x9802 +#define GLX_TEXTURE_TARGET_ATI 0x9803 +#define GLX_MIPMAP_TEXTURE_ATI 0x9804 +#define GLX_TEXTURE_RGB_ATI 0x9805 +#define GLX_TEXTURE_RGBA_ATI 0x9806 +#define GLX_NO_TEXTURE_ATI 0x9807 +#define GLX_TEXTURE_CUBE_MAP_ATI 0x9808 +#define GLX_TEXTURE_1D_ATI 0x9809 +#define GLX_TEXTURE_2D_ATI 0x980A +#define GLX_MIPMAP_LEVEL_ATI 0x980B +#define GLX_CUBE_MAP_FACE_ATI 0x980C +#define GLX_TEXTURE_CUBE_MAP_POSITIVE_X_ATI 0x980D +#define GLX_TEXTURE_CUBE_MAP_NEGATIVE_X_ATI 0x980E +#define GLX_TEXTURE_CUBE_MAP_POSITIVE_Y_ATI 0x980F +#define GLX_TEXTURE_CUBE_MAP_NEGATIVE_Y_ATI 0x9810 +#define GLX_TEXTURE_CUBE_MAP_POSITIVE_Z_ATI 0x9811 +#define GLX_TEXTURE_CUBE_MAP_NEGATIVE_Z_ATI 0x9812 +#define GLX_FRONT_LEFT_ATI 0x9813 +#define GLX_FRONT_RIGHT_ATI 0x9814 +#define GLX_BACK_LEFT_ATI 0x9815 +#define GLX_BACK_RIGHT_ATI 0x9816 +#define GLX_AUX0_ATI 0x9817 +#define GLX_AUX1_ATI 0x9818 +#define GLX_AUX2_ATI 0x9819 +#define GLX_AUX3_ATI 0x981A +#define GLX_AUX4_ATI 0x981B +#define GLX_AUX5_ATI 0x981C +#define GLX_AUX6_ATI 0x981D +#define GLX_AUX7_ATI 0x981E +#define GLX_AUX8_ATI 0x981F +#define GLX_AUX9_ATI 0x9820 +#define GLX_BIND_TO_TEXTURE_LUMINANCE_ATI 0x9821 +#define GLX_BIND_TO_TEXTURE_INTENSITY_ATI 0x9822 -- GitLab