OGL Extension string patch

Rob Crittenden <[email protected]> Tue, 26 Oct 2004 12:25:22 -0400 (EDT)
Newsgroups gmane.comp.emulators.winex.devel
Message-ID <[email protected]>
Attached is a patch that gives the user complete control over the
OpenGL extensions string returned through opengl32.dll.

This patch was done to fix an error in the Medal of Honor series that uses
a fixed buffer for receiving the list of extensions. With newer nVidia cards
and the 6x.xx drivers this causes an overflow and the game crashes.

A new config file section is added, [opengl]. There are 2 options:

FixedGLExtensionBuffer (Y/N). If "Y" then return the extension list from the
card. This returns a list based on a GF4 4400 Ti with 61.11 driver instead of
the string from the native driver.

GLExtensionBuffer. This is a comma-separate list of extensions prefixed with
+ or - that turns on or off extensions. This gives the user complete control
over what extensions are enabled/disabled so they can tweak/tune as
necessary. Turning an option on here does not magically give the card
the capability to do it.

A sample might be:

"GLExtensionBuffer" = "+GL_ARB_imaging,-GL_ARB_depth_texture"

This modifies the default settings as set by "FixedGLExtensionBuffer" = "Y".

GLExtensionBuffer is not used if FixedGLExtensionBuffer is disabled.

Once the patch is applied then make_opengl will need to be run again.

This patch also pulled some manual updates to the autogenerated files into
the make_opengl script.

rob
opengl32.diff (text/plain, 18.7 KB)
diff -r -u --new-file /home/rcrit/wine/winex2/org.0923/winex/dlls/opengl32/make_opengl ./make_opengl
--- /home/rcrit/wine/winex2/org.0923/winex/dlls/opengl32/make_opengl	Tue Jun  1 18:06:02 2004
+++ ./make_opengl	Mon Oct 25 22:53:58 2004
@@ -198,7 +198,11 @@
     if ($func_ref->[1] ne "void") {
 	$ret = $ret . "ret_value = ";
     }
-    $ret = $ret . $prefix . $func_ref->[0] . "( " . $call_arg . ");\n";
+    if ($func_ref->[0] eq "glGetString") {
+        $ret = $ret .  $prefix . "SetFixedBuffer( " . $call_arg . ");\n";
+    } else {
+        $ret = $ret . $prefix . $func_ref->[0] . "( " . $call_arg . ");\n";
+    }
     if ($thread_safe) {
 	$ret = $ret . "  LEAVE_GL();\n";
     }
@@ -511,6 +515,7 @@
 import kernel32.dll
 import ntdll.dll
 import ddraw.dll
+import advapi32.dll
 
 debug_channels (opengl)
 
@@ -530,6 +535,16 @@
 @  stdcall wglSwapLayerBuffers(long long) wglSwapLayerBuffers
 @  stdcall wglUseFontBitmapsA(long long long long) wglUseFontBitmapsA
 @  stdcall wglUseFontOutlinesA(long long long long long long long ptr) wglUseFontOutlinesA
+@  stdcall wglGetExtensionsStringARB(long) wglGetExtensionsStringARB
+@  stdcall wglGetPixelFormatAttribivARB(long long long long ptr ptr) wglGetPixelFormatAttribivARB
+@  stdcall wglGetPixelFormatAttribfvARB(long long long long ptr ptr) wglGetPixelFormatAttribfvARB
+@  stdcall wglChoosePixelFormatARB(long ptr ptr long ptr ptr) wglChoosePixelFormatARB
+@  stdcall wglCreatePbufferARB(long long long long ptr) wglCreatePbufferARB
+@  stdcall wglGetPbufferDCARB(long) wglGetPbufferDCARB
+@  stdcall wglReleasePbufferDCARB(long long) wglReleasePbufferDCARB
+@  stdcall wglDestroyPbufferARB(long) wglDestroyPbufferARB
+@  stdcall wglQueryPbufferARB(long long ptr) wglQueryPbufferARB
+@  stdcall wglGetExtensionsStringEXT() wglGetExtensionsStringEXT
 @  stdcall wglSwapIntervalEXT(long) wglSwapIntervalEXT
 @  stdcall wglGetSwapIntervalEXT() wglGetSwapIntervalEXT
 @  stub    glGetLevelParameterfv
