From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/opengl.c | 189 ++++++++++++++++++++++++++++++++++- include/wine/opengl_driver.h | 4 +- 2 files changed, 188 insertions(+), 5 deletions(-)
diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 31f5e68143d..34e7a847de9 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -238,14 +238,189 @@ static void *egldrv_get_proc_address( const char *name )
static UINT egldrv_init_pixel_formats( UINT *onscreen_count ) { - FIXME( "stub!\n" ); - return *onscreen_count = 0; + static struct opengl_funcs *funcs = &display_funcs; + const EGLint attribs[] = + { + EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_NONE + }; + EGLConfig *configs; + EGLint i, count; + + funcs->p_eglChooseConfig( funcs->egl_display, attribs, NULL, 0, &count ); + if (!(configs = malloc( count * sizeof(*configs) ))) return 0; + if (!funcs->p_eglChooseConfig( funcs->egl_display, attribs, configs, count, &count ) || !count) + { + ERR( "Failed to get any configs from eglChooseConfig\n" ); + free( configs ); + return 0; + } + + if (TRACE_ON(wgl)) for (i = 0; i < count; i++) + { + EGLint id, type, visual_id, native, render, color, r, g, b, a, d, s; + funcs->p_eglGetConfigAttrib( funcs->egl_display, configs[i], EGL_NATIVE_VISUAL_ID, &visual_id ); + funcs->p_eglGetConfigAttrib( funcs->egl_display, configs[i], EGL_SURFACE_TYPE, &type ); + funcs->p_eglGetConfigAttrib( funcs->egl_display, configs[i], EGL_RENDERABLE_TYPE, &render ); + funcs->p_eglGetConfigAttrib( funcs->egl_display, configs[i], EGL_CONFIG_ID, &id ); + funcs->p_eglGetConfigAttrib( funcs->egl_display, configs[i], EGL_NATIVE_RENDERABLE, &native ); + funcs->p_eglGetConfigAttrib( funcs->egl_display, configs[i], EGL_COLOR_BUFFER_TYPE, &color ); + funcs->p_eglGetConfigAttrib( funcs->egl_display, configs[i], EGL_RED_SIZE, &r ); + funcs->p_eglGetConfigAttrib( funcs->egl_display, configs[i], EGL_GREEN_SIZE, &g ); + funcs->p_eglGetConfigAttrib( funcs->egl_display, configs[i], EGL_BLUE_SIZE, &b ); + funcs->p_eglGetConfigAttrib( funcs->egl_display, configs[i], EGL_ALPHA_SIZE, &a ); + funcs->p_eglGetConfigAttrib( funcs->egl_display, configs[i], EGL_DEPTH_SIZE, &d ); + funcs->p_eglGetConfigAttrib( funcs->egl_display, configs[i], EGL_STENCIL_SIZE, &s ); + TRACE( "%u: config %d id %d type %x visual %d native %d render %x colortype %d rgba %d,%d,%d,%d depth %u stencil %d\n", + count, i, id, type, visual_id, native, render, color, r, g, b, a, d, s ); + } + + funcs->egl_configs = configs; + funcs->egl_config_count = count; + *onscreen_count = count; + return 2 * count; +} + +static BOOL describe_egl_config( EGLConfig config, struct wgl_pixel_format *fmt, BOOL onscreen ) +{ + static struct opengl_funcs *funcs = &display_funcs; + EGLint value, surface_type; + PIXELFORMATDESCRIPTOR *pfd = &fmt->pfd; + + /* If we can't get basic information, there is no point continuing */ + if (!funcs->p_eglGetConfigAttrib( funcs->egl_display, config, EGL_SURFACE_TYPE, &surface_type )) return FALSE; + + memset( fmt, 0, sizeof(*fmt) ); + pfd->nSize = sizeof(*pfd); + pfd->nVersion = 1; + pfd->dwFlags = PFD_SUPPORT_OPENGL | PFD_SUPPORT_COMPOSITION; + if (onscreen) + { + pfd->dwFlags |= PFD_DOUBLEBUFFER; + if (surface_type & EGL_WINDOW_BIT) pfd->dwFlags |= PFD_DRAW_TO_WINDOW; + } + pfd->iPixelType = PFD_TYPE_RGBA; + pfd->iLayerType = PFD_MAIN_PLANE; + +#define SET_ATTRIB( field, attrib ) \ + value = 0; \ + funcs->p_eglGetConfigAttrib( funcs->egl_display, config, attrib, &value ); \ + pfd->field = value; +#define SET_ATTRIB_ARB( field, attrib ) \ + if (!funcs->p_eglGetConfigAttrib( funcs->egl_display, config, attrib, &value )) value = -1; \ + fmt->field = value; + + /* Although the documentation describes cColorBits as excluding alpha, real + * drivers tend to return the full pixel size, so do the same. */ + SET_ATTRIB( cColorBits, EGL_BUFFER_SIZE ); + SET_ATTRIB( cRedBits, EGL_RED_SIZE ); + SET_ATTRIB( cGreenBits, EGL_GREEN_SIZE ); + SET_ATTRIB( cBlueBits, EGL_BLUE_SIZE ); + SET_ATTRIB( cAlphaBits, EGL_ALPHA_SIZE ); + /* Although we don't get information from EGL about the component shifts + * or the native format, the 0xARGB order is the most common. */ + pfd->cBlueShift = 0; + pfd->cGreenShift = pfd->cBlueBits; + pfd->cRedShift = pfd->cGreenBits + pfd->cBlueBits; + if (!pfd->cAlphaBits) pfd->cAlphaShift = 0; + else pfd->cAlphaShift = pfd->cRedBits + pfd->cGreenBits + pfd->cBlueBits; + + SET_ATTRIB( cDepthBits, EGL_DEPTH_SIZE ); + SET_ATTRIB( cStencilBits, EGL_STENCIL_SIZE ); + + fmt->swap_method = WGL_SWAP_UNDEFINED_ARB; + + if (funcs->p_eglGetConfigAttrib( funcs->egl_display, config, EGL_TRANSPARENT_TYPE, &value )) + { + switch (value) + { + case EGL_TRANSPARENT_RGB: + fmt->transparent = GL_TRUE; + break; + case EGL_NONE: + fmt->transparent = GL_FALSE; + break; + default: + ERR( "unexpected transparency type 0x%x\n", value ); + fmt->transparent = -1; + break; + } + } + else fmt->transparent = -1; + + if (!funcs->has_EGL_EXT_pixel_format_float) fmt->pixel_type = WGL_TYPE_RGBA_ARB; + else if (funcs->p_eglGetConfigAttrib( funcs->egl_display, config, EGL_COLOR_COMPONENT_TYPE_EXT, &value )) + { + switch (value) + { + case EGL_COLOR_COMPONENT_TYPE_FIXED_EXT: + fmt->pixel_type = WGL_TYPE_RGBA_ARB; + break; + case EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT: + fmt->pixel_type = WGL_TYPE_RGBA_FLOAT_ARB; + break; + default: + ERR( "unexpected color component type 0x%x\n", value ); + fmt->pixel_type = -1; + break; + } + } + else fmt->pixel_type = -1; + + fmt->draw_to_pbuffer = TRUE; + /* Use some arbitrary but reasonable limits (4096 is also Mesa's default) */ + fmt->max_pbuffer_width = 4096; + fmt->max_pbuffer_height = 4096; + fmt->max_pbuffer_pixels = fmt->max_pbuffer_width * fmt->max_pbuffer_height; + + if (funcs->p_eglGetConfigAttrib( funcs->egl_display, config, EGL_TRANSPARENT_RED_VALUE, &value )) + { + fmt->transparent_red_value_valid = GL_TRUE; + fmt->transparent_red_value = value; + } + if (funcs->p_eglGetConfigAttrib( funcs->egl_display, config, EGL_TRANSPARENT_GREEN_VALUE, &value )) + { + fmt->transparent_green_value_valid = GL_TRUE; + fmt->transparent_green_value = value; + } + if (funcs->p_eglGetConfigAttrib( funcs->egl_display, config, EGL_TRANSPARENT_BLUE_VALUE, &value )) + { + fmt->transparent_blue_value_valid = GL_TRUE; + fmt->transparent_blue_value = value; + } + fmt->transparent_alpha_value_valid = GL_TRUE; + fmt->transparent_alpha_value = 0; + fmt->transparent_index_value_valid = GL_TRUE; + fmt->transparent_index_value = 0; + + SET_ATTRIB_ARB( sample_buffers, EGL_SAMPLE_BUFFERS ); + SET_ATTRIB_ARB( samples, EGL_SAMPLES ); + + fmt->bind_to_texture_rgb = GL_TRUE; + fmt->bind_to_texture_rgba = GL_TRUE; + fmt->bind_to_texture_rectangle_rgb = GL_TRUE; + fmt->bind_to_texture_rectangle_rgba = GL_TRUE; + + /* TODO: Support SRGB surfaces and enable the attribute */ + fmt->framebuffer_srgb_capable = GL_FALSE; + + fmt->float_components = GL_FALSE; + +#undef SET_ATTRIB +#undef SET_ATTRIB_ARB + return TRUE; }
static BOOL egldrv_describe_pixel_format( int format, struct wgl_pixel_format *desc ) { - FIXME( "stub!\n" ); - return FALSE; + static struct opengl_funcs *funcs = &display_funcs; + int count = funcs->egl_config_count; + BOOL onscreen = TRUE; + + if (--format < 0 || format > 2 * count) return FALSE; + if (format >= count) onscreen = FALSE; + return describe_egl_config( funcs->egl_configs[format % count], desc, onscreen ); }
static const char *egldrv_init_wgl_extensions( struct opengl_funcs *funcs ) @@ -1607,6 +1782,12 @@ static void display_funcs_init(void) p_display_glFlush = display_funcs.p_glFlush; display_funcs.p_glFlush = win32u_glFlush;
+ if (display_funcs.has_EGL_EXT_pixel_format_float) + { + register_extension( wgl_extensions, ARRAY_SIZE(wgl_extensions), "WGL_ARB_pixel_format_float" ); + register_extension( wgl_extensions, ARRAY_SIZE(wgl_extensions), "WGL_ATI_pixel_format_float" ); + } + register_extension( wgl_extensions, ARRAY_SIZE(wgl_extensions), "WGL_ARB_extensions_string" ); display_funcs.p_wglGetExtensionsStringARB = win32u_wglGetExtensionsStringARB;
diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index 60edc2edff3..23bc07da9ab 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -61,7 +61,7 @@ struct wgl_pixel_format #ifdef WINE_UNIX_LIB
/* Wine internal opengl driver version, needs to be bumped upon opengl_funcs changes. */ -#define WINE_OPENGL_DRIVER_VERSION 34 +#define WINE_OPENGL_DRIVER_VERSION 35
struct wgl_context; struct wgl_pbuffer; @@ -112,6 +112,8 @@ struct opengl_funcs
void *egl_handle; EGLDisplay egl_display; + UINT egl_config_count; + EGLConfig *egl_configs; BOOL has_EGL_EXT_present_opaque; BOOL has_EGL_EXT_pixel_format_float; };