aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/mesa/main
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/mesa/main')
-rw-r--r--mesalib/src/mesa/main/enable.c27
-rw-r--r--mesalib/src/mesa/main/get.c43
-rw-r--r--mesalib/src/mesa/main/texgetimage.c150
-rw-r--r--mesalib/src/mesa/main/version.c25
4 files changed, 188 insertions, 57 deletions
diff --git a/mesalib/src/mesa/main/enable.c b/mesalib/src/mesa/main/enable.c
index 23b6a9480..689dc8a99 100644
--- a/mesalib/src/mesa/main/enable.c
+++ b/mesalib/src/mesa/main/enable.c
@@ -304,7 +304,10 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state)
case GL_CLIP_DISTANCE6:
case GL_CLIP_DISTANCE7:
{
- const GLuint p = cap - GL_CLIP_PLANE0;
+ const GLuint p = cap - GL_CLIP_DISTANCE0;
+
+ if (p >= ctx->Const.MaxClipPlanes)
+ goto invalid_enum_error;
if ((ctx->Transform.ClipPlanesEnabled & (1 << p))
== ((GLuint) state << p))
@@ -1084,13 +1087,21 @@ _mesa_IsEnabled( GLenum cap )
return ctx->Eval.AutoNormal;
case GL_BLEND:
return ctx->Color.BlendEnabled & 1; /* return state for buffer[0] */
- case GL_CLIP_PLANE0:
- case GL_CLIP_PLANE1:
- case GL_CLIP_PLANE2:
- case GL_CLIP_PLANE3:
- case GL_CLIP_PLANE4:
- case GL_CLIP_PLANE5:
- return (ctx->Transform.ClipPlanesEnabled >> (cap - GL_CLIP_PLANE0)) & 1;
+ case GL_CLIP_DISTANCE0:
+ case GL_CLIP_DISTANCE1:
+ case GL_CLIP_DISTANCE2:
+ case GL_CLIP_DISTANCE3:
+ case GL_CLIP_DISTANCE4:
+ case GL_CLIP_DISTANCE5:
+ case GL_CLIP_DISTANCE6:
+ case GL_CLIP_DISTANCE7: {
+ const GLuint p = cap - GL_CLIP_DISTANCE0;
+
+ if (p >= ctx->Const.MaxClipPlanes)
+ goto invalid_enum_error;
+
+ return (ctx->Transform.ClipPlanesEnabled >> p) & 1;
+ }
case GL_COLOR_MATERIAL:
return ctx->Light.ColorMaterialEnabled;
case GL_CULL_FACE:
diff --git a/mesalib/src/mesa/main/get.c b/mesalib/src/mesa/main/get.c
index 99ce567cc..cddea8ea2 100644
--- a/mesalib/src/mesa/main/get.c
+++ b/mesalib/src/mesa/main/get.c
@@ -102,6 +102,8 @@ enum value_type {
TYPE_BIT_3,
TYPE_BIT_4,
TYPE_BIT_5,
+ TYPE_BIT_6,
+ TYPE_BIT_7,
TYPE_FLOAT,
TYPE_FLOAT_2,
TYPE_FLOAT_3,
@@ -134,6 +136,7 @@ enum value_extra {
EXTRA_NEW_FRAG_CLAMP,
EXTRA_VALID_DRAW_BUFFER,
EXTRA_VALID_TEXTURE_UNIT,
+ EXTRA_VALID_CLIP_DISTANCE,
EXTRA_FLUSH_CURRENT,
};
@@ -189,6 +192,8 @@ union value {
#define CONTEXT_BIT3(field) CONTEXT_FIELD(field, TYPE_BIT_3)
#define CONTEXT_BIT4(field) CONTEXT_FIELD(field, TYPE_BIT_4)
#define CONTEXT_BIT5(field) CONTEXT_FIELD(field, TYPE_BIT_5)
+#define CONTEXT_BIT6(field) CONTEXT_FIELD(field, TYPE_BIT_6)
+#define CONTEXT_BIT7(field) CONTEXT_FIELD(field, TYPE_BIT_7)
#define CONTEXT_FLOAT(field) CONTEXT_FIELD(field, TYPE_FLOAT)
#define CONTEXT_FLOAT2(field) CONTEXT_FIELD(field, TYPE_FLOAT_2)
#define CONTEXT_FLOAT3(field) CONTEXT_FIELD(field, TYPE_FLOAT_3)
@@ -239,6 +244,11 @@ static const int extra_valid_texture_unit[] = {
EXTRA_END
};
+static const int extra_valid_clip_distance[] = {
+ EXTRA_VALID_CLIP_DISTANCE,
+ EXTRA_END
+};
+
static const int extra_flush_current_valid_texture_unit[] = {
EXTRA_FLUSH_CURRENT,
EXTRA_VALID_TEXTURE_UNIT,
@@ -515,12 +525,14 @@ static const struct value_desc values[] = {
{ GL_ALPHA_TEST_FUNC, CONTEXT_ENUM(Color.AlphaFunc), NO_EXTRA },
{ GL_ALPHA_TEST_REF, LOC_CUSTOM, TYPE_FLOATN, 0, extra_new_frag_clamp },
{ GL_BLEND_DST, CONTEXT_ENUM(Color.Blend[0].DstRGB), NO_EXTRA },
- { GL_CLIP_PLANE0, CONTEXT_BIT0(Transform.ClipPlanesEnabled), NO_EXTRA },
- { GL_CLIP_PLANE1, CONTEXT_BIT1(Transform.ClipPlanesEnabled), NO_EXTRA },
- { GL_CLIP_PLANE2, CONTEXT_BIT2(Transform.ClipPlanesEnabled), NO_EXTRA },
- { GL_CLIP_PLANE3, CONTEXT_BIT3(Transform.ClipPlanesEnabled), NO_EXTRA },
- { GL_CLIP_PLANE4, CONTEXT_BIT4(Transform.ClipPlanesEnabled), NO_EXTRA },
- { GL_CLIP_PLANE5, CONTEXT_BIT5(Transform.ClipPlanesEnabled), NO_EXTRA },
+ { GL_CLIP_DISTANCE0, CONTEXT_BIT0(Transform.ClipPlanesEnabled), extra_valid_clip_distance },
+ { GL_CLIP_DISTANCE1, CONTEXT_BIT1(Transform.ClipPlanesEnabled), extra_valid_clip_distance },
+ { GL_CLIP_DISTANCE2, CONTEXT_BIT2(Transform.ClipPlanesEnabled), extra_valid_clip_distance },
+ { GL_CLIP_DISTANCE3, CONTEXT_BIT3(Transform.ClipPlanesEnabled), extra_valid_clip_distance },
+ { GL_CLIP_DISTANCE4, CONTEXT_BIT4(Transform.ClipPlanesEnabled), extra_valid_clip_distance },
+ { GL_CLIP_DISTANCE5, CONTEXT_BIT5(Transform.ClipPlanesEnabled), extra_valid_clip_distance },
+ { GL_CLIP_DISTANCE6, CONTEXT_BIT6(Transform.ClipPlanesEnabled), extra_valid_clip_distance },
+ { GL_CLIP_DISTANCE7, CONTEXT_BIT7(Transform.ClipPlanesEnabled), extra_valid_clip_distance },
{ GL_COLOR_MATERIAL, CONTEXT_BOOL(Light.ColorMaterialEnabled), NO_EXTRA },
{ GL_CURRENT_COLOR,
CONTEXT_FIELD(Current.Attrib[VERT_ATTRIB_COLOR0][0], TYPE_FLOATN_4),
@@ -1798,6 +1810,13 @@ check_extra(struct gl_context *ctx, const char *func, const struct value_desc *d
return GL_FALSE;
}
break;
+ case EXTRA_VALID_CLIP_DISTANCE:
+ if (d->pname - GL_CLIP_DISTANCE0 >= ctx->Const.MaxClipPlanes) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s(clip distance %u)",
+ func, d->pname - GL_CLIP_DISTANCE0);
+ return GL_FALSE;
+ }
+ break;
case EXTRA_END:
break;
default: /* *e is a offset into the extension struct */
@@ -1986,6 +2005,8 @@ _mesa_GetBooleanv(GLenum pname, GLboolean *params)
case TYPE_BIT_3:
case TYPE_BIT_4:
case TYPE_BIT_5:
+ case TYPE_BIT_6:
+ case TYPE_BIT_7:
shift = d->type - TYPE_BIT_0;
params[0] = (*(GLbitfield *) p >> shift) & 1;
break;
@@ -2073,6 +2094,8 @@ _mesa_GetFloatv(GLenum pname, GLfloat *params)
case TYPE_BIT_3:
case TYPE_BIT_4:
case TYPE_BIT_5:
+ case TYPE_BIT_6:
+ case TYPE_BIT_7:
shift = d->type - TYPE_BIT_0;
params[0] = BOOLEAN_TO_FLOAT((*(GLbitfield *) p >> shift) & 1);
break;
@@ -2166,6 +2189,8 @@ _mesa_GetIntegerv(GLenum pname, GLint *params)
case TYPE_BIT_3:
case TYPE_BIT_4:
case TYPE_BIT_5:
+ case TYPE_BIT_6:
+ case TYPE_BIT_7:
shift = d->type - TYPE_BIT_0;
params[0] = (*(GLbitfield *) p >> shift) & 1;
break;
@@ -2260,6 +2285,8 @@ _mesa_GetInteger64v(GLenum pname, GLint64 *params)
case TYPE_BIT_3:
case TYPE_BIT_4:
case TYPE_BIT_5:
+ case TYPE_BIT_6:
+ case TYPE_BIT_7:
shift = d->type - TYPE_BIT_0;
params[0] = (*(GLbitfield *) p >> shift) & 1;
break;
@@ -2348,6 +2375,8 @@ _mesa_GetDoublev(GLenum pname, GLdouble *params)
case TYPE_BIT_3:
case TYPE_BIT_4:
case TYPE_BIT_5:
+ case TYPE_BIT_6:
+ case TYPE_BIT_7:
shift = d->type - TYPE_BIT_0;
params[0] = (*(GLbitfield *) p >> shift) & 1;
break;
@@ -2618,6 +2647,8 @@ _mesa_GetFixedv(GLenum pname, GLfixed *params)
case TYPE_BIT_3:
case TYPE_BIT_4:
case TYPE_BIT_5:
+ case TYPE_BIT_6:
+ case TYPE_BIT_7:
shift = d->type - TYPE_BIT_0;
params[0] = BOOLEAN_TO_FIXED((*(GLbitfield *) p >> shift) & 1);
break;
diff --git a/mesalib/src/mesa/main/texgetimage.c b/mesalib/src/mesa/main/texgetimage.c
index 2830dda86..d2f25b9f8 100644
--- a/mesalib/src/mesa/main/texgetimage.c
+++ b/mesalib/src/mesa/main/texgetimage.c
@@ -71,14 +71,13 @@ type_with_negative_values(GLenum type)
static void
get_tex_depth(struct gl_context *ctx, GLuint dimensions,
GLenum format, GLenum type, GLvoid *pixels,
- const struct gl_texture_image *texImage)
+ struct gl_texture_image *texImage)
{
const GLint width = texImage->Width;
const GLint height = texImage->Height;
const GLint depth = texImage->Depth;
GLint img, row;
GLfloat *depthRow = (GLfloat *) malloc(width * sizeof(GLfloat));
- const GLint texelSize = _mesa_get_format_bytes(texImage->TexFormat);
if (!depthRow) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage");
@@ -86,18 +85,24 @@ get_tex_depth(struct gl_context *ctx, GLuint dimensions,
}
for (img = 0; img < depth; img++) {
+ GLubyte *srcMap;
+ GLint srcRowStride;
+
+ /* map src texture buffer */
+ ctx->Driver.MapTextureImage(ctx, texImage, img,
+ 0, 0, width, height, GL_MAP_READ_BIT,
+ &srcMap, &srcRowStride);
+
for (row = 0; row < height; row++) {
void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels,
width, height, format, type,
img, row, 0);
- const GLubyte *src = (GLubyte *) texImage->Data +
- (texImage->ImageOffsets[img] +
- texImage->RowStride * row) * texelSize;
-
+ const GLubyte *src = srcMap + row * srcRowStride;
_mesa_unpack_float_z_row(texImage->TexFormat, width, src, depthRow);
-
_mesa_pack_depth_span(ctx, width, dest, type, depthRow, &ctx->Pack);
}
+
+ ctx->Driver.UnmapTextureImage(ctx, texImage, img);
}
free(depthRow);
@@ -110,27 +115,35 @@ get_tex_depth(struct gl_context *ctx, GLuint dimensions,
static void
get_tex_depth_stencil(struct gl_context *ctx, GLuint dimensions,
GLenum format, GLenum type, GLvoid *pixels,
- const struct gl_texture_image *texImage)
+ struct gl_texture_image *texImage)
{
const GLint width = texImage->Width;
const GLint height = texImage->Height;
const GLint depth = texImage->Depth;
- const GLint rowstride = texImage->RowStride;
- const GLuint *src = (const GLuint *) texImage->Data;
GLint img, row;
for (img = 0; img < depth; img++) {
+ GLubyte *srcMap;
+ GLint rowstride;
+
+ /* map src texture buffer */
+ ctx->Driver.MapTextureImage(ctx, texImage, img,
+ 0, 0, width, height, GL_MAP_READ_BIT,
+ &srcMap, &rowstride);
+
for (row = 0; row < height; row++) {
+ const GLubyte *src = srcMap + row * rowstride;
void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels,
width, height, format, type,
img, row, 0);
+ /* XXX Z24_S8 vs. S8_Z24??? */
memcpy(dest, src, width * sizeof(GLuint));
if (ctx->Pack.SwapBytes) {
_mesa_swap4((GLuint *) dest, width);
}
-
- src += rowstride;
}
+
+ ctx->Driver.UnmapTextureImage(ctx, texImage, img);
}
}
@@ -141,17 +154,24 @@ get_tex_depth_stencil(struct gl_context *ctx, GLuint dimensions,
static void
get_tex_ycbcr(struct gl_context *ctx, GLuint dimensions,
GLenum format, GLenum type, GLvoid *pixels,
- const struct gl_texture_image *texImage)
+ struct gl_texture_image *texImage)
{
const GLint width = texImage->Width;
const GLint height = texImage->Height;
const GLint depth = texImage->Depth;
- const GLint rowstride = texImage->RowStride;
- const GLushort *src = (const GLushort *) texImage->Data;
GLint img, row;
for (img = 0; img < depth; img++) {
+ GLubyte *srcMap;
+ GLint rowstride;
+
+ /* map src texture buffer */
+ ctx->Driver.MapTextureImage(ctx, texImage, img,
+ 0, 0, width, height, GL_MAP_READ_BIT,
+ &srcMap, &rowstride);
+
for (row = 0; row < height; row++) {
+ const GLubyte *src = srcMap + row * rowstride;
void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels,
width, height, format, type,
img, row, 0);
@@ -168,9 +188,9 @@ get_tex_ycbcr(struct gl_context *ctx, GLuint dimensions,
else if (ctx->Pack.SwapBytes) {
_mesa_swap2((GLushort *) dest, width);
}
-
- src += rowstride;
}
+
+ ctx->Driver.UnmapTextureImage(ctx, texImage, img);
}
}
@@ -221,8 +241,32 @@ get_tex_rgba(struct gl_context *ctx, GLuint dimensions,
return;
}
- _mesa_decompress_image(texFormat, texImage->Width, texImage->Height,
- texImage->Data, texImage->RowStride, tempImage);
+ /* Decompress the texture image - results in 'tempImage' */
+ {
+ GLubyte *srcMap;
+ GLint srcRowStride;
+ GLuint bytes, bw, bh;
+
+ bytes = _mesa_get_format_bytes(texImage->TexFormat);
+ _mesa_get_format_block_size(texImage->TexFormat, &bw, &bh);
+
+ ctx->Driver.MapTextureImage(ctx, texImage, 0,
+ 0, 0, width, height,
+ GL_MAP_READ_BIT,
+ &srcMap, &srcRowStride);
+
+ /* XXX This line is a bit of a hack to work around the
+ * mismatch of compressed row strides as returned by
+ * MapTextureImage() vs. what the texture decompression code
+ * uses. This will be fixed in the future.
+ */
+ srcRowStride = srcRowStride * bh / bytes;
+
+ _mesa_decompress_image(texFormat, width, height,
+ srcMap, srcRowStride, tempImage);
+
+ ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
+ }
if (baseFormat == GL_LUMINANCE ||
baseFormat == GL_LUMINANCE_ALPHA) {
@@ -250,7 +294,6 @@ get_tex_rgba(struct gl_context *ctx, GLuint dimensions,
}
else {
/* No decompression needed */
- const GLint texelSize = _mesa_get_format_bytes(texFormat);
GLuint img, row;
GLfloat (*rgba)[4];
@@ -261,13 +304,19 @@ get_tex_rgba(struct gl_context *ctx, GLuint dimensions,
}
for (img = 0; img < depth; img++) {
+ GLubyte *srcMap;
+ GLint rowstride;
+
+ /* map src texture buffer */
+ ctx->Driver.MapTextureImage(ctx, texImage, img,
+ 0, 0, width, height, GL_MAP_READ_BIT,
+ &srcMap, &rowstride);
+
for (row = 0; row < height; row++) {
+ const GLubyte *src = srcMap + row * rowstride;
void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels,
width, height, format, type,
img, row, 0);
- const GLubyte *src = (const GLubyte *) texImage->Data +
- (texImage->ImageOffsets[img] +
- texImage->RowStride * row) * texelSize;
_mesa_unpack_rgba_row(texFormat, width, src, rgba);
@@ -307,6 +356,9 @@ get_tex_rgba(struct gl_context *ctx, GLuint dimensions,
format, type, dest,
&ctx->Pack, transferOps);
}
+
+ /* Unmap the src texture buffer */
+ ctx->Driver.UnmapTextureImage(ctx, texImage, img);
}
free(rgba);
@@ -319,15 +371,13 @@ get_tex_rgba(struct gl_context *ctx, GLuint dimensions,
* \return GL_TRUE if done, GL_FALSE otherwise
*/
static GLboolean
-get_tex_memcpy(struct gl_context *ctx, GLenum format, GLenum type, GLvoid *pixels,
- const struct gl_texture_object *texObj,
- const struct gl_texture_image *texImage)
+get_tex_memcpy(struct gl_context *ctx, GLenum format, GLenum type,
+ GLvoid *pixels,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
{
GLboolean memCopy = GL_FALSE;
- /* Texture image should have been mapped already */
- assert(texImage->Data);
-
/*
* Check if the src/dst formats are compatible.
* Also note that GL's pixel transfer ops don't apply to glGetTexImage()
@@ -386,20 +436,28 @@ get_tex_memcpy(struct gl_context *ctx, GLenum format, GLenum type, GLvoid *pixel
texImage->Height, format, type, 0, 0);
const GLint dstRowStride =
_mesa_image_row_stride(&ctx->Pack, texImage->Width, format, type);
- const GLubyte *src = texImage->Data;
- const GLint srcRowStride = texImage->RowStride * bpp;
- GLuint row;
+ GLubyte *src;
+ GLint srcRowStride;
+
+ /* map src texture buffer */
+ ctx->Driver.MapTextureImage(ctx, texImage, 0,
+ 0, 0, texImage->Width, texImage->Height,
+ GL_MAP_READ_BIT, &src, &srcRowStride);
if (bytesPerRow == dstRowStride && bytesPerRow == srcRowStride) {
memcpy(dst, src, bytesPerRow * texImage->Height);
}
else {
+ GLuint row;
for (row = 0; row < texImage->Height; row++) {
memcpy(dst, src, bytesPerRow);
dst += dstRowStride;
src += srcRowStride;
}
}
+
+ /* unmap src texture buffer */
+ ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
}
return memCopy;
@@ -409,7 +467,8 @@ get_tex_memcpy(struct gl_context *ctx, GLenum format, GLenum type, GLvoid *pixel
/**
* This is the software fallback for Driver.GetTexImage().
* All error checking will have been done before this routine is called.
- * The texture image must be mapped.
+ * We'll call ctx->Driver.MapTextureImage() to access the data, then
+ * unmap with ctx->Driver.UnmapTextureImage().
*/
void
_mesa_get_teximage(struct gl_context *ctx, GLenum target, GLint level,
@@ -419,9 +478,6 @@ _mesa_get_teximage(struct gl_context *ctx, GLenum target, GLint level,
{
GLuint dimensions;
- /* If we get here, the texture image should be mapped */
- assert(texImage->Data);
-
switch (target) {
case GL_TEXTURE_1D:
dimensions = 1;
@@ -433,6 +489,7 @@ _mesa_get_teximage(struct gl_context *ctx, GLenum target, GLint level,
dimensions = 2;
}
+ /* map dest buffer, if PBO */
if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
/* Packing texture image into a PBO.
* Map the (potentially) VRAM-based buffer into our process space so
@@ -487,11 +544,11 @@ _mesa_get_compressed_teximage(struct gl_context *ctx, GLenum target, GLint level
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
- const GLuint row_stride = _mesa_format_row_stride(texImage->TexFormat,
- texImage->Width);
- const GLuint row_stride_stored = _mesa_format_row_stride(texImage->TexFormat,
- texImage->RowStride);
+ const GLuint row_stride =
+ _mesa_format_row_stride(texImage->TexFormat, texImage->Width);
GLuint i;
+ GLubyte *src;
+ GLint srcRowStride;
if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
/* pack texture image into a PBO */
@@ -507,25 +564,32 @@ _mesa_get_compressed_teximage(struct gl_context *ctx, GLenum target, GLint level
img = ADD_POINTERS(buf, img);
}
+ /* map src texture buffer */
+ ctx->Driver.MapTextureImage(ctx, texImage, 0,
+ 0, 0, texImage->Width, texImage->Height,
+ GL_MAP_READ_BIT, &src, &srcRowStride);
+
/* no pixelstore or pixel transfer, but respect stride */
- if (row_stride == row_stride_stored) {
+ if (row_stride == srcRowStride) {
const GLuint size = _mesa_format_image_size(texImage->TexFormat,
texImage->Width,
texImage->Height,
texImage->Depth);
- memcpy(img, texImage->Data, size);
+ memcpy(img, src, size);
}
else {
GLuint bw, bh;
_mesa_get_format_block_size(texImage->TexFormat, &bw, &bh);
for (i = 0; i < (texImage->Height + bh - 1) / bh; i++) {
memcpy((GLubyte *)img + i * row_stride,
- (GLubyte *)texImage->Data + i * row_stride_stored,
+ (GLubyte *)src + i * srcRowStride,
row_stride);
}
}
+ ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
+
if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
ctx->Driver.UnmapBuffer(ctx, ctx->Pack.BufferObj);
}
diff --git a/mesalib/src/mesa/main/version.c b/mesalib/src/mesa/main/version.c
index b2d507786..3b5a78d1b 100644
--- a/mesalib/src/mesa/main/version.c
+++ b/mesalib/src/mesa/main/version.c
@@ -27,7 +27,29 @@
#include "version.h"
/*#include "git_sha1.h"*/
+/**
+ * Override the context's GL version if the environment variable
+ * MESA_GL_VERSION_OVERRIDE is set. Valid values of MESA_GL_VERSION_OVERRIDE
+ * are point-separated version numbers, such as "3.0".
+ */
+static void
+override_version(struct gl_context *ctx, GLuint *major, GLuint *minor)
+{
+ const char *env_var = "MESA_GL_VERSION_OVERRIDE";
+ const char *version;
+ int n;
+
+ version = getenv(env_var);
+ if (!version) {
+ return;
+ }
+ n = sscanf(version, "%d.%d", major, minor);
+ if (n != 2) {
+ fprintf(stderr, "error: invalid value for %s: %s\n", env_var, version);
+ return;
+ }
+}
/**
* Examine enabled GL extensions to determine GL version.
@@ -178,6 +200,9 @@ compute_version(struct gl_context *ctx)
ctx->VersionMajor = major;
ctx->VersionMinor = minor;
+
+ override_version(ctx, &ctx->VersionMajor, &ctx->VersionMinor);
+
ctx->VersionString = (char *) malloc(max);
if (ctx->VersionString) {
_mesa_snprintf(ctx->VersionString, max,