@@ -571,8 +586,7 @@
 #include \"config.h\"
 #include \"wine/wine_gl.h\"
 #include \"wine/debug.h\"
-
-WINE_DEFAULT_DEBUG_CHANNEL(opengl);
+#include \"mohaa_kludge.h\"
 
 ";
 foreach (sort keys %norm_functions) {
diff -r -u --new-file /home/rcrit/wine/winex2/org.0923/winex/dlls/opengl32/mohaa_kludge.h ./mohaa_kludge.h
--- /home/rcrit/wine/winex2/org.0923/winex/dlls/opengl32/mohaa_kludge.h	Wed Dec 31 19:00:00 1969
+++ ./mohaa_kludge.h	Tue Oct 26 12:13:21 2004
@@ -0,0 +1,423 @@
+#include "winbase.h"
+#include "winreg.h"
+#include "wine/winbase16.h"
+#include <stdlib.h>
+
+WINE_DEFAULT_DEBUG_CHANNEL(opengl);
+
+typedef struct
+{
+    const GLubyte *name;
+    int enabled;
+} extension_properties;
+
+/*
+ * The extensions that are "on" are based on a GeForce4 4400 Ti with
+ * nVidia binary driver v61.11
+ */
+extension_properties extension_def[] =
+{
+   {"GL_3DFX_multisample", 0},
+   {"GL_3DFX_tbuffer", 0},
+   {"GL_3DFX_texture_compression_FXT1", 0},
+   {"GL_APPLE_client_storage", 0},
+   {"GL_APPLE_element_array", 0},
+   {"GL_APPLE_fence", 0},
+   {"GL_APPLE_specular_vector", 0},
+   {"GL_APPLE_transform_hint", 0},
+   {"GL_APPLE_vertex_array_object", 0},
+   {"GL_APPLE_vertex_array_range", 0},
+   {"GL_APPLE_ycbcr_422", 0},
+   {"GL_ARB_depth_texture", 1},
+   {"GL_ARB_draw_buffers", 0},
+   {"GL_ARB_fragment_program", 0},
+   {"GL_ARB_fragment_program_shadow", 0},
+   {"GL_ARB_fragment_shader", 0},
+   {"GL_ARB_imaging", 1},
+   {"GL_ARB_matrix_palette", 0},
+   {"GL_ARB_multisample", 1},
+   {"GL_ARB_multitexture", 1},
+   {"GL_ARB_occlusion_query", 1},
+   {"GL_ARB_point_parameters", 1},
+   {"GL_ARB_point_sprite", 1},
+   {"GL_ARB_shader_objects", 0},
+   {"GL_ARB_shader_objects", 1},
+   {"GL_ARB_shading_language_100", 1},
+   {"GL_ARB_shadow", 1},
+   {"GL_ARB_shadow_ambient", 0},
+   {"GL_ARB_texture_border_clamp", 1},
+   {"GL_ARB_texture_compression", 1},
+   {"GL_ARB_texture_cube_map", 1},
+   {"GL_ARB_texture_env_add", 1},
+   {"GL_ARB_texture_env_combine", 1},
+   {"GL_ARB_texture_env_crossbar", 0},
+   {"GL_ARB_texture_env_dot3", 1},
+   {"GL_ARB_texture_mirrored_repeat", 1},
+   {"GL_ARB_texture_non_power_of_two", 0},
+   {"GL_ARB_texture_rectangle", 0},
+   {"GL_ARB_transpose_matrix", 1},
+   {"GL_ARB_vertex_blend", 0},
+   {"GL_ARB_vertex_buffer_object", 1},
+   {"GL_ARB_vertex_program", 1},
+   {"GL_ARB_vertex_shader", 1},
+   {"GL_ARB_window_pos", 1},
+   {"GL_ATI_draw_buffers", 0},
+   {"GL_ATI_element_array", 0},
+   {"GL_ATI_envmap_bumpmap", 0},
+   {"GL_ATI_fragment_shader", 0},
+   {"GL_ATI_map_object_buffer", 0},
+   {"GL_ATI_pixel_format_float", 0},
+   {"GL_ATI_pn_triangles", 0},
+   {"GL_ATI_separate_stencil", 0},
+   {"GL_ATI_text_fragment_shader", 0},
+   {"GL_ATI_texture_env_combine3", 0},
+   {"GL_ATI_texture_float", 0},
+   {"GL_ATI_texture_mirror_once", 0},
+   {"GL_ATI_vertex_array_object", 0},
+   {"GL_ATI_vertex_attrib_array_object", 0},
+   {"GL_ATI_vertex_streams", 0},
+   {"GL_EXT_422_pixels", 0},
+   {"GL_EXT_abgr", 1},
+   {"GL_EXT_bgra", 1},
+   {"GL_EXT_blend_color", 1},
+   {"GL_EXT_blend_equation_separate", 0},
+   {"GL_EXT_blend_func_separate", 0},
+   {"GL_EXT_blend_logic_op", 0},
+   {"GL_EXT_blend_minmax", 1},
+   {"GL_EXT_blend_subtract", 1},
+   {"GL_EXT_Cg_shader", 0},
+   {"GL_EXT_clip_volume_hint", 0},
+   {"GL_EXT_cmyka", 0},
+   {"GL_EXT_color_subtable", 0},
+   {"GL_EXT_compiled_vertex_array", 1},
+   {"GL_EXT_convolution", 0},
+   {"GL_EXT_coordinate_frame", 0},
+   {"GL_EXT_copy_texture", 0},
+   {"GL_EXT_cull_vertex", 0},
+   {"GL_EXT_depth_bounds_test", 0},
+   {"GL_EXT_draw_range_elements", 1},
+   {"GL_EXT_fog_coord", 1},
+   {"GL_EXT_fragment_lighting", 0},
+   {"GL_EXT_histogram", 0},
+   {"GL_EXT_index_array_formats", 0},
+   {"GL_EXT_index_func", 0},
+   {"GL_EXT_index_material", 0},
+   {"GL_EXT_index_texture", 0},
+   {"GL_EXT_light_texture", 0},
+   {"GL_EXT_misc_attribute", 0},
+   {"GL_EXT_multi_draw_arrays", 1},
+   {"GL_EXT_packed_pixels", 1},
+   {"GL_EXT_paletted_texture", 1},
+   {"GL_EXT_pixel_buffer_object", 1},
+   {"GL_EXT_pixel_transform", 0},
+   {"GL_EXT_pixel_transform_color_table", 0},
+   {"GL_EXT_point_parameters", 1},
+   {"GL_EXT_polygon_offset", 0},
+   {"GL_EXT_rescale_normal", 1},
+   {"GL_EXT_scene_marker", 0},
+   {"GL_EXT_secondary_color", 1},
+   {"GL_EXT_separate_specular_color", 1},
+   {"GL_EXT_shadow_funcs", 1},
+   {"GL_EXT_shared_texture_palette", 1},
+   {"GL_EXT_stencil_two_side", 0},
+   {"GL_EXT_stencil_wrap", 1},
+   {"GL_EXT_subtexture", 0},
+   {"GL_EXT_texture", 0},
+   {"GL_EXT_texture3D", 1},
+   {"GL_EXT_texture_compression_dxt1", 0},
+   {"GL_EXT_texture_compression_s3tc", 1},
+   {"GL_EXT_texture_cube_map", 1},
+   {"GL_EXT_texture_edge_clamp", 1},
+   {"GL_EXT_texture_env", 0},
+   {"GL_EXT_texture_env_add", 1},
+   {"GL_EXT_texture_env_combine", 1},
+   {"GL_EXT_texture_env_dot3", 1},
+   {"GL_EXT_texture_filter_anisotropic", 1},
+   {"GL_EXT_texture_lod", 1},
+   {"GL_EXT_texture_lod_bias", 1},
+   {"GL_EXT_texture_mirror_clamp", 0},
+   {"GL_EXT_texture_object", 1},
+   {"GL_EXT_texture_perturb_normal", 0},
+   {"GL_EXT_vertex_array", 1},
+   {"GL_EXT_vertex_shader", 0},
+   {"GL_EXT_vertex_weighting", 0},
+   {"GL_HP_convolution_border_modes", 0},
+   {"GL_HP_image_transform", 0},
+   {"GL_HP_occlusion_test", 1},
+   {"GL_HP_texture_lighting", 0},
+   {"GL_IBM_cull_vertex", 0},
+   {"GL_IBM_multimode_draw_arrays", 0},
+   {"GL_IBM_rasterpos_clip", 1},
+   {"GL_IBM_static_data", 0},
+   {"GL_IBM_texture_mirrored_repeat", 1},
+   {"GL_IBM_vertex_array_lists", 0},
+   {"GL_INGR_color_clamp", 0},
+   {"GL_INGR_interlace_read", 0},
+   {"GL_INTEL_parallel_arrays", 0},
+   {"GL_INTEL_texture_scissor", 0},
+   {"GL_KTX_buffer_region", 1},
+   {"GL_MESA_pack_invert", 0},
+   {"GL_MESA_resize_buffers", 0},
+   {"GL_MESA_window_pos", 0},
+   {"GL_MESA_ycbcr_texture", 0},
+   {"GL_NV_blend_square", 1},
+   {"GL_NV_copy_depth_to_color", 1},
+   {"GL_NV_depth_clamp", 1},
+   {"GL_NV_evaluators", 0},
+   {"GL_NV_fence", 1},
+   {"GL_NV_float_buffer", 0},
+   {"GL_NV_fog_distance", 1},
+   {"GL_NV_fragment_program", 0},
+   {"GL_NV_fragment_program2", 0},
+   {"GL_NV_fragment_program_option", 0},
+   {"GL_NV_half_float", 0},
+   {"GL_NV_light_max_exponent", 1},
+   {"GL_NV_multisample_filter_hint", 1},
+   {"GL_NV_occlusion_query", 1},
+   {"GL_NV_packed_depth_stencil", 1},
+   {"GL_NV_pixel_data_range", 1},
+   {"GL_NV_point_sprite", 1},
+   {"GL_NV_primitive_restart", 0},
+   {"GL_NV_register_combiners", 1},
+   {"GL_NV_register_combiners2", 1},
+   {"GL_NV_texgen_emboss", 0},
+   {"GL_NV_texgen_reflection", 1},
+   {"GL_NV_texture_compression_vtc", 1},
+   {"GL_NV_texture_env_combine4", 1},
+   {"GL_NV_texture_expand_normal", 0},
+   {"GL_NV_texture_rectangle", 1},
+   {"GL_NV_texture_shader", 1},
+   {"GL_NV_texture_shader2", 1},
+   {"GL_NV_texture_shader3", 1},
+   {"GL_NV_vertex_array_range", 1},
+   {"GL_NV_vertex_array_range2", 1},
+   {"GL_NV_vertex_program", 1},
+   {"GL_NV_vertex_program1_1", 1},
+   {"GL_NV_vertex_program2", 0},
+   {"GL_NV_vertex_program2_option", 0},
+   {"GL_NV_vertex_program3", 0},
+   {"GL_OES_byte_coordinates", 0},
+   {"GL_OES_compressed_paletted_texture", 0},
+   {"GL_OES_fixed_point", 0},
+   {"GL_OES_query_matrix", 0},
+   {"GL_OES_read_format", 0},
+   {"GL_OES_single_precision", 0},
+   {"GL_OML_interlace", 0},
+   {"GL_OML_resample", 0},
+   {"GL_OML_subsample", 0},
+   {"GL_PGI_misc_hints", 0},
+   {"GL_PGI_vertex_hints", 0},
+   {"GL_REND_screen_coordinates", 0},
+   {"GL_S3_s3tc", 1},
+   {"GL_SGI_color_matrix", 0},
+   {"GL_SGI_color_table", 0},
+   {"GL_SGIS_detail_texture", 0},
+   {"GL_SGIS_fog_function", 0},
+   {"GL_SGIS_generate_mipmap", 1},
+   {"GL_SGIS_multisample", 0},
+   {"GL_SGIS_multitexture", 1},
+   {"GL_SGIS_pixel_texture", 0},
+   {"GL_SGIS_sharpen_texture", 0},
+   {"GL_SGIS_texture4D", 0},
+   {"GL_SGIS_texture_border_clamp", 0},
+   {"GL_SGIS_texture_color_mask", 0},
+   {"GL_SGIS_texture_edge_clamp", 0},
+   {"GL_SGIS_texture_filter4", 0},
+   {"GL_SGIS_texture_lod", 1},
+   {"GL_SGIS_texture_select", 0},
+   {"GL_SGI_texture_color_table", 0},
+   {"GL_SGIX_async", 0},
+   {"GL_SGIX_async_histogram", 0},
+   {"GL_SGIX_async_pixel", 0},
+   {"GL_SGIX_blend_alpha_minmax", 0},
+   {"GL_SGIX_clipmap", 0},
+   {"GL_SGIX_depth_texture", 1},
+   {"GL_SGIX_flush_raster", 0},
+   {"GL_SGIX_fog_offset", 0},
+   {"GL_SGIX_framezoom", 0},
+   {"GL_SGIX_instruments", 0},
+   {"GL_SGIX_interlace", 0},
+   {"GL_SGIX_ir_instrument1", 0},
+   {"GL_SGIX_list_priority", 0},
+   {"GL_SGIX_pixel_texture", 0},
+   {"GL_SGIX_pixel_texture_bits", 0},
+   {"GL_SGIX_reference_plane", 0},
+   {"GL_SGIX_resample", 0},
+   {"GL_SGIX_shadow", 1},
+   {"GL_SGIX_shadow_ambient", 0},
+   {"GL_SGIX_sprite", 0},
+   {"GL_SGIX_tag_sample_buffer", 0},
+   {"GL_SGIX_texture_add_env", 0},
+   {"GL_SGIX_texture_coordinate_clamp", 0},
+   {"GL_SGIX_texture_lod_bias", 0},
+   {"GL_SGIX_texture_multi_buffer", 0},
+   {"GL_SGIX_texture_range", 0},
+   {"GL_SGIX_texture_scale_bias", 0},
+   {"GL_SGIX_vertex_preclip", 0},
+   {"GL_SGIX_ycrcb", 0},
+   {"GL_SUN_convolution_border_modes", 0},
+   {"GL_SUN_global_alpha", 0},
+   {"GL_SUN_mesh_array", 0},
+   {"GL_SUN_slice_accum", 1},
+   {"GL_SUN_triangle_list", 0},
+   {"GL_SUN_vertex", 0},
+   {"GL_SUNX_constant_data", 0},
+   {"GL_WIN_phong_shading", 0},
+   {"GL_WIN_specular_fog", 0},
+};
+
+#define extnum sizeof(extension_def) / sizeof(extension_properties)
+
+#define IS_OPTION_TRUE(ch) \
+    ((ch) == 'y' || (ch) == 'Y' || (ch) == 't' || (ch) == 'T' || (ch) == '1')
+
+ /***********************************************************************
+ * get_config_key
+ *
+ * Get a config key from either the app-specific or the default config
+ */
+inline static DWORD get_config_key( HKEY defkey, HKEY appkey, const char *name,
+                                    char *buffer, DWORD size )
+{
+    if (appkey && !RegQueryValueExA( appkey, name, 0, NULL, buffer, &size )) return 0;
+    return RegQueryValueExA( defkey, name, 0, NULL, buffer, &size );
+}
+
+/*
+ * Take a comma-separated list of extensions and update the internal list
+ * by enabling (+) or disabling (-) a given extension. A sample list might
+ * look like: +GL_ARB_imaging,-GL_ARB_depth_texture,-GL_SUN_slice_accum
+ */
+static void parse_extensions(GLubyte *e)
+{
+    GLubyte *extensions = e;
+    GLubyte *extension = extensions;
+    int found, x;
+    int active;
+
+    while (extensions && (strlen(extensions)) )
+    {
+        while((*extension) && (isspace(*extension)))
+            ++extension;
+
+        switch(*extension++)
+        {
+            case '+':
+                active = 1;
+                break;
+            case '-':
+                active = 0;
+                break;
+
+            default:
+                {
+                ERR("bad extension string %s\n", extension-1);
+                return;
+                };
+        };
+
+        if( (extensions = (GLubyte *)strchr(extension, ',')) )
+            *extensions++ = '\0';
+
+        found = 0;
+
+        for(x = 0; x < extnum; x++)
+        {
+            if(!strcasecmp(extension, extension_def[x].name))
+            {
+                extension_def[x].enabled = active;
+                found = 1;
+                break;
+            }
+        }
+
+        if (!found) {
+            ERR("unknown extension %s\n", extension);
+        }
+
+        if (extensions)
+            extension = extensions;
+    }
+
+    return;
+}
+
+/*
+ * Returns 1 if the option FixedGLExtensionBuffer is set in the [opengl]
+ * section. If true then the list extensions_def[] can be run through to
+ * come up with a list of enabled OpenGL extensions.
+ */
+static int FixedGLBuffer() {
+    char buffer[MAX_PATH+16] = "";
+    HKEY hkey, appkey = 0;
+    int result = 0;
+
+    if (RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config\\opengl", 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, NULL ))
+    {
+        ERR("Cannot create config registry key\n" );
+        return 0;
+    }
+
+    /* open the app-specific key */
+    if (GetModuleFileName16( GetCurrentTask(), buffer, MAX_PATH ) ||
+        GetModuleFileNameA( 0, buffer, MAX_PATH ))
+    {
+        HKEY tmpkey;
+        char *p, *appname = buffer;
+        if ((p = strrchr( appname, '/' ))) appname = p + 1;
+        if ((p = strrchr( appname, '\\' ))) appname = p + 1;
+        strcat( appname, "\\opengl" );
+        if (!RegOpenKeyA( HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config\\AppDefaults", &tmpkey ))
+        {
+            if (RegOpenKeyA( tmpkey, appname, &appkey )) appkey = 0;
+            RegCloseKey( tmpkey );
+        }
+    }
+
+    if (!get_config_key( hkey, appkey, "FixedGLExtensionBuffer", buffer, sizeof(buffer) ))
+        result = IS_OPTION_TRUE(buffer[0]);
+
+    if (result) {
+        if (!get_config_key( hkey, appkey, "GLExtensionBuffer", buffer, sizeof(buffer) ))
+            parse_extensions(buffer);
+    }
+
+    if (appkey) RegCloseKey( appkey );
+    RegCloseKey( hkey );
+
+    return result;
+}
+
+/*
+ * Do some special work when trying to return the GL_EXTENSIONS string.
+ */
+static const GLubyte * SetFixedBuffer( GLenum name ) {
+    if (name == GL_EXTENSIONS && FixedGLBuffer()) {
+        int i;
+        GLubyte * string;
+        int size = 4096;
+
+        // Yes this memory will "leak"
+        string = (GLubyte *)malloc(4096);
+
+        string[0] = '\0';
+
+        // The extension string is a space-delimited list
+        for (i=0; i < extnum; i++) {
+            if (extension_def[i].enabled) {
+                if ((strlen(string) + strlen(extension_def[i].name) + 1) > size)
+                {
+                    size += 4096;
+                    string = (GLubyte *)realloc(string, size);
+                }
+                strcat(string, extension_def[i].name);
+                strcat(string, " ");
+            }
+        }
+        string[strlen(string)] = '\0'; // remove trailing space
+
+        return string;
+    } else {
+        return glGetString( name );
+    }
+}
diff -r -u --new-file /home/rcrit/wine/winex2/org.0923/winex/dlls/opengl32/opengl32.spec ./opengl32.spec
--- /home/rcrit/wine/winex2/org.0923/winex/dlls/opengl32/opengl32.spec	Wed Jul  7 12:27:31 2004
+++ ./opengl32.spec	Tue Oct 26 11:13:33 2004
@@ -8,6 +8,7 @@
 import kernel32.dll
 import ntdll.dll
 import ddraw.dll
+import advapi32.dll
 
 debug_channels (opengl)
 
@@ -27,35 +28,28 @@
 @  stdcall wglSwapLayerBuffers(long long) wglSwapLayerBuffers
 @  stdcall wglUseFontBitmapsA(long long long long) wglUseFontBitmapsA
 @  stdcall wglUseFontOutlinesA(long long long long long long long ptr) wglUseFontOutlinesA
-@  stub    glGetLevelParameterfv
-@  stub    glGetLevelParameteriv
-@  stub    wglUseFontBitmapsW
-@  stub    wglUseFontOutlinesW
-@  stub    wglGetDefaultProcAddress
-
-@  forward wglChoosePixelFormat GDI32.ChoosePixelFormat
-@  forward wglDescribePixelFormat GDI32.DescribePixelFormat
-@  forward wglGetPixelFormat GDI32.GetPixelFormat
-@  forward wglSetPixelFormat GDI32.SetPixelFormat
-@  forward wglSwapBuffers GDI32.SwapBuffers
-
 @  stdcall wglGetExtensionsStringARB(long) wglGetExtensionsStringARB
-
 @  stdcall wglGetPixelFormatAttribivARB(long long long long ptr ptr) wglGetPixelFormatAttribivARB
 @  stdcall wglGetPixelFormatAttribfvARB(long long long long ptr ptr) wglGetPixelFormatAttribfvARB
 @  stdcall wglChoosePixelFormatARB(long ptr ptr long ptr ptr) wglChoosePixelFormatARB
-
 @  stdcall wglCreatePbufferARB(long long long long ptr) wglCreatePbufferARB
 @  stdcall wglGetPbufferDCARB(long) wglGetPbufferDCARB
 @  stdcall wglReleasePbufferDCARB(long long) wglReleasePbufferDCARB
 @  stdcall wglDestroyPbufferARB(long) wglDestroyPbufferARB
 @  stdcall wglQueryPbufferARB(long long ptr) wglQueryPbufferARB
-
 @  stdcall wglGetExtensionsStringEXT() wglGetExtensionsStringEXT
-
 @  stdcall wglSwapIntervalEXT(long) wglSwapIntervalEXT
 @  stdcall wglGetSwapIntervalEXT() wglGetSwapIntervalEXT
-
+@  stub    glGetLevelParameterfv
+@  stub    glGetLevelParameteriv
+@  stub    wglUseFontBitmapsW
+@  stub    wglUseFontOutlinesW
+@  stub    wglGetDefaultProcAddress
+@  forward wglChoosePixelFormat GDI32.ChoosePixelFormat
+@  forward wglDescribePixelFormat GDI32.DescribePixelFormat
+@  forward wglGetPixelFormat GDI32.GetPixelFormat
+@  forward wglSetPixelFormat GDI32.SetPixelFormat
+@  forward wglSwapBuffers GDI32.SwapBuffers
 @  stdcall glAccum( long long ) wine_glAccum
 @  stdcall glActiveTextureARB( long ) wine_glActiveTextureARB
 @  stdcall glAlphaFunc( long long ) wine_glAlphaFunc