wgl: Add extension checking code / glxGetProcAddress protection.
This commit is contained in:
parent
02fc886302
commit
2f8a05e27e
|
@ -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
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue