summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoridr <idr>2004-06-11 01:49:19 +0000
committeridr <idr>2004-06-11 01:49:19 +0000
commitaf4c17494b998bb31e605b204b185b9ed0653904 (patch)
tree597414a4a343f59b130ec097012d742518ea35d7
parent5476daf9e6ff7077946490d6abe3294be7a24c86 (diff)
Enable extensions not specifically listed in the server's extension
string but are implied by the core GL version number. This code is not actually enabled, but it's all there. Comments in glGetString (in single2.c) explain it all.
-rw-r--r--xc/lib/GL/glx/glxclient.h12
-rw-r--r--xc/lib/GL/glx/glxextensions.c13
-rw-r--r--xc/lib/GL/glx/glxextensions.h1
-rw-r--r--xc/lib/GL/glx/single2.c142
4 files changed, 142 insertions, 26 deletions
diff --git a/xc/lib/GL/glx/glxclient.h b/xc/lib/GL/glx/glxclient.h
index 0134c3a39..f469660c4 100644
--- a/xc/lib/GL/glx/glxclient.h
+++ b/xc/lib/GL/glx/glxclient.h
@@ -534,6 +534,18 @@ struct __GLXcontextRec {
* Stored value for \c glXQueryContext attribute \c GLX_RENDER_TYPE.
*/
int renderType;
+
+ /**
+ * \name Raw server GL version
+ *
+ * True core GL version supported by the server. This is the raw value
+ * returned by the server, and it may not reflect what is actually
+ * supported (or reported) by the client-side library.
+ */
+ /*@{*/
+ int server_major; /**< Major version number. */
+ int server_minor; /**< Minor version number. */
+ /*@}*/
};
#define __glXSetError(gc,code) \
diff --git a/xc/lib/GL/glx/glxextensions.c b/xc/lib/GL/glx/glxextensions.c
index 12645a74c..d4c2e0578 100644
--- a/xc/lib/GL/glx/glxextensions.c
+++ b/xc/lib/GL/glx/glxextensions.c
@@ -670,3 +670,16 @@ __glXCalculateUsableGLExtensions( __GLXcontext * gc,
gc->extensions = (unsigned char *)
__glXGetStringFromTable( known_gl_extensions, usable );
}
+
+
+/**
+ * Calculates the maximum core GL version that can be supported for indirect
+ * rendering.
+ */
+void
+__glXGetGLVersion( int * major_version, int * minor_version )
+{
+ __glXExtensionsCtr();
+ *major_version = gl_major;
+ *minor_version = gl_minor;
+}
diff --git a/xc/lib/GL/glx/glxextensions.h b/xc/lib/GL/glx/glxextensions.h
index 28d068242..cf6163a04 100644
--- a/xc/lib/GL/glx/glxextensions.h
+++ b/xc/lib/GL/glx/glxextensions.h
@@ -217,6 +217,7 @@ extern void __glXCalculateUsableExtensions( __GLXscreenConfigs *psc,
extern void __glXScrEnableExtension( __GLXscreenConfigs *psc, const char * name );
extern void __glXCalculateUsableGLExtensions( __GLXcontext * gc,
const char * server_string, int major_version, int minor_version );
+extern void __glXGetGLVersion( int * major_version, int * minor_version );
/* Source-level backwards compatibility with old drivers. They won't
* find the respective functions, though.
diff --git a/xc/lib/GL/glx/single2.c b/xc/lib/GL/glx/single2.c
index e932a1d76..d3006b870 100644
--- a/xc/lib/GL/glx/single2.c
+++ b/xc/lib/GL/glx/single2.c
@@ -38,6 +38,7 @@
#include <stdio.h>
#include "glxclient.h"
#include "packsingle.h"
+#include "glxextensions.h"
/* Used for GL_ARB_transpose_matrix */
static void TransposeMatrixf(GLfloat m[16])
@@ -848,6 +849,25 @@ void glFinish(void)
__GLX_SINGLE_END();
}
+
+/**
+ * Extract the major and minor version numbers from a version string.
+ */
+static void
+version_from_string( const char * ver,
+ int * major_version, int * minor_version )
+{
+ const char * end;
+ long major;
+ long minor;
+
+ major = strtol( ver, (char **) & end, 10 );
+ minor = strtol( end + 1, NULL, 10 );
+ *major_version = major;
+ *minor_version = minor;
+}
+
+
const GLubyte *glGetString(GLenum name)
{
__GLX_SINGLE_DECLARE_VARIABLES();
@@ -881,7 +901,25 @@ const GLubyte *glGetString(GLenum name)
** Get requested string from server
*/
__GLX_SINGLE_LOAD_VARIABLES();
- __GLX_SINGLE_BEGIN(X_GLsop_GetString,4);
+
+
+ /* This is usually done by the __GLX_SINGLE_BEGIN macro. However, that
+ * macro actually starts a new block and the __GLX_SINGLE_END macro closes
+ * it. The problem is that this function would need to use
+ * __GLX_SINGLE_END macro in two places, and both places are inside other
+ * blocks. The resulting code would either not compile or not work
+ * correctly.
+ */
+
+ (void) __glXFlushRenderBuffer( gc, pc );
+ LockDisplay(dpy);
+ GetReqExtra( GLXSingle, 4, req );
+ req->reqType = gc->majorOpcode;
+ req->glxCode = X_GLsop_GetString;
+ req->contextTag = gc->currentContextTag;
+
+ pc = ((GLubyte *)(req) + sz_xGLXSingleReq);
+
__GLX_SINGLE_PUT_LONG(0,name);
__GLX_SINGLE_READ_XREPLY();
__GLX_SINGLE_GET_SIZE(compsize);
@@ -890,55 +928,107 @@ const GLubyte *glGetString(GLenum name)
/* Throw data on the floor */
_XEatData(dpy, compsize);
__glXSetError(gc, GL_OUT_OF_MEMORY);
+
+ UnlockDisplay(dpy);
+ SyncHandle();
} else {
__GLX_SINGLE_GET_CHAR_ARRAY(s,compsize);
+ UnlockDisplay(dpy);
+ SyncHandle();
+
/*
** Update local cache
*/
switch(name) {
- case GL_VENDOR:
+ case GL_VENDOR:
gc->vendor = s;
break;
- case GL_RENDERER:
+
+ case GL_RENDERER:
gc->renderer = s;
break;
- case GL_VERSION: {
- float server_version = strtof(s, NULL);
- float client_version = strtof(__glXGLClientVersion, NULL);
- if ( server_version <= client_version ) {
+ case GL_VERSION: {
+ int client_major;
+ int client_minor;
+
+ version_from_string( (char *) s,
+ & gc->server_major, & gc->server_minor );
+ __glXGetGLVersion( & client_major, & client_minor );
+
+ if ( (gc->server_major < client_major)
+ || ((gc->server_major == client_major)
+ && (gc->server_minor <= client_minor)) ) {
gc->version = s;
- }
- else {
+ }
+ else {
gc->version = Xmalloc( strlen(__glXGLClientVersion)
+ strlen((char *)s) + 4 );
if ( gc->version == NULL ) {
- /* If we couldn't allocate memory for the new string,
- * make a best-effort and just copy the client-side version
- * to the string and use that. It probably doesn't
- * matter what is done here. If there not memory available
- * for a short string, the system is probably going to die
- * soon anyway.
- */
- strcpy((char *)s, __glXGLClientVersion);
+ /* If we couldn't allocate memory for the new string,
+ * make a best-effort and just copy the client-side version
+ * to the string and use that. It probably doesn't
+ * matter what is done here. If there not memory available
+ * for a short string, the system is probably going to die
+ * soon anyway.
+ */
+ strcpy((char *)s, __glXGLClientVersion);
}
else {
- sprintf( (char *)gc->version, "%s (%s)", __glXGLClientVersion, s );
- Xfree( s );
- s = gc->version;
+ sprintf( (char *)gc->version, "%s (%s)", __glXGLClientVersion, s );
+ Xfree( s );
+ s = gc->version;
}
- }
- break;
- }
- case GL_EXTENSIONS:
- __glXCalculateUsableGLExtensions( gc, s, 1, 0 );
+ }
+ break;
+ }
+
+ case GL_EXTENSIONS: {
+ int major = 1;
+ int minor = 0;
+
+ /* This code is currently disabled. I was reminded that some
+ * vendors intentionally exclude some extensions from their
+ * extension string that are part of the core version they
+ * advertise. In particular, on Nvidia drivers this means that
+ * the functionality is supported by the driver, but is not
+ * hardware accelerated. For example, a TNT will show core
+ * version 1.5, but most of the post-1.2 functionality is a
+ * software fallback.
+ *
+ * I don't want to break applications that rely on this odd
+ * behavior. At the same time, the code is written and tested,
+ * so I didn't want to throw it away. Therefore, the code is here
+ * but disabled. In the future, we may wish to and an environment
+ * variable to enable it.
+ */
+
+#if 0
+ /* Call glGetString just to make sure that gc->server_major and
+ * gc->server_minor are set. This version may be higher than we
+ * can completely support, but it may imply support for some
+ * extensions that we can support.
+ *
+ * For example, at the time of this writing, the client-side
+ * library only supports upto core GL version 1.2. However, cubic
+ * textures, multitexture, multisampling, and some other 1.3
+ * features are supported. If the server reports back version
+ * 1.3, but does not report all of those extensions, we will
+ * enable them.
+ */
+ (void *) glGetString( GL_VERSION );
+ major = gc->server_major,
+ minor = gc->server_minor;
+#endif
+
+ __glXCalculateUsableGLExtensions( gc, (char *) s, major, minor );
XFree( s );
s = gc->extensions;
break;
}
+ }
}
- __GLX_SINGLE_END();
return s;
}