From: Alexandros Frantzis alexandros.frantzis@collabora.com
Introduce a new wgl driver callback function to allow the driver to provide a complete list of all pixel formats along with all the information needed to implement WGL_ARB_pixel_format. --- dlls/opengl32/make_opengl | 55 ++++++++++ dlls/opengl32/unix_thunks.c | 10 +- dlls/opengl32/unix_wgl.c | 193 ++++++++++++++++++++++++++++++++++++ include/wine/wgl_driver.h | 56 ++++++++++- 4 files changed, 304 insertions(+), 10 deletions(-)
diff --git a/dlls/opengl32/make_opengl b/dlls/opengl32/make_opengl index b5afeeaa415..f3f669ddf93 100755 --- a/dlls/opengl32/make_opengl +++ b/dlls/opengl32/make_opengl @@ -193,6 +193,7 @@ my %manual_unix_functions = "glGetString" => 1, "glGetStringi" => 1, "glGetIntegerv" => 1, + "wglGetPixelFormatAttribivARB" => 1, "wglGetProcAddress" => 1, ); my %manual_wow64_thunks = @@ -890,6 +891,59 @@ printf HEADER "#define WINE_WGL_DRIVER_VERSION %u\n\n", $wgl_version + 1; print HEADER "struct wgl_context;\n"; print HEADER "struct wgl_pbuffer;\n\n";
+print HEADER "struct wgl_pixel_format\n"; +print HEADER "{\n"; +print HEADER " unsigned int id;\n"; +print HEADER " unsigned int draw_to_window:1;\n"; +print HEADER " unsigned int draw_to_bitmap:1;\n"; +print HEADER " unsigned int acceleration:2; /* 0=No, 1=Generic, 2=Full */\n"; +print HEADER " unsigned int need_palette:1;\n"; +print HEADER " unsigned int need_system_palette:1;\n"; +print HEADER " unsigned int swap_layer_buffers:1;\n"; +print HEADER " unsigned int swap_method:2; /* 0=Exchange, 1=Copy, 2=Undefined */\n"; +print HEADER " unsigned int number_overlays:8;\n"; +print HEADER " unsigned int number_underlays:8;\n"; +print HEADER " unsigned int transparent:1;\n"; +print HEADER " unsigned int support_gdi:1;\n"; +print HEADER " unsigned int support_opengl:1;\n"; +print HEADER " unsigned int double_buffer:1;\n"; +print HEADER " unsigned int stereo:1;\n"; +print HEADER " unsigned int pixel_type:2; /* 0=RGBA, 1=ColorIndex, 2=RGBA_UNSIGNED_FLOAT 3=RGBA_FLOAT */\n"; +print HEADER " unsigned int color_bits:11;\n"; +print HEADER " unsigned int red_bits:8;\n"; +print HEADER " unsigned int red_shift:8;\n"; +print HEADER " unsigned int green_bits:8;\n"; +print HEADER " unsigned int green_shift:8;\n"; +print HEADER " unsigned int blue_bits:8;\n"; +print HEADER " unsigned int blue_shift:8;\n"; +print HEADER " unsigned int alpha_bits:8;\n"; +print HEADER " unsigned int alpha_shift:8;\n"; +print HEADER " unsigned int accum_bits:8;\n"; +print HEADER " unsigned int accum_red_bits:8;\n"; +print HEADER " unsigned int accum_green_bits:8;\n"; +print HEADER " unsigned int accum_blue_bits:8;\n"; +print HEADER " unsigned int accum_alpha_bits:8;\n"; +print HEADER " unsigned int depth_bits:8;\n"; +print HEADER " unsigned int stencil_bits:8;\n"; +print HEADER " unsigned int aux_buffers:8;\n"; +print HEADER " unsigned int draw_to_pbuffer:1;\n"; +print HEADER " unsigned int max_pbuffer_pixels;\n"; +print HEADER " unsigned int max_pbuffer_width;\n"; +print HEADER " unsigned int max_pbuffer_height;\n"; +print HEADER " unsigned int transparent_red_value;\n"; +print HEADER " unsigned int transparent_green_value;\n"; +print HEADER " unsigned int transparent_blue_value;\n"; +print HEADER " unsigned int transparent_alpha_value;\n"; +print HEADER " unsigned int transparent_index_value;\n"; +print HEADER " unsigned int sample_buffers:1;\n"; +print HEADER " unsigned int samples:8;\n"; +print HEADER " unsigned int bind_to_texture_rgb:1;\n"; +print HEADER " unsigned int bind_to_texture_rgba:1;\n"; +print HEADER " unsigned int bind_to_texture_rectangle_rgb:1;\n"; +print HEADER " unsigned int bind_to_texture_rectangle_rgba:1;\n"; +print HEADER " unsigned int framebuffer_srgb_capable:1;\n"; +print HEADER "};\n\n"; + print HEADER "struct opengl_funcs\n{\n"; print HEADER " struct\n {\n"; foreach (sort keys %wgl_functions) @@ -899,6 +953,7 @@ foreach (sort keys %wgl_functions) my $func_ret = get_func_ret( $wgl_functions{$_}, 1 ); printf HEADER " %-10s (WINE_GLAPI *p_$_)($decl_args);\n", $func_ret; } +printf HEADER " %-10s (WINE_GLAPI *p_get_pixel_formats)( const struct wgl_pixel_format ** formats );\n", "UINT"; print HEADER " } wgl;\n\n";
print HEADER " struct\n {\n"; diff --git a/dlls/opengl32/unix_thunks.c b/dlls/opengl32/unix_thunks.c index a2889e7cd32..b8898d19d4e 100644 --- a/dlls/opengl32/unix_thunks.c +++ b/dlls/opengl32/unix_thunks.c @@ -41,6 +41,7 @@ extern NTSTATUS ext_wglCreateContextAttribsARB( void *args ); extern NTSTATUS ext_wglCreatePbufferARB( void *args ); extern NTSTATUS ext_wglDestroyPbufferARB( void *args ); extern NTSTATUS ext_wglGetPbufferDCARB( void *args ); +extern NTSTATUS ext_wglGetPixelFormatAttribivARB( void *args ); extern NTSTATUS ext_wglMakeContextCurrentARB( void *args ); extern NTSTATUS ext_wglQueryPbufferARB( void *args ); extern NTSTATUS ext_wglReleasePbufferDCARB( void *args ); @@ -24134,15 +24135,6 @@ static NTSTATUS ext_wglGetPixelFormatAttribfvARB( void *args ) return STATUS_SUCCESS; }
-static NTSTATUS ext_wglGetPixelFormatAttribivARB( void *args ) -{ - struct wglGetPixelFormatAttribivARB_params *params = args; - const struct opengl_funcs *funcs = get_dc_funcs( params->hdc ); - if (!funcs || !funcs->ext.p_wglGetPixelFormatAttribivARB) return STATUS_NOT_IMPLEMENTED; - params->ret = funcs->ext.p_wglGetPixelFormatAttribivARB( params->hdc, params->iPixelFormat, params->iLayerPlane, params->nAttributes, params->piAttributes, params->piValues ); - return STATUS_SUCCESS; -} - static NTSTATUS ext_wglGetSwapIntervalEXT( void *args ) { struct wglGetSwapIntervalEXT_params *params = args; diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index b75a940d1d6..eaafc7102cf 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -437,6 +437,134 @@ static BOOL check_extension_support( TEB *teb, const char *extension, const char return FALSE; }
+static BOOL wgl_attrib_uses_layer( int attrib ) +{ + switch (attrib) + { + case WGL_ACCELERATION_ARB: + case WGL_TRANSPARENT_ARB: + case WGL_SHARE_DEPTH_ARB: + case WGL_SHARE_STENCIL_ARB: + case WGL_SHARE_ACCUM_ARB: + case WGL_TRANSPARENT_RED_VALUE_ARB: + case WGL_TRANSPARENT_GREEN_VALUE_ARB: + case WGL_TRANSPARENT_BLUE_VALUE_ARB: + case WGL_TRANSPARENT_ALPHA_VALUE_ARB: + case WGL_TRANSPARENT_INDEX_VALUE_ARB: + case WGL_SUPPORT_OPENGL_ARB: + case WGL_DOUBLE_BUFFER_ARB: + case WGL_STEREO_ARB: + case WGL_PIXEL_TYPE_ARB: + case WGL_TYPE_COLORINDEX_ARB: + case WGL_COLOR_BITS_ARB: + case WGL_RED_BITS_ARB: + case WGL_RED_SHIFT_ARB: + case WGL_GREEN_BITS_ARB: + case WGL_GREEN_SHIFT_ARB: + case WGL_BLUE_BITS_ARB: + case WGL_BLUE_SHIFT_ARB: + case WGL_ALPHA_BITS_ARB: + case WGL_ALPHA_SHIFT_ARB: + case WGL_ACCUM_BITS_ARB: + case WGL_ACCUM_RED_BITS_ARB: + case WGL_ACCUM_GREEN_BITS_ARB: + case WGL_ACCUM_BLUE_BITS_ARB: + case WGL_ACCUM_ALPHA_BITS_ARB: + case WGL_DEPTH_BITS_ARB: + case WGL_STENCIL_BITS_ARB: + case WGL_AUX_BUFFERS_ARB: + return TRUE; + default: + return FALSE; + } +} + +static int wgl_pixel_format_get_attrib( const struct wgl_pixel_format *fmt, int attrib ) +{ + switch (attrib) + { + case WGL_DRAW_TO_WINDOW_ARB: return fmt->draw_to_window; + case WGL_DRAW_TO_BITMAP_ARB: return fmt->draw_to_bitmap; + case WGL_ACCELERATION_ARB: + switch (fmt->acceleration) + { + case 0: return WGL_NO_ACCELERATION_ARB; + case 1: return WGL_GENERIC_ACCELERATION_ARB; + case 2: return WGL_FULL_ACCELERATION_ARB; + } + break; + case WGL_NEED_PALETTE_ARB: return fmt->need_palette; + case WGL_NEED_SYSTEM_PALETTE_ARB: return fmt->need_system_palette; + case WGL_SWAP_LAYER_BUFFERS_ARB: return fmt->swap_layer_buffers; + case WGL_SWAP_METHOD_ARB: + switch (fmt->swap_method) + { + case 0: return WGL_SWAP_EXCHANGE_ARB; + case 1: return WGL_SWAP_COPY_ARB; + case 2: return WGL_SWAP_UNDEFINED_ARB; + } + break; + case WGL_NUMBER_OVERLAYS_ARB: return fmt->number_overlays; + case WGL_NUMBER_UNDERLAYS_ARB: return fmt->number_underlays; + case WGL_TRANSPARENT_ARB: return fmt->transparent; + case WGL_SHARE_DEPTH_ARB: + case WGL_SHARE_STENCIL_ARB: + case WGL_SHARE_ACCUM_ARB: + /* We support only a main plane at the moment which by definition + * shares the depth/stencil/accum buffers with itself. */ + return GL_TRUE; + case WGL_SUPPORT_GDI_ARB: return fmt->support_gdi; + case WGL_SUPPORT_OPENGL_ARB: return fmt->support_opengl; + case WGL_DOUBLE_BUFFER_ARB: return fmt->double_buffer; + case WGL_STEREO_ARB: return fmt->stereo; + case WGL_PIXEL_TYPE_ARB: + switch (fmt->pixel_type) + { + case 0: return WGL_TYPE_RGBA_ARB; + case 1: return WGL_TYPE_COLORINDEX_ARB; + case 2: return WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT; + case 3: return WGL_TYPE_RGBA_FLOAT_ARB; + } + break; + case WGL_COLOR_BITS_ARB: return fmt->color_bits; + case WGL_RED_BITS_ARB: return fmt->red_bits; + case WGL_RED_SHIFT_ARB: return fmt->red_shift; + case WGL_GREEN_BITS_ARB: return fmt->green_bits; + case WGL_GREEN_SHIFT_ARB: return fmt->green_shift; + case WGL_BLUE_BITS_ARB: return fmt->blue_bits; + case WGL_BLUE_SHIFT_ARB: return fmt->blue_shift; + case WGL_ALPHA_BITS_ARB: return fmt->alpha_bits; + case WGL_ALPHA_SHIFT_ARB: return fmt->alpha_shift; + case WGL_ACCUM_BITS_ARB: return fmt->accum_bits; + case WGL_ACCUM_RED_BITS_ARB: return fmt->accum_red_bits; + case WGL_ACCUM_GREEN_BITS_ARB: return fmt->accum_green_bits; + case WGL_ACCUM_BLUE_BITS_ARB: return fmt->accum_blue_bits; + case WGL_ACCUM_ALPHA_BITS_ARB: return fmt->accum_alpha_bits; + case WGL_DEPTH_BITS_ARB: return fmt->depth_bits; + case WGL_STENCIL_BITS_ARB: return fmt->stencil_bits; + case WGL_AUX_BUFFERS_ARB: return fmt->aux_buffers; + case WGL_DRAW_TO_PBUFFER_ARB: return fmt->draw_to_pbuffer; + case WGL_MAX_PBUFFER_PIXELS_ARB: return fmt->max_pbuffer_pixels; + case WGL_MAX_PBUFFER_WIDTH_ARB: return fmt->max_pbuffer_width; + case WGL_MAX_PBUFFER_HEIGHT_ARB: return fmt->max_pbuffer_height; + case WGL_TRANSPARENT_RED_VALUE_ARB: return fmt->transparent_red_value; + case WGL_TRANSPARENT_GREEN_VALUE_ARB: return fmt->transparent_green_value; + case WGL_TRANSPARENT_BLUE_VALUE_ARB: return fmt->transparent_blue_value; + case WGL_TRANSPARENT_ALPHA_VALUE_ARB: return fmt->transparent_alpha_value; + case WGL_TRANSPARENT_INDEX_VALUE_ARB: return fmt->transparent_index_value; + case WGL_SAMPLE_BUFFERS_ARB: return fmt->sample_buffers; + case WGL_SAMPLES_ARB: return fmt->samples; + case WGL_BIND_TO_TEXTURE_RGB_ARB: return fmt->bind_to_texture_rgb; + case WGL_BIND_TO_TEXTURE_RGBA_ARB: return fmt->bind_to_texture_rgba; + case WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV: return fmt->bind_to_texture_rectangle_rgb; + case WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV: return fmt->bind_to_texture_rectangle_rgba; + case WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB: return fmt->framebuffer_srgb_capable; + default: FIXME( "unsupported 0x%x WGL attribute\n", attrib ); + } + + return 0; +} + static void wrap_glGetIntegerv( TEB *teb, GLenum pname, GLint *data ) { const struct opengl_funcs *funcs = teb->glTable; @@ -828,6 +956,42 @@ static HDC wrap_wglGetPbufferDCARB( HPBUFFERARB handle ) return ptr->funcs->ext.p_wglGetPbufferDCARB( ptr->u.pbuffer ); }
+static BOOL wrap_wglGetPixelFormatAttribivARB( HDC hdc, int iPixelFormat, int iLayerPlane, + UINT nAttributes, const int *piAttributes, INT *piValues ) +{ + const struct opengl_funcs *funcs = get_dc_funcs( hdc ); + const struct wgl_pixel_format *formats, *format; + UINT num_formats; + UINT i; + + TRACE( "(%p, %d, %d, %d, %p, %p)\n", hdc, iPixelFormat, iLayerPlane, nAttributes, piAttributes, piValues ); + + num_formats = funcs->wgl.p_get_pixel_formats( &formats ); + + if (iPixelFormat > 0 && iPixelFormat - 1 < num_formats) + format = &formats[iPixelFormat - 1]; + else + format = NULL; + + for (i = 0; i < nAttributes; ++i) + { + int attrib = piAttributes[i]; + switch (attrib) + { + case WGL_NUMBER_PIXEL_FORMATS_ARB: + piValues[i] = num_formats; + break; + default: + if (format && (iLayerPlane == 0 || !wgl_attrib_uses_layer( attrib ))) + piValues[i] = wgl_pixel_format_get_attrib( format, attrib ); + else + return FALSE; + } + } + + return TRUE; +} + static BOOL wrap_wglMakeContextCurrentARB( TEB *teb, HDC draw_hdc, HDC read_hdc, HGLRC hglrc ) { BOOL ret = TRUE; @@ -1100,6 +1264,35 @@ NTSTATUS ext_wglGetPbufferDCARB( void *args ) return STATUS_SUCCESS; }
+NTSTATUS ext_wglGetPixelFormatAttribivARB( void *args ) +{ + struct wglGetPixelFormatAttribivARB_params *params = args; + const struct opengl_funcs *funcs = get_dc_funcs( params->hdc ); + + if (!funcs) return STATUS_NOT_IMPLEMENTED; + + if (funcs->ext.p_wglGetPixelFormatAttribivARB && + funcs->ext.p_wglGetPixelFormatAttribivARB != (void *)1) + { + params->ret = + funcs->ext.p_wglGetPixelFormatAttribivARB( params->hdc, params->iPixelFormat, + params->iLayerPlane, params->nAttributes, + params->piAttributes, params->piValues ); + } + else if (funcs->wgl.p_get_pixel_formats) + { + params->ret = wrap_wglGetPixelFormatAttribivARB( params->hdc, params->iPixelFormat, + params->iLayerPlane, params->nAttributes, + params->piAttributes, params->piValues ); + } + else + { + return STATUS_NOT_IMPLEMENTED; + } + + return STATUS_SUCCESS; +} + NTSTATUS ext_wglMakeContextCurrentARB( void *args ) { struct wglMakeContextCurrentARB_params *params = args; diff --git a/include/wine/wgl_driver.h b/include/wine/wgl_driver.h index 93ebe7d7f46..cb41e7c3a43 100644 --- a/include/wine/wgl_driver.h +++ b/include/wine/wgl_driver.h @@ -7,11 +7,64 @@ #define WINE_GLAPI #endif
-#define WINE_WGL_DRIVER_VERSION 23 +#define WINE_WGL_DRIVER_VERSION 24
struct wgl_context; struct wgl_pbuffer;
+struct wgl_pixel_format +{ + unsigned int id; + unsigned int draw_to_window:1; + unsigned int draw_to_bitmap:1; + unsigned int acceleration:2; /* 0=No, 1=Generic, 2=Full */ + unsigned int need_palette:1; + unsigned int need_system_palette:1; + unsigned int swap_layer_buffers:1; + unsigned int swap_method:2; /* 0=Exchange, 1=Copy, 2=Undefined */ + unsigned int number_overlays:8; + unsigned int number_underlays:8; + unsigned int transparent:1; + unsigned int support_gdi:1; + unsigned int support_opengl:1; + unsigned int double_buffer:1; + unsigned int stereo:1; + unsigned int pixel_type:2; /* 0=RGBA, 1=ColorIndex, 2=RGBA_UNSIGNED_FLOAT 3=RGBA_FLOAT */ + unsigned int color_bits:11; + unsigned int red_bits:8; + unsigned int red_shift:8; + unsigned int green_bits:8; + unsigned int green_shift:8; + unsigned int blue_bits:8; + unsigned int blue_shift:8; + unsigned int alpha_bits:8; + unsigned int alpha_shift:8; + unsigned int accum_bits:8; + unsigned int accum_red_bits:8; + unsigned int accum_green_bits:8; + unsigned int accum_blue_bits:8; + unsigned int accum_alpha_bits:8; + unsigned int depth_bits:8; + unsigned int stencil_bits:8; + unsigned int aux_buffers:8; + unsigned int draw_to_pbuffer:1; + unsigned int max_pbuffer_pixels; + unsigned int max_pbuffer_width; + unsigned int max_pbuffer_height; + unsigned int transparent_red_value; + unsigned int transparent_green_value; + unsigned int transparent_blue_value; + unsigned int transparent_alpha_value; + unsigned int transparent_index_value; + unsigned int sample_buffers:1; + unsigned int samples:8; + unsigned int bind_to_texture_rgb:1; + unsigned int bind_to_texture_rgba:1; + unsigned int bind_to_texture_rectangle_rgb:1; + unsigned int bind_to_texture_rectangle_rgba:1; + unsigned int framebuffer_srgb_capable:1; +}; + struct opengl_funcs { struct @@ -26,6 +79,7 @@ struct opengl_funcs BOOL (WINE_GLAPI *p_wglSetPixelFormat)( HDC hdc, int ipfd, const PIXELFORMATDESCRIPTOR *ppfd ); BOOL (WINE_GLAPI *p_wglShareLists)( struct wgl_context * hrcSrvShare, struct wgl_context * hrcSrvSource ); BOOL (WINE_GLAPI *p_wglSwapBuffers)( HDC hdc ); + UINT (WINE_GLAPI *p_get_pixel_formats)( const struct wgl_pixel_format ** formats ); } wgl;
struct