wgl: Add extension checking code / glxGetProcAddress protection.

This commit is contained in:
Roderick Colenbrander 2006-10-29 22:56:27 +01:00 committed by Alexandre Julliard
parent 02fc886302
commit 2f8a05e27e
4 changed files with 1196 additions and 1169 deletions

View File

@ -376,127 +376,122 @@ my %norm_functions = ();
#
my %ext_functions =
( "glDeleteBufferRegion" => [ "glDeleteBufferRegion", "void", [ [ "GLenum", "region" ] ], "glDeleteBufferRegion" ],
( "glDeleteBufferRegion" => [ "glDeleteBufferRegion", "void", [ [ "GLenum", "region" ] ], "glDeleteBufferRegion", "GL_KTX_buffer_region" ],
"glReadBufferRegion" => [ "glReadBufferRegion", "void", [ [ "GLenum", "region" ],
[ "GLint", "x" ],
[ "GLint", "y" ],
[ "GLsizei", "width" ],
[ "GLsizei", "height" ] ], "glReadBufferRegion" ],
[ "GLsizei", "height" ] ], "glReadBufferRegion", "GL_KTX_buffer_region" ],
"glDrawBufferRegion" => [ "glDrawBufferRegion", "void", [ [ "GLenum", "region" ],
[ "GLint", "x" ],
[ "GLint", "y" ],
[ "GLsizei", "width" ],
[ "GLsizei", "height" ],
[ "GLint", "xDest" ],
[ "GLint", "yDest" ] ], "glDrawBufferRegion" ],
"glBufferRegionEnabled" => [ "glBufferRegionEnabled", "GLuint", [ ], "glBufferRegionEnabled" ],
"glNewBufferRegion" => [ "glNewBufferRegion", "GLuint", [ [ "GLenum", "type" ] ], "glNewBufferRegion" ],
[ "GLint", "yDest" ] ], "glDrawBufferRegion", "GL_KTX_buffer_region" ],
"glBufferRegionEnabled" => [ "glBufferRegionEnabled", "GLuint", [ ], "glBufferRegionEnabled", "GL_KTX_buffer_region" ],
"glNewBufferRegion" => [ "glNewBufferRegion", "GLuint", [ [ "GLenum", "type" ] ], "glNewBufferRegion", "GL_KTX_buffer_region" ],
"glMTexCoord2fSGIS" => [ "glMTexCoord2fSGIS", "void", [ [ "GLenum", "target" ],
[ "GLfloat", "s" ],
[ "GLfloat", "t" ] ], "glMTexCoord2fSGIS" ],
[ "GLfloat", "t" ] ], "glMTexCoord2fSGIS", "GL_SGIS_multitexture" ],
"glMTexCoord2fvSGIS" => [ "glMTexCoord2fvSGIS", "void", [ [ "GLenum", "target" ],
[ "GLfloat *", "v" ] ], "glMTexCoord2fvSGIS" ],
[ "GLfloat *", "v" ] ], "glMTexCoord2fvSGIS", "GL_SGIS_multitexture" ],
"glMultiTexCoord1dSGIS" => [ "glMultiTexCoord1dSGIS", "void", [ [ "GLenum", "target" ],
[ "GLdouble", "s" ] ], "glMultiTexCoord1dSGIS" ],
[ "GLdouble", "s" ] ], "glMultiTexCoord1dSGIS", "GL_SGIS_multitexture" ],
"glMultiTexCoord1dvSGIS" => [ "glMultiTexCoord1dvSGIS", "void", [ [ "GLenum", "target" ],
[ "GLdouble *", "v" ] ], "glMultiTexCoord1dvSGIS" ],
[ "GLdouble *", "v" ] ], "glMultiTexCoord1dvSGIS", "GL_SGIS_multitexture" ],
"glMultiTexCoord1fSGIS" => [ "glMultiTexCoord1fSGIS", "void", [ [ "GLenum", "target" ],
[ "GLfloat", "s" ] ], "glMultiTexCoord1fSGIS" ],
[ "GLfloat", "s" ] ], "glMultiTexCoord1fSGIS", "GL_SGIS_multitexture" ],
"glMultiTexCoord1fvSGIS" => [ "glMultiTexCoord1fvSGIS", "void", [ [ "GLenum", "target" ],
[ "const GLfloat *", "v" ] ], "glMultiTexCoord1fvSGIS" ],
[ "const GLfloat *", "v" ] ], "glMultiTexCoord1fvSGIS", "GL_SGIS_multitexture" ],
"glMultiTexCoord1iSGIS" => [ "glMultiTexCoord1iSGIS", "void", [ [ "GLenum", "target" ],
[ "GLint", "s" ] ], "glMultiTexCoord1iSGIS" ],
[ "GLint", "s" ] ], "glMultiTexCoord1iSGIS", "GL_SGIS_multitexture" ],
"glMultiTexCoord1ivSGIS" => [ "glMultiTexCoord1ivSGIS", "void", [ [ "GLenum", "target" ],
[ "GLint *", "v" ] ], "glMultiTexCoord1ivSGIS" ],
[ "GLint *", "v" ] ], "glMultiTexCoord1ivSGIS", "GL_SGIS_multitexture" ],
"glMultiTexCoord1sSGIS" => [ "glMultiTexCoord1sSGIS", "void", [ [ "GLenum", "target" ],
[ "GLshort", "s" ] ], "glMultiTexCoord1sSGIS" ],
[ "GLshort", "s" ] ], "glMultiTexCoord1sSGIS", "GL_SGIS_multitexture" ],
"glMultiTexCoord1svSGIS" => [ "glMultiTexCoord1svSGIS", "void", [ [ "GLenum", "target" ],
[ "GLshort *", "v" ] ], "glMultiTexCoord1svSGIS" ],
[ "GLshort *", "v" ] ], "glMultiTexCoord1svSGIS", "GL_SGIS_multitexture" ],
"glMultiTexCoord2dSGIS" => [ "glMultiTexCoord2dSGIS", "void", [ [ "GLenum", "target" ],
[ "GLdouble", "s"],
[ "GLdouble", "t" ] ], "glMultiTexCoord2dSGIS" ],
[ "GLdouble", "t" ] ], "glMultiTexCoord2dSGIS", "GL_SGIS_multitexture" ],
"glMultiTexCoord2dvSGIS" => [ "glMultiTexCoord2dvSGIS", "void", [ [ "GLenum", "target" ],
[ "GLdouble *", "v" ] ], "glMultiTexCoord2dvSGIS" ],
[ "GLdouble *", "v" ] ], "glMultiTexCoord2dvSGIS", "GL_SGIS_multitexture" ],
"glMultiTexCoord2fSGIS" => [ "glMultiTexCoord2fSGIS", "void", [ [ "GLenum", "target" ],
[ "GLfloat", "s" ],
[ "GLfloat", "t" ] ], "glMultiTexCoord2fSGIS" ],
[ "GLfloat", "t" ] ], "glMultiTexCoord2fSGIS", "GL_SGIS_multitexture" ],
"glMultiTexCoord2fvSGIS" => [ "glMultiTexCoord2fvSGIS", "void", [ [ "GLenum", "target" ],
[ "GLfloat *", "v" ] ], "glMultiTexCoord2fvSGIS" ],
[ "GLfloat *", "v" ] ], "glMultiTexCoord2fvSGIS", "GL_SGIS_multitexture" ],
"glMultiTexCoord2iSGIS" => [ "glMultiTexCoord2iSGIS", "void", [ [ "GLenum", "target" ],
[ "GLint", "s" ],
[ "GLint", "t" ] ], "glMultiTexCoord2iSGIS" ],
[ "GLint", "t" ] ], "glMultiTexCoord2iSGIS", "GL_SGIS_multitexture" ],
"glMultiTexCoord2ivSGIS" => [ "glMultiTexCoord2ivSGIS", "void", [ [ "GLenum", "target" ],
[ "GLint *", "v" ] ], "glMultiTexCoord2ivSGIS" ],
[ "GLint *", "v" ] ], "glMultiTexCoord2ivSGIS", "GL_SGIS_multitexture" ],
"glMultiTexCoord2sSGIS" => [ "glMultiTexCoord2sSGIS", "void", [ [ "GLenum", "target" ],
[ "GLshort", "s" ],
[ "GLshort", "t" ] ], "glMultiTexCoord2sSGIS" ],
[ "GLshort", "t" ] ], "glMultiTexCoord2sSGIS", "GL_SGIS_multitexture" ],
"glMultiTexCoord2svSGIS" => [ "glMultiTexCoord2svSGIS", "void", [ [ "GLenum", "target" ],
[ "GLshort *", "v" ] ], "glMultiTexCoord2svSGIS" ],
[ "GLshort *", "v" ] ], "glMultiTexCoord2svSGIS", "GL_SGIS_multitexture" ],
"glMultiTexCoord3dSGIS" => [ "glMultiTexCoord3dSGIS", "void", [ [ "GLenum", "target" ],
[ "GLdouble", "s" ],
[ "GLdouble", "t" ],
[ "GLdouble", "r" ] ], "glMultiTexCoord3dSGIS" ],
[ "GLdouble", "r" ] ], "glMultiTexCoord3dSGIS", "GL_SGIS_multitexture" ],
"glMultiTexCoord3dvSGIS" => [ "glMultiTexCoord3dvSGIS", "void", [ [ "GLenum", "target" ],
[ "GLdouble *", "v" ] ], "glMultiTexCoord3dvSGIS" ],
[ "GLdouble *", "v" ] ], "glMultiTexCoord3dvSGIS", "GL_SGIS_multitexture" ],
"glMultiTexCoord3fSGIS" => [ "glMultiTexCoord3fSGIS", "void", [ [ "GLenum", "target" ],
[ "GLfloat", "s" ],
[ "GLfloat", "t" ],
[ "GLfloat", "r" ] ], "glMultiTexCoord3fSGIS" ],
[ "GLfloat", "r" ] ], "glMultiTexCoord3fSGIS", "GL_SGIS_multitexture" ],
"glMultiTexCoord3fvSGIS" => [ "glMultiTexCoord3fvSGIS", "void", [ [ "GLenum", "target" ],
[ "GLfloat *", "v" ] ], "glMultiTexCoord3fvSGIS" ],
[ "GLfloat *", "v" ] ], "glMultiTexCoord3fvSGIS", "GL_SGIS_multitexture" ],
"glMultiTexCoord3iSGIS" => [ "glMultiTexCoord3iSGIS", "void", [ [ "GLenum", "target" ],
[ "GLint", "s" ],
[ "GLint", "t" ],
[ "GLint", "r" ] ], "glMultiTexCoord3iSGIS" ],
[ "GLint", "r" ] ], "glMultiTexCoord3iSGIS", "GL_SGIS_multitexture" ],
"glMultiTexCoord3ivSGIS" => [ "glMultiTexCoord3ivSGIS", "void", [ [ "GLenum", "target" ],
[ "GLint *", "v" ] ], "glMultiTexCoord3ivSGIS" ],
[ "GLint *", "v" ] ], "glMultiTexCoord3ivSGIS", "GL_SGIS_multitexture" ],
"glMultiTexCoord3sSGIS" => [ "glMultiTexCoord3sSGIS", "void", [ [ "GLenum", "target" ],
[ "GLshort", "s" ],
[ "GLshort", "t" ],
[ "GLshort", "r" ] ], "glMultiTexCoord3sSGIS" ],
[ "GLshort", "r" ] ], "glMultiTexCoord3sSGIS", "GL_SGIS_multitexture" ],
"glMultiTexCoord3svSGIS" => [ "glMultiTexCoord3svSGIS", "void", [ [ "GLenum", "target" ],
[ "GLshort *", "v" ] ], "glMultiTexCoord3svSGIS" ],
[ "GLshort *", "v" ] ], "glMultiTexCoord3svSGIS", "GL_SGIS_multitexture" ],
"glMultiTexCoord4dSGIS" => [ "glMultiTexCoord4dSGIS", "void", [ [ "GLenum", "target" ],
[ "GLdouble", "s" ],
[ "GLdouble", "t" ],
[ "GLdouble", "r" ],
[ "GLdouble", "q" ] ], "glMultiTexCoord4dSGIS" ],
[ "GLdouble", "q" ] ], "glMultiTexCoord4dSGIS", "GL_SGIS_multitexture" ],
"glMultiTexCoord4dvSGIS" => [ "glMultiTexCoord4dvSGIS", "void", [ [ "GLenum", "target" ],
[ "GLdouble *", "v" ] ], "glMultiTexCoord4dvSGIS" ],
[ "GLdouble *", "v" ] ], "glMultiTexCoord4dvSGIS", "GL_SGIS_multitexture" ],
"glMultiTexCoord4fSGIS" => [ "glMultiTexCoord4fSGIS", "void", [ [ "GLenum", "target" ],
[ "GLfloat", "s" ],
[ "GLfloat", "t" ],
[ "GLfloat", "r" ],
[ "GLfloat", "q" ] ], "glMultiTexCoord4fSGIS" ],
[ "GLfloat", "q" ] ], "glMultiTexCoord4fSGIS", "GL_SGIS_multitexture" ],
"glMultiTexCoord4fvSGIS" => [ "glMultiTexCoord4fvSGIS", "void", [ [ "GLenum", "target" ],
[ "GLfloat *", "v" ] ], "glMultiTexCoord4fvSGIS" ],
[ "GLfloat *", "v" ] ], "glMultiTexCoord4fvSGIS", "GL_SGIS_multitexture" ],
"glMultiTexCoord4iSGIS" => [ "glMultiTexCoord4iSGIS", "void", [ [ "GLenum", "target" ],
[ "GLint", "s" ],
[ "GLint", "t" ],
[ "GLint", "r" ],
[ "GLint", "q" ] ], "glMultiTexCoord4iSGIS" ],
[ "GLint", "q" ] ], "glMultiTexCoord4iSGIS", "GL_SGIS_multitexture" ],
"glMultiTexCoord4ivSGIS" => [ "glMultiTexCoord4ivSGIS", "void", [ [ "GLenum", "target" ],
[ "GLint *", "v" ] ], "glMultiTexCoord4ivSGIS" ],
[ "GLint *", "v" ] ], "glMultiTexCoord4ivSGIS", "GL_SGIS_multitexture" ],
"glMultiTexCoord4sSGIS" => [ "glMultiTexCoord4sSGIS", "void", [ [ "GLenum", "target" ],
[ "GLshort", "s" ],
[ "GLshort", "t" ],
[ "GLshort", "r" ],
[ "GLshort", "q" ] ], "glMultiTexCoord4sSGIS" ],
[ "GLshort", "q" ] ], "glMultiTexCoord4sSGIS", "GL_SGIS_multitexture" ],
"glMultiTexCoord4svSGIS" => [ "glMultiTexCoord4svSGIS", "void", [ [ "GLenum", "target" ],
[ "GLshort *", "v" ] ], "glMultiTexCoord4svSGIS" ],
[ "GLshort *", "v" ] ], "glMultiTexCoord4svSGIS", "GL_SGIS_multitexture" ],
"glMultiTexCoordPointerSGIS" => [ "glMultiTexCoordPointerSGIS", "void", [ [ "GLenum", "target" ],
[ "GLint", "size" ],
[ "GLenum", "type" ],
[ "GLsizei", "stride" ],
[ "GLvoid *", "pointer" ] ], "glMultiTexCoordPointerSGIS" ],
"glSelectTextureSGIS" => [ "glSelectTextureSGIS", "void", [ [ "GLenum", "target" ] ], "glSelectTextureSGIS" ],
"glSelectTextureCoordSetSGIS" => [ "glSelectTextureCoordSetSGIS", "void", [ [ "GLenum", "target" ] ], "glSelectTextureCoordSetSGIS" ],
"wglAllocateMemoryNV" => [ "wglAllocateMemoryNV", "void *", [ [ "GLsizei", "size" ],
[ "GLfloat", "readfreq" ],
[ "GLfloat", "writefreq"],
[ "GLfloat", "priority" ] ], "glXAllocateMemoryNV" ],
"wglFreeMemoryNV" => [ "wglFreeMemoryNV", "void", [ [ "GLvoid *", "pointer" ] ], "glXFreeMemoryNV" ],
"glDeleteObjectBufferATI" => [ "glDeleteObjectBufferATI", "void", [ [ "GLuint", "buffer" ] ], "glDeleteObjectBufferATI" ]
[ "GLvoid *", "pointer" ] ], "glMultiTexCoordPointerSGIS", "GL_SGIS_multitexture" ],
"glSelectTextureSGIS" => [ "glSelectTextureSGIS", "void", [ [ "GLenum", "target" ] ], "glSelectTextureSGIS", "GL_SGIS_multitexture" ],
"glSelectTextureCoordSetSGIS" => [ "glSelectTextureCoordSetSGIS", "void", [ [ "GLenum", "target" ] ], "glSelectTextureCoordSetSGIS", "GL_SGIS_multitexture" ],
"glDeleteObjectBufferATI" => [ "glDeleteObjectBufferATI", "void", [ [ "GLuint", "buffer" ] ], "glDeleteObjectBufferATI", "GL_ATI_vertex_array_object" ]
);
my @arg_names;
@ -510,6 +505,7 @@ while (my $line = <REGISTRY>) {
# After get :
# - the return type
# - category (the extension the function is part of)
# - the argument types
# - the category the function belongs
%arg_types = ();
@ -580,7 +576,8 @@ while (my $line = <REGISTRY>) {
my $func_ref = [ "gl$funcname",
$ret_type,
$arg_ref,
"gl$funcname" ];
"gl$funcname",
"GL_$category" ];
# Now, put in one or the other hash table
if ($norm_categories{$category}) {
@ -714,11 +711,7 @@ foreach (sort keys %ext_functions) {
my $func_ref = $ext_functions{$_};
if ($func_ref->[0] eq $func_ref->[3])
{
print EXT " { \"$func_ref->[0]\", NULL, (void *) wine_$func_ref->[0] }";
}
else
{
print EXT " { \"$func_ref->[0]\", \"$func_ref->[3]\", (void *) wine_$func_ref->[0] }";
print EXT " { \"$func_ref->[0]\", \"$func_ref->[4]\", (void *) wine_$func_ref->[0] }";
}
if ($i != $count-1) {
print EXT ",";

File diff suppressed because it is too large Load Diff

View File

@ -54,7 +54,7 @@ void enter_gl(void);
typedef struct {
const char *name; /* name of the extension */
const char *glx_name; /* name used on Unix's libGL */
const char *extension; /* name of the GL/WGL extension */
void *func; /* pointer to the Wine function for this extension */
} OpenGL_extension;

View File

@ -178,6 +178,53 @@ static int compar(const void *elt_a, const void *elt_b) {
((const OpenGL_extension *) elt_b)->name);
}
/* Check if a GL extension is supported */
static BOOL is_extension_supported(const char* extension)
{
const char *gl_ext_string = (const char*)internal_glGetString(GL_EXTENSIONS);
TRACE("Checking for extension '%s'\n", extension);
if(!gl_ext_string) {
ERR("No OpenGL extensions found, check if your OpenGL setup is correct!\n");
return FALSE;
}
/* We use the GetProcAddress function from the display driver to retrieve function pointers
* for OpenGL and WGL extensions. In case of winex11.drv the OpenGL extension lookup is done
* using glXGetProcAddress. This function is quite unreliable in the sense that its specs don't
* require the function to return NULL when a extension isn't found. For this reason we check
* if the OpenGL extension required for the function we are looking up is supported. */
/* Check if the extension is part of the GL extension string to see if it is supported. */
if(strstr(gl_ext_string, extension) != NULL)
return TRUE;
/* In general an OpenGL function starts as an ARB/EXT extension and at some stage
* it becomes part of the core OpenGL library and can be reached without the ARB/EXT
* suffix aswell. In the extension table, these functions contain GL_VERSION_major_minor.
* Check if we are searching for a core GL function */
if(strncmp(extension, "GL_VERSION_", 11) == 0)
{
const GLubyte *gl_version = glGetString(GL_VERSION);
const const char *version = extension + 11; /* Move past 'GL_VERSION_' */
if(!gl_version) {
ERR("Error no OpenGL version found,\n");
return FALSE;
}
/* Compare the major/minor version numbers of the native OpenGL library and what is required by the function.
* The gl_version string is guaranteed to have atleast a major/minor and sometimes it has a release number aswell. */
if( (gl_version[0] >= version[0]) || ((gl_version[0] == version[0]) && (gl_version[2] >= version[2])) ) {
return TRUE;
}
WARN("The function requires OpenGL version '%c.%c' while your drivers only provide '%c.%c'\n", version[0], version[2], gl_version[0], gl_version[2]);
}
return FALSE;
}
PROC WINAPI wglGetProcAddress(LPCSTR lpszProc) {
void *local_func;
OpenGL_extension ext;
@ -201,6 +248,13 @@ PROC WINAPI wglGetProcAddress(LPCSTR lpszProc) {
WARN("Extension '%s' not defined in opengl32.dll's function table!\n", lpszProc);
return wine_wgl.p_wglGetProcAddress(lpszProc);
} else { /* We are looking for an OpenGL extension */
/* Check if the GL extension required by the function is available */
if(!is_extension_supported(ext_ret->extension)) {
WARN("Extension '%s' required by function '%s' not supported!\n", ext_ret->extension, lpszProc);
return NULL;
}
local_func = wine_wgl.p_wglGetProcAddress(ext_ret->name);
/* After that, look at the extensions defined in the Linux OpenGL library